This example illustrates how to read a factor graph from a file and how to run several inference algorithms (junction tree, loopy belief propagation, and the max-product algorithm) on it.
#include <iostream>
#include <map>
int main( int argc, char *argv[] ) {
#if defined(DAI_WITH_BP) && defined(DAI_WITH_JTREE)
if ( argc != 2 && argc != 3 ) {
cout << "Usage: " << argv[0] << " <filename.fg> [maxstates]" << endl << endl;
cout << "Reads factor graph <filename.fg> and runs" << endl;
cout << "Belief Propagation, Max-Product and JunctionTree on it." << endl;
cout << "JunctionTree is only run if a junction tree is found with" << endl;
cout << "total number of states less than <maxstates> (where 0 means unlimited)." << endl << endl;
return 1;
} else {
size_t maxstates = 1000000;
if( argc == 3 )
maxstates = fromString<size_t>( argv[2] );
size_t maxiter = 10000;
size_t verb = 1;
opts.
set(
"maxiter",maxiter);
opts.
set(
"verbose",verb);
bool do_jt = true;
try {
if( e.
getCode() == Exception::OUT_OF_MEMORY ) {
do_jt = false;
cout << "Skipping junction tree (need more than " << maxstates << " states)." << endl;
}
else
throw;
}
vector<size_t> jtmapstate;
if( do_jt ) {
jt =
JTree( fg, opts(
"updates",
string(
"HUGIN")) );
jtmap =
JTree( fg, opts(
"updates",
string(
"HUGIN"))(
"inference",
string(
"MAXPROD")) );
}
BP bp(fg, opts(
"updates",
string(
"SEQRND"))(
"logdomain",
false));
BP mp(fg, opts(
"updates",
string(
"SEQRND"))(
"logdomain",
false)(
"inference",
string(
"MAXPROD"))(
"damping",
string(
"0.1")));
DecMAP decmap(fg, opts("reinit",true)("ianame",string("BP"))("iaopts",string("[damping=0.1,inference=MAXPROD,logdomain=0,maxiter=1000,tol=1e-9,updates=SEQRND,verbose=1]")) );
decmap.init();
decmap.run();
vector<size_t> decmapstate = decmap.findMaximum();
if( do_jt ) {
cout << "Exact variable marginals:" << endl;
for(
size_t i = 0; i < fg.
nrVars(); i++ )
}
cout << "Approximate (loopy belief propagation) variable marginals:" << endl;
for(
size_t i = 0; i < fg.
nrVars(); i++ )
if( do_jt ) {
cout << "Exact factor marginals:" << endl;
}
cout << "Approximate (loopy belief propagation) factor marginals:" << endl;
if( do_jt ) {
cout <<
"Exact log partition sum: " << jt.
logZ() << endl;
}
cout <<
"Approximate (loopy belief propagation) log partition sum: " << bp.
logZ() << endl;
if( do_jt ) {
cout << "Exact MAP variable marginals:" << endl;
for(
size_t i = 0; i < fg.
nrVars(); i++ )
}
cout << "Approximate (max-product) MAP variable marginals:" << endl;
for(
size_t i = 0; i < fg.
nrVars(); i++ )
if( do_jt ) {
cout << "Exact MAP factor marginals:" << endl;
}
cout << "Approximate (max-product) MAP factor marginals:" << endl;
if( do_jt ) {
cout <<
"Exact MAP state (log score = " << fg.
logScore( jtmapstate ) <<
"):" << endl;
for( size_t i = 0; i < jtmapstate.size(); i++ )
cout << fg.
var(i) <<
": " << jtmapstate[i] << endl;
}
cout <<
"Approximate (max-product) MAP state (log score = " << fg.
logScore( mpstate ) <<
"):" << endl;
for( size_t i = 0; i < mpstate.size(); i++ )
cout << fg.
var(i) <<
": " << mpstate[i] << endl;
cout <<
"Approximate DecMAP state (log score = " << fg.
logScore( decmapstate ) <<
"):" << endl;
for( size_t i = 0; i < decmapstate.size(); i++ )
cout << fg.
var(i) <<
": " << decmapstate[i] << endl;
}
return 0;
#else
cout << "libDAI was configured without BP or JunctionTree (this can be changed in include/dai/dai_config.h)." << endl;
#endif
}