TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opts("updates",string("HUGIN")), false), _maxdiff(0.0), _iters(0), props(), _Q() { setProperties( opts ); if( opts.hasKey("tree") ) { construct( fg, opts.getAs<RootedTree>("tree") ); } else { if( props.type == Properties::TypeType::ORG || props.type == Properties::TypeType::ALT ) { // ORG: construct weighted graph with as weights a crude estimate of the // mutual information between the nodes // ALT: construct weighted graph with as weights an upper bound on the // effective interaction strength between pairs of nodes WeightedGraph<Real> wg; // in order to get a connected weighted graph, we start // by connecting every variable to the zero'th variable with weight 0 for( size_t i = 1; i < fg.nrVars(); i++ ) wg[UEdge(i,0)] = 0.0; for( size_t i = 0; i < fg.nrVars(); i++ ) { SmallSet<size_t> delta_i = fg.bipGraph().delta1( i, false ); const Var& v_i = fg.var(i); foreach( size_t j, delta_i ) if( i < j ) { const Var& v_j = fg.var(j); VarSet v_ij( v_i, v_j ); SmallSet<size_t> nb_ij = fg.bipGraph().nb1Set( i ) | fg.bipGraph().nb1Set( j ); Factor piet; foreach( size_t I, nb_ij ) { const VarSet& Ivars = fg.factor(I).vars(); if( props.type == Properties::TypeType::ORG ) { if( (Ivars == v_i) || (Ivars == v_j) ) piet *= fg.factor(I); else if( Ivars >> v_ij ) piet *= fg.factor(I).marginal( v_ij ); } else { if( Ivars >> v_ij ) piet *= fg.factor(I); } } if( props.type == Properties::TypeType::ORG ) { if( piet.vars() >> v_ij ) { piet = piet.marginal( v_ij ); Factor pietf = piet.marginal(v_i) * piet.marginal(v_j); wg[UEdge(i,j)] = dist( piet, pietf, DISTKL ); } else { // this should never happen... DAI_ASSERT( 0 == 1 ); wg[UEdge(i,j)] = 0; } } else wg[UEdge(i,j)] = piet.strength(v_i, v_j); }
void GI_libDAI::copyLabels_MSRC(vector<std::size_t>& labels, labelType* nodeLabels, BP& bp, FactorGraph& fg) { labelType voidLabel = classIdxToLabel[0]; labelType moutainLabel = classIdxToLabel[4161600]; labelType horseLabel = classIdxToLabel[8323328]; INFERENCE_PRINT("[gi_libDAI] copyLabels_MSRC void=%d, moutain=%d, horse=%d\n", (int)voidLabel, (int)moutainLabel, (int)horseLabel); int label; int n = slice->getNbSupernodes(); for(int sid = 0; sid < n; sid++) { label = labels[sid]; //if(lossPerLabel == 0 && label > 20) // void label if(label == voidLabel || label == moutainLabel || label == horseLabel) { //Factor f = bp.beliefV(sid); Factor f = bp.belief(fg.var(sid)); double maxProb = -1; for(int i = 0; i < (int)f.states(); i++) { if(i != voidLabel && i != moutainLabel && i != horseLabel) if(maxProb < f[i]) { maxProb = f[i]; label = i; } } //INFERENCE_PRINT("label=%d\n", label); } nodeLabels[sid] = label; } }
// use bp.findmaximum instead void GI_libDAI::getLabels(BP& bp, FactorGraph& fg, vector<std::size_t>& labels) { float maxProb; int label; ofstream ofs("beliefs2"); ofs << "------------------------------- UNARY -------------------------------\n"; for(long sid = 0; sid < slice->getNbSupernodes(); sid++) { Factor f = bp.belief(fg.var(sid)); maxProb = f[0]; label = 0; ofs << sid; for(int i=1; i < (int)param->nClasses; i++) { ofs << " " << i << ":" << f[i]; if(f[i] > maxProb) { maxProb = f[i]; label = i; } } ofs << endl; labels[sid] = label; } ofs.close(); }
/// Construct from factor graph \a fg, name \a _name, and set of properties \a opts TestDAI( const FactorGraph &fg, const string &_name, const PropertySet &opts ) : obj(NULL), name(_name), varErr(), facErr(), varMarginals(), facMarginals(), allMarginals(), logZ(0.0), maxdiff(0.0), time(0), iters(0U), has_logZ(false), has_maxdiff(false), has_iters(false) { double tic = toc(); if( name == "LDPC" ) { // special case: simulating a Low Density Parity Check code Real zero[2] = {1.0, 0.0}; for( size_t i = 0; i < fg.nrVars(); i++ ) varMarginals.push_back( Factor(fg.var(i), zero) ); allMarginals = varMarginals; logZ = 0.0; maxdiff = 0.0; iters = 1; has_logZ = false; has_maxdiff = false; has_iters = false; } else // create a corresponding InfAlg object obj = newInfAlg( name, fg, opts ); // Add the time needed to create the object time += toc() - tic; }
int main( int argc, char *argv[] ) { int i; char* myString = (char*) malloc (50); if ( argc < 3 ) { cout << "Usage: Filename and then Number of Nodes in the One Loop Graph. " << endl; cout << "Reads filename, it creates the fg file and then runs inference algorithms" << endl; return 1; } else { strcpy(myString,"Results"); strcat(myString,argv[1]); ofstream file( myString,ios::out); FactorGraph fg; vector<Var> vars; vector<Factor> factors; //Number of variables. size_t dimx=atoi(argv[2]); double J=0.5; size_t N=dimx; vars.reserve( N ); for( size_t i = 0; i < N; i++ ) vars.push_back( Var( i, 2 ) ); factors.reserve( N ); for( size_t i = 0; i < dimx; i++ ){ // Add a pairwise interaction with the next neighboring pixel if (i!=dimx-1) factors.push_back( createFactorIsing( vars[i], vars[i+1], J ) ); else if (i==dimx-1) factors.push_back( createFactorIsing( vars[i], vars[0], J ) ); // Add a single-variable interaction with strength th. double th=0.1; factors.push_back( createFactorIsing( vars[i], th) ); } fg=FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() ); fg.WriteToFile( strcat(myString,".fg") ); cout << "1" << endl; // Set some constants size_t maxiter = 10000; Real tol = 1e-9; size_t verb = 1; // Store the constants in a PropertySet object PropertySet opts,cavaiopts; opts.set("maxiter",maxiter); // Maximum number of iterations opts.set("tol",tol); // Tolerance for convergence opts.set("verbose",verb); // Verbosity (amount of output generated) cavaiopts.set("maxiter",maxiter); // Maximum number of iterations cavaiopts.set("tol",tol); // Tolerance for convergence cavaiopts.set("verbose",verb); // Verbosity (amount of output generated) cavaiopts.set("updates",string("HUGIN")); printf("Doing Juction Tree\n"); JTree jt( fg, opts("updates",string("HUGIN")) ); jt.init(); jt.run(); printf("Doing BP\n"); BP bp(fg, opts("updates",string("SEQRND"))("logdomain",false)); bp.init(); bp.run(); printf("Doing LC\n"); LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("PAIR"))("cavainame",string("BP"))("cavaiopts",string("[updates=SEQMAX,tol=1e-9,maxiter=10000,logdomain=0]"))); //LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("UNIFORM"))); //LC lc(fg, opts("updates",string("SEQRND"))("logdomain",false)("cavity",string("FULL"))); lc.init(); lc.run(); printf("Doing MR\n"); MR mr(fg, opts("updates",string("LINEAR"))("logdomain",false)("inits",string("CLAMPING"))); mr.init(); mr.run(); // Report variable marginals for fg, calculated by the junction tree algorithm file << "Exact variable marginals:" << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg file << jt.belief(fg.var(i)) << endl; // display the "belief" of jt for that variable file << "\n" << endl; // Report variable marginals for fg, calculated by the belief propagation algorithm file << "Approximate (LBF) variable marginals:" << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg file << bp.belief(fg.var(i)) << endl; // display the belief of bp for that variable file << "\n" << endl; // Report variable marginals for fg, calculated by the MoK07 file << "Approximate (Loop Corrected MoK07) variable marginals:" << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg file << lc.belief(fg.var(i)) << endl; // display the belief of bp for that variable file << "\n" << endl; // Report variable marginals for fg, calculated by the MR05 file << "Approximate (Loop Corrected MR05) variable marginals:" << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg file << mr.belief(fg.var(i)) << endl; // display the belief of bp for that variable file << "\n" << endl; file.close(); } return 0; }
/* Convert cell vector of Matlab sets to vector<VarSet> */ vector<VarSet> mx2VarSets(const mxArray *vs, const FactorGraph &fg, long verbose, vector<Permute> &perms) { vector<VarSet> varsets; int n1 = mxGetM(vs); int n2 = mxGetN(vs); if( n2 != 1 && n1 != 1 ) mexErrMsgTxt("varsets should be a Nx1 or 1xN cell matrix."); size_t nr_vs = n1; if( n1 == 1 ) nr_vs = n2; // interpret vs, linear cell array of varsets varsets.reserve( nr_vs ); perms.clear(); perms.reserve( nr_vs ); for( size_t cellind = 0; cellind < nr_vs; cellind++ ) { if( verbose >= 3 ) cerr << "reading varset " << cellind << ": " << endl; mxArray *cell = mxGetCell(vs, cellind); if( verbose >= 3 ) cerr << " got cell " << endl; size_t nr_mem = mxGetN(cell); if( verbose >= 3 ) cerr << " number members: " << nr_mem << endl; double *members = mxGetPr(cell); if( verbose >= 3 ) cerr << " got them! " << endl; // add variables VarSet vsvars; if( verbose >= 3 ) cerr << " vars: "; vector<long> labels(nr_mem,0); vector<size_t> dims(nr_mem,0); for( size_t mi = 0; mi < nr_mem; mi++ ) { labels[mi] = (long)members[mi]; dims[mi] = fg.var(labels[mi]).states(); if( verbose >= 3 ) cerr << labels[mi] << " "; vsvars.insert( fg.var(labels[mi]) ); } if( verbose >= 3 ) cerr << endl; DAI_ASSERT( nr_mem == vsvars.size() ); varsets.push_back(vsvars); // calculate permutation matrix vector<size_t> perm(nr_mem,0); VarSet::iterator j = vsvars.begin(); for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { long gezocht = j->label(); vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht); perm[mi] = piet - labels.begin(); } if( verbose >= 3 ) { cerr << endl << " perm: "; for( vector<size_t>::iterator r=perm.begin(); r!=perm.end(); r++ ) cerr << *r << " "; cerr << endl; } // create Permute object vector<size_t> di(nr_mem,0); size_t prod = 1; for( size_t k = 0; k < nr_mem; k++ ) { di[k] = dims[k]; prod *= dims[k]; } Permute permindex( di, perm ); perms.push_back( permindex ); } if( verbose >= 3 ) { for(vector<VarSet>::const_iterator I=varsets.begin(); I!=varsets.end(); I++ ) cerr << *I << endl; } return( varsets ); }
int main( int argc, char *argv[] ) { if ( argc != 3 ) { cout << "Usage: " << argv[0] << " <filename.fg> [map|pd]" << endl << endl; cout << "Reads factor graph <filename.fg> and runs" << endl; cout << "map: Junction tree MAP" << endl; cout << "pd : LBP and posterior decoding" << endl << endl; return 1; } else { // Redirect cerr to inf.log ofstream errlog("inf.log"); //streambuf* orig_cerr = cerr.rdbuf(); cerr.rdbuf(errlog.rdbuf()); // Read FactorGraph from the file specified by the first command line argument FactorGraph fg; fg.ReadFromFile(argv[1]); // Set some constants size_t maxiter = 10000; Real tol = 1e-9; size_t verb = 1; // Store the constants in a PropertySet object PropertySet opts; opts.set("maxiter",maxiter); // Maximum number of iterations opts.set("tol",tol); // Tolerance for convergence opts.set("verbose",verb); // Verbosity (amount of output generated) if (strcmp(argv[2], "map") == 0) { // Construct another JTree (junction tree) object that is used to calculate // the joint configuration of variables that has maximum probability (MAP state) JTree jtmap( fg, opts("updates",string("HUGIN"))("inference",string("MAXPROD")) ); // Initialize junction tree algorithm jtmap.init(); // Run junction tree algorithm jtmap.run(); // Calculate joint state of all variables that has maximum probability vector<size_t> jtmapstate = jtmap.findMaximum(); /* // Report exact MAP variable marginals cout << "Exact MAP variable marginals:" << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) cout << jtmap.belief(fg.var(i)) << endl; */ // Report exact MAP joint state cerr << "Exact MAP state (log score = " << fg.logScore( jtmapstate ) << "):" << endl; cout << fg.nrVars() << endl; for( size_t i = 0; i < jtmapstate.size(); i++ ) cout << fg.var(i).label() << " " << jtmapstate[i] + 1 << endl; // +1 because in MATLAB assignments start at 1 } else if (strcmp(argv[2], "pd") == 0) { // Construct a BP (belief propagation) object from the FactorGraph fg // using the parameters specified by opts and two additional properties, // specifying the type of updates the BP algorithm should perform and // whether they should be done in the real or in the logdomain BP bp(fg, opts("updates",string("SEQMAX"))("logdomain",true)); // Initialize belief propagation algorithm bp.init(); // Run belief propagation algorithm bp.run(); // Report variable marginals for fg, calculated by the belief propagation algorithm cerr << "LBP posterior decoding (highest prob assignment in marginal):" << endl; cout << fg.nrVars() << endl; for( size_t i = 0; i < fg.nrVars(); i++ ) {// iterate over all variables in fg //cout << bp.belief(fg.var(i)) << endl; // display the belief of bp for that variable Factor marginal = bp.belief(fg.var(i)); Real maxprob = marginal.max(); for (size_t j = 0; j < marginal.nrStates(); j++) { if (marginal[j] == maxprob) { cout << fg.var(i).label() << " " << j + 1 << endl; // +1 because in MATLAB assignments start at 1 } } } } else { cerr << "Invalid inference algorithm specified." << endl; return 1; } } return 0; }
void TestHSMM::test_marginal_cut(const char* filename, size_t ID){ HSMMparam param(filename); FactorGraph *graph; JTree *jt; // Set some constants size_t maxiter = 10000; Real tol = 1e-9; size_t verb = 0; //window size size_t W = 20; size_t start = 0; // Store the constants in a PropertySet object PropertySet opts; opts.set("maxiter",maxiter); // Maximum number of iterations opts.set("tol",tol); // Tolerance for convergence opts.set("verbose",verb); // Verbosity (amount of output generated) Factor O_last; vector< vector<Real> > all_marginal; vector<Real> sequence_marginal; all_marginal.reserve(test_data.size()); cout << "Now we do testing...\n"; for(size_t i=0; i<test_data.size(); i++) { //allocate memory sequence_marginal.reserve(test_data[i].size()); //initialize HSMM of ever increasing size up to test_data[i].size() graph = new FactorGraph(); graph->createHSMMFactorGraph(param.init, param.dist, test_data[i].size()); jt = new JTree(*graph, opts("updates",string("HUGIN"))("heuristic",string("MINWEIGHT")) ); jt->init(); jt->run(); O_last = jt->calcMarginal(graph->var(4)); sequence_marginal.push_back( log(O_last.p().get(test_data[i][0].second)) ); delete jt; for(size_t k=1; k < test_data[i].size(); k++){ jt = new JTree(*graph, opts("updates",string("HUGIN"))("heuristic",string("MINWEIGHT")) ); //clamp a window of observable variables to their values, except last variable which is not clamped start = k-W; if(start < 0) start = 0; for(size_t j = start; j <= k-1; j++){ jt->clamp(test_data[i][j].first, test_data[i][j].second); } jt->init(); jt->run(); //compute p(o_last=c | o_1...o_{last-1}) //this will give us a distribution: {o_last=1, o_last=2, ... o_last=M} O_last = jt->calcMarginal(graph->var(3*k+4)); //since we have a specific observation at last time step: o_last=c, get its probability: sequence_marginal.push_back( log(O_last.p().get(test_data[i][k].second)) ); delete jt; } cout << "Tested point " << i << " out of " << test_data.size() <<"\n"; all_marginal.push_back(sequence_marginal); sequence_marginal.clear(); delete graph; } cout << "Testing done.\n"; ofstream os; stringstream result; result << string("data/HSMMmarginal_test_") << ID << string(".txt"); os.open(result.str().c_str(), ios::trunc); for(size_t i=0; i<all_marginal.size(); i++){ for(size_t j=0; j<all_marginal[i].size(); j++){ os << all_marginal[i][j]<<" "; } os << "\n"; } }
int main( int argc, char *argv[] ) { if( argc != 3 ) { cout << "Usage: " << argv[0] << " <in.fg> <tw>" << endl << endl; cout << "Reports some characteristics of the .fg network." << endl; cout << "Also calculates treewidth (which may take some time) unless <tw> == 0." << endl; return 1; } else { // Read factorgraph FactorGraph fg; char *infile = argv[1]; int calc_tw = atoi(argv[2]); fg.ReadFromFile( infile ); cout << "Number of variables: " << fg.nrVars() << endl; cout << "Number of factors: " << fg.nrFactors() << endl; cout << "Connected: " << fg.isConnected() << endl; cout << "Tree: " << fg.isTree() << endl; cout << "Has short loops: " << hasShortLoops(fg.factors()) << endl; cout << "Has negatives: " << hasNegatives(fg.factors()) << endl; cout << "Binary variables? " << fg.isBinary() << endl; cout << "Pairwise interactions? " << fg.isPairwise() << endl; if( calc_tw ) { std::pair<size_t,size_t> tw = treewidth(fg); cout << "Treewidth: " << tw.first << endl; cout << "Largest cluster for JTree has " << tw.second << " states " << endl; } double stsp = 1.0; for( size_t i = 0; i < fg.nrVars(); i++ ) stsp *= fg.var(i).states(); cout << "Total state space: " << stsp << endl; double cavsum_lcbp = 0.0; double cavsum_lcbp2 = 0.0; size_t max_Delta_size = 0; map<size_t,size_t> cavsizes; for( size_t i = 0; i < fg.nrVars(); i++ ) { VarSet di = fg.delta(i); if( cavsizes.count(di.size()) ) cavsizes[di.size()]++; else cavsizes[di.size()] = 1; size_t Ds = fg.Delta(i).nrStates(); if( Ds > max_Delta_size ) max_Delta_size = Ds; cavsum_lcbp += di.nrStates(); for( VarSet::const_iterator j = di.begin(); j != di.end(); j++ ) cavsum_lcbp2 += j->states(); } cout << "Maximum pancake has " << max_Delta_size << " states" << endl; cout << "LCBP with full cavities needs " << cavsum_lcbp << " BP runs" << endl; cout << "LCBP with only pairinteractions needs " << cavsum_lcbp2 << " BP runs" << endl; cout << "Cavity sizes: "; for( map<size_t,size_t>::const_iterator it = cavsizes.begin(); it != cavsizes.end(); it++ ) cout << it->first << "(" << it->second << ") "; cout << endl; cout << "Type: " << (fg.isPairwise() ? "pairwise" : "higher order") << " interactions, " << (fg.isBinary() ? "binary" : "nonbinary") << " variables" << endl; if( fg.isPairwise() ) { bool girth_reached = false; size_t loopdepth; for( loopdepth = 2; loopdepth <= fg.nrVars() && !girth_reached; loopdepth++ ) { size_t nr_loops = countLoops( fg, loopdepth ); cout << "Loops up to " << loopdepth << " variables: " << nr_loops << endl; if( nr_loops > 0 ) girth_reached = true; } if( girth_reached ) cout << "Girth: " << loopdepth-1 << endl; else cout << "Girth: infinity" << endl; } return 0; } }