/** Only maximization step included * * This function performs maximization based on the evidence collected from tab file * Since there's no belief propagation stage, it does not return proper likelihood. */ Real UnsafeEmalg::iterateWithoutEstep(MaximizationStep &mstep) { Real logZ = 0; Real likelihood = 0; // Expectation calculation int nProcessed = 0; for( Evidence::const_iterator e = _evidence.begin(); e != _evidence.end(); ++e ) { InfAlg* clamped = _estep.clone(); // Apply evidence for( Evidence::Observation::const_iterator i = e->begin(); i != e->end(); ++i ) clamped->clamp( clamped->fg().findVar(i->first), i->second ); mstep.addExpectations( *clamped ); delete clamped; nProcessed++; if (nProcessed % 10 == 0) { cout << nProcessed << " number of samples processed" << endl; } } // Maximization of parameters mstep.maximize(_estep.fg()); return likelihood; }
void doDAI() { double tic = toc(); if( obj != NULL ) { obj->init(); obj->run(); time += toc() - tic; try { logZ = obj->logZ(); has_logZ = true; } catch( Exception &e ) { has_logZ = false; } try { maxdiff = obj->maxDiff(); has_maxdiff = true; } catch( Exception &e ) { has_maxdiff = false; } try { iters = obj->Iterations(); has_iters = true; } catch( Exception &e ) { has_iters = false; } q = allBeliefs(); }; }
string mapper(EMdata &dat) { FactorGraph fg = dat.fg; PropertySet infprops = getProps(); InfAlg* inf = newInfAlg(INF_TYPE, fg, infprops); inf->init(); // Read sample from file Evidence e; istringstream estream(dat.tabFile); e.addEvidenceTabFile(estream, fg); // Read EM specification istringstream emstream(dat.emFile); EMAlg em(e, *inf, emstream); // perform 1 iteration e-step Real likelihood = hadoop_iterate(em._msteps, em._evidence, em._estep); dat.likelihood = likelihood; dat.msteps = em._msteps; // Clean up delete inf; dat.emFile = ""; // reduce amount of serialization dat.tabFile = ""; return emToString(dat); }
int main() { // This is the INFERENCE/EM engine, derived from the // libDAI example program (example_sprinkler_em) // (http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html) // // The factor graph file (input.fg) has to be generated first // and the data file (sprinkler.tab), // as well as the EM commands // Read the factorgraph from the file FactorGraph Network; Network.ReadFromFile( "input.fg" ); // Prepare junction-tree object for doing exact inference for E-step PropertySet infprops; infprops.set( "verbose", (size_t)1 ); infprops.set( "updates", string("HUGIN") ); infprops.set( "maxiter", string("1000") ); infprops.set( "tol", string("0.00001") ); infprops.set( "logdomain", true); infprops.set( "updates", string("SEQFIX") ); InfAlg* inf = newInfAlg("BP", Network, infprops ); inf->init(); // Read sample from file Evidence e; ifstream estream( "input.tab" ); e.addEvidenceTabFile( estream, Network ); cerr << "Number of samples: " << e.nrSamples() << endl; // Read EM specification ifstream emstream( "input.em" ); EMAlg em(e, *inf, emstream); // Iterate EM until convergence while( !em.hasSatisfiedTermConditions() ) { Real l = em.iterate(); cerr << "Iteration " << em.Iterations() << " likelihood: " << l <<endl; Real c = inf->logZ(); cerr << "Iteration infAlg " << em.Iterations() << " likelihood: " << c <<endl; } cout.precision(6); cout << inf->fg(); delete inf; return 0; }
EMAlg::EMAlg( const Evidence &evidence, InfAlg &estep, std::istream &msteps_file ) : _evidence(evidence), _estep(estep), _msteps(), _iters(0), _lastLogZ(), _max_iters(MAX_ITERS_DEFAULT), _log_z_tol(LOG_Z_TOL_DEFAULT) { msteps_file.exceptions( std::istream::eofbit | std::istream::failbit | std::istream::badbit ); size_t num_msteps = -1; msteps_file >> num_msteps; _msteps.reserve(num_msteps); for( size_t i = 0; i < num_msteps; ++i ) _msteps.push_back( MaximizationStep( msteps_file, estep.fg() ) ); }
void SharedParameters::collectSufficientStatistics( InfAlg &alg ) { for( std::map< FactorIndex, Permute >::iterator i = _perms.begin(); i != _perms.end(); ++i ) { Permute &perm = i->second; VarSet &vs = _varsets[i->first]; Factor b = alg.belief(vs); Prob p( b.states(), 0.0 ); for( size_t entry = 0; entry < b.states(); ++entry ) p[entry] = b[perm.convertLinearIndex(entry)]; // apply inverse permutation _estimation->addSufficientStatistics( p ); } }
void SharedParameters::collectExpectations( InfAlg &alg ) { for( std::map< FactorIndex, Permute >::iterator i = _perms.begin(); i != _perms.end(); ++i ) { Permute &perm = i->second; VarSet &vs = _varsets[i->first]; Factor b = alg.belief(vs); Prob p( b.nrStates(), 0.0 ); for( size_t entry = 0; entry < b.nrStates(); ++entry ) p.set( entry, b[perm.convertLinearIndex(entry)] ); // apply inverse permutation (*_expectations) += p; } }
Real EMAlg::iterate( MaximizationStep &mstep ) { Real logZ = 0; Real likelihood = 0; _estep.run(); logZ = _estep.logZ(); // Expectation calculation for( Evidence::const_iterator e = _evidence.begin(); e != _evidence.end(); ++e ) { InfAlg* clamped = _estep.clone(); // Apply evidence for( Evidence::Observation::const_iterator i = e->begin(); i != e->end(); ++i ) clamped->clamp( clamped->fg().findVar(i->first), i->second ); clamped->init(); clamped->run(); likelihood += clamped->logZ() - logZ; mstep.addExpectations( *clamped ); delete clamped; } // Maximization of parameters mstep.maximize( _estep.fg() ); return likelihood; }
Real LC::CalcCavityDist (size_t i, const std::string &name, const PropertySet &opts) { Factor Bi; Real maxdiff = 0; if( props.verbose >= 2 ) cerr << "Initing cavity " << var(i) << "(" << delta(i).size() << " vars, " << delta(i).nrStates() << " states)" << endl; if( props.cavity == Properties::CavityType::UNIFORM ) Bi = Factor(delta(i)); else { InfAlg *cav = newInfAlg( name, *this, opts ); cav->makeCavity( i ); if( props.cavity == Properties::CavityType::FULL ) Bi = calcMarginal( *cav, cav->fg().delta(i), props.reinit ); else if( props.cavity == Properties::CavityType::PAIR ) { vector<Factor> pairbeliefs = calcPairBeliefs( *cav, cav->fg().delta(i), props.reinit, false ); for( size_t ij = 0; ij < pairbeliefs.size(); ij++ ) Bi *= pairbeliefs[ij]; } else if( props.cavity == Properties::CavityType::PAIR2 ) { vector<Factor> pairbeliefs = calcPairBeliefs( *cav, cav->fg().delta(i), props.reinit, true ); for( size_t ij = 0; ij < pairbeliefs.size(); ij++ ) Bi *= pairbeliefs[ij]; } maxdiff = cav->maxDiff(); delete cav; } Bi.normalize(); _cavitydists[i] = Bi; return maxdiff; }
int main( int argc, char** argv ) { if( argc != 4 ) usage("Incorrect number of arguments."); FactorGraph fg; fg.ReadFromFile( argv[1] ); PropertySet infprops; infprops.set( "verbose", (size_t)0 ); infprops.set( "updates", string("HUGIN") ); InfAlg* inf = newInfAlg( "JTREE", fg, infprops ); inf->init(); Evidence e; ifstream estream( argv[2] ); e.addEvidenceTabFile( estream, fg ); cout << "Number of samples: " << e.nrSamples() << endl; for( Evidence::iterator ps = e.begin(); ps != e.end(); ps++ ) cout << "Sample #" << (ps - e.begin()) << " has " << ps->size() << " observations." << endl; ifstream emstream( argv[3] ); EMAlg em(e, *inf, emstream); while( !em.hasSatisfiedTermConditions() ) { Real l = em.iterate(); cout << "Iteration " << em.Iterations() << " likelihood: " << l <<endl; } cout << endl << "Inferred Factor Graph:" << endl << "######################" << endl; cout.precision(12); cout << inf->fg(); delete inf; return 0; }
Real EM_estep(MaximizationStep &mstep, const Evidence &evidence, InfAlg &inf) { Real likelihood = 0; inf.run(); Real logZ = inf.logZ(); // Expectation calculation for (Evidence::const_iterator e = evidence.begin(); e != evidence.end(); ++e) { InfAlg* clamped = inf.clone(); // Apply evidence for (Evidence::Observation::const_iterator i = e->begin(); i != e->end(); ++i) clamped->clamp(clamped->fg().findVar(i->first), i->second); clamped->init(); clamped->run(); likelihood += clamped->logZ() - logZ; mstep.addExpectations(*clamped); delete clamped; } return likelihood; }
vector<Factor> allBeliefs() { vector<Factor> result; for( size_t i = 0; i < obj->fg().nrVars(); i++ ) result.push_back( obj->belief( obj->fg().var(i) ) ); return result; }
string identify() { if( obj != NULL ) return obj->identify(); else return "NULL"; }
Real BBPCostFunction::evaluate( const InfAlg &ia, const vector<size_t> *stateP ) const { Real cf = 0.0; const FactorGraph &fg = ia.fg(); switch( (size_t)(*this) ) { case CFN_BETHE_ENT: // ignores state cf = -ia.logZ(); break; case CFN_VAR_ENT: // ignores state for( size_t i = 0; i < fg.nrVars(); i++ ) cf += -ia.beliefV(i).entropy(); break; case CFN_FACTOR_ENT: // ignores state for( size_t I = 0; I < fg.nrFactors(); I++ ) cf += -ia.beliefF(I).entropy(); break; case CFN_GIBBS_B: case CFN_GIBBS_B2: case CFN_GIBBS_EXP: { DAI_ASSERT( stateP != NULL ); vector<size_t> state = *stateP; DAI_ASSERT( state.size() == fg.nrVars() ); for( size_t i = 0; i < fg.nrVars(); i++ ) { Real b = ia.beliefV(i)[state[i]]; switch( (size_t)(*this) ) { case CFN_GIBBS_B: cf += b; break; case CFN_GIBBS_B2: cf += b * b / 2.0; break; case CFN_GIBBS_EXP: cf += exp( b ); break; default: DAI_THROW(UNKNOWN_ENUM_VALUE); } } break; } case CFN_GIBBS_B_FACTOR: case CFN_GIBBS_B2_FACTOR: case CFN_GIBBS_EXP_FACTOR: { DAI_ASSERT( stateP != NULL ); vector<size_t> state = *stateP; DAI_ASSERT( state.size() == fg.nrVars() ); for( size_t I = 0; I < fg.nrFactors(); I++ ) { size_t x_I = getFactorEntryForState( fg, I, state ); Real b = ia.beliefF(I)[x_I]; switch( (size_t)(*this) ) { case CFN_GIBBS_B_FACTOR: cf += b; break; case CFN_GIBBS_B2_FACTOR: cf += b * b / 2.0; break; case CFN_GIBBS_EXP_FACTOR: cf += exp( b ); break; default: DAI_THROW(UNKNOWN_ENUM_VALUE); } } break; } default: DAI_THROWE(UNKNOWN_ENUM_VALUE, "Unknown cost function " + std::string(*this)); } return cf; }
int main( int argc, char *argv[] ) { if ( argc != 5 ) { cout << "This program is part of libDAI - http://www.libdai.org/" << endl << endl; cout << "It is one of the winning solvers that participated in the" << endl; cout << "UAI 2010 Approximate Inference Challenge" << endl; cout << "(see http://www.cs.huji.ac.il/project/UAI10/)" << endl << endl; cout << "Usage: " << argv[0] << " <filename.uai> <filename.uai.evid> <seed> <task>" << endl << endl; return 1; } else { double starttic = toc(); size_t verbose = 1; // verbosity size_t ia_verbose = 0; // verbosity of inference algorithms bool surgery = true; // change factor graph structure based on evidence if( verbose ) cout << "Solver: " << argv[0] << endl; // set random seed size_t seed = fromString<size_t>( argv[3] ); rnd_seed( seed ); if( verbose ) cout << "Seed: " << seed << endl; // check whether the task is valid string task( argv[4] ); if( task != string("PR") && task != string("MPE") && task != string("MAR") ) DAI_THROWE(RUNTIME_ERROR,"Unknown task"); if( verbose ) cout << "Task: " << task << endl; // output other command line options if( verbose ) { cout << "Factorgraph filename: " << argv[1] << endl; cout << "Evidence filename: " << argv[2] << endl; } // get time and memory limits char *buf = getenv( "UAI_TIME" ); double UAI_time = INFINITY; if( buf != NULL ) UAI_time = fromString<double>( buf ); buf = getenv( "UAI_MEMORY" ); size_t UAI_memory = 0; if( buf != NULL ) { UAI_memory = fromString<double>( buf ) * 1024 * 1024 * 1024; } if( verbose ) { cout << "Time limit: " << UAI_time << endl; cout << "Memory limit: " << UAI_memory << endl; } // build output file name vector<string> pathComponents = tokenizeString( string(argv[1]), true, "/" ); string outfile = pathComponents.back() + "." + task; if( verbose ) cout << "Output filename: " << outfile << endl; // open output stream ofstream os; os.open( outfile.c_str() ); if( !os.is_open() ) DAI_THROWE(CANNOT_WRITE_FILE,"Cannot write to file " + outfile); if( verbose ) cout << "Opened output stream" << endl; // read factor graph vector<Var> vars; vector<Factor> facs0; vector<Permute> permutations; if( verbose ) cout << "Reading factor graph..." << endl; ReadUaiAieFactorGraphFile( argv[1], verbose, vars, facs0, permutations ); if( verbose ) cout << "Successfully read factor graph" << endl; // check if it could be a grid bool couldBeGrid = true; FactorGraph fg0( facs0.begin(), facs0.end(), vars.begin(), vars.end(), facs0.size(), vars.size() ); for( size_t i = 0; i < fg0.nrVars(); i++ ) if( fg0.delta(i).size() > 4 ) { couldBeGrid = false; break; } if( couldBeGrid ) for( size_t I = 0; I < fg0.nrFactors(); I++ ) if( fg0.factor(I).vars().size() > 2 ) { couldBeGrid = false; break; } if( verbose ) { if( couldBeGrid ) cout << "This could be a grid!" << endl; else cout << "This cannot be a grid!" << endl; } // read evidence if( verbose ) cout << "Reading evidence..." << endl; vector<map<size_t,size_t> > evid = ReadUaiAieEvidenceFile( argv[2], verbose ); if( verbose ) cout << "Successfully read " << evid.size() << " evidence cases" << endl; // write output header if( verbose ) cout << " Writing header to file..." << endl; os << task << endl; // construct clamped factor graphs if( verbose ) cout << "Constructing clamped factor graphs..." << endl; vector<FactorGraph> fgs; fgs.reserve( evid.size() ); for( size_t ev = 0; ev < evid.size(); ev++ ) { if( verbose ) cout << " Evidence case " << ev << "..." << endl; // copy vector of factors vector<Factor> facs( facs0 ); // change factor graph to reflect observed evidence if( verbose ) cout << " Applying evidence..." << endl; if( surgery ) { // replace factors with clamped variables with slices for( size_t I = 0; I < facs.size(); I++ ) { for( map<size_t,size_t>::const_iterator e = evid[ev].begin(); e != evid[ev].end(); e++ ) { if( facs[I].vars() >> vars[e->first] ) { if( verbose >= 2 ) cout << " Clamping " << e->first << " to value " << e->second << " in factor " << I << " = " << facs[I].vars() << endl; facs[I] = facs[I].slice( vars[e->first], e->second ); if( verbose >= 2 ) cout << " ...remaining vars: " << facs[I].vars() << endl; } } } // remove empty factors Real logZcorr = 0.0; for( vector<Factor>::iterator I = facs.begin(); I != facs.end(); ) if( I->vars().size() == 0 ) { logZcorr += std::log( (Real)(*I)[0] ); I = facs.erase( I ); } else I++; // multiply with logZcorr constant if( facs.size() == 0 ) facs.push_back( Factor( VarSet(), std::exp(logZcorr) ) ); else facs.front() *= std::exp(logZcorr); } // add delta factors corresponding to observed variable values for( map<size_t,size_t>::const_iterator e = evid[ev].begin(); e != evid[ev].end(); e++ ) facs.push_back( createFactorDelta( vars[e->first], e->second ) ); // construct clamped factor graph if( verbose ) cout << " Constructing factor graph..." << endl; fgs.push_back( FactorGraph( facs.begin(), facs.end(), vars.begin(), vars.end(), facs.size(), vars.size() ) ); } // variables for storing best results so far vector<PRbest> bestPR( evid.size() ); vector<MARbest> bestMAR( evid.size() ); vector<MPEbest> bestMPE( evid.size() ); for( size_t ev = 0; ev < evid.size(); ev++ ) bestMPE[ev].state = stateVec( fgs[ev].nrVars(), 0 ); vector<size_t> ev2go; ev2go.reserve( evid.size() ); for( size_t ev = 0; ev < evid.size(); ev++ ) ev2go.push_back( ev ); // solve inference problems if( verbose ) cout << "Solving inference problems..." << endl; bool first = true; size_t nrsolvers = 3; vector<size_t> nrsubsolvers( nrsolvers ); nrsubsolvers[0] = 2; nrsubsolvers[1] = 1; nrsubsolvers[2] = 1; double MPEdamping = 0.49; // for each (sub)solver for( size_t solver = 0; solver < nrsolvers; solver++ ) { if( verbose ) cout << " Solver " << solver << endl; // for each evidence case size_t subsolver = 0; for( long _ev = 0; _ev < (long)ev2go.size(); ) { bool improved = false; size_t ev = ev2go[_ev]; if( verbose ) cout << " Evidence case " << ev << ", subsolver = " << subsolver << "..." << endl; // construct inference algorithm on clamped factor graph if( verbose ) cout << " Constructing inference algorithm..." << endl; InfAlg *ia = NULL; double tic = toc(); bool failed = false; try { // construct if( solver == 0 ) { // the quick one double remtime = (UAI_time - (toc() - starttic)) * 0.9; if( remtime < 1.0 ) remtime = 1.0 ; double maxtime = remtime / (ev2go.size() - _ev); if( verbose ) { cout << " Past time: " << (toc() - starttic) << endl; cout << " Remaining time:" << remtime << endl; cout << " Allotted time: " << maxtime << endl; } string maxtimestr; if( maxtime != INFINITY ) maxtimestr = ",maxtime=" + toString(maxtime); // quick and dirty... if( task == "MPE" ) ia = newInfAlgFromString( "BP[inference=MAXPROD,updates=SEQRND,logdomain=" + toString(subsolver) + ",tol=1e-9,maxiter=10000" + maxtimestr + ",damping=0.1,verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else { if( couldBeGrid ) ia = newInfAlgFromString( "HAK[doubleloop=1,clusters=LOOP,init=UNIFORM,loopdepth=4,tol=1e-9,maxiter=10000" + maxtimestr + ",verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else ia = newInfAlgFromString( "BP[inference=SUMPROD,updates=SEQRND,logdomain=" + toString(subsolver) + ",tol=1e-9,maxiter=10000" + maxtimestr + ",damping=0.0,verbose=" + toString(ia_verbose) + "]", fgs[ev] ); } } else if( solver == 1 ) { // the exact one string maxmemstr; if( UAI_memory != 0 ) maxmemstr = ",maxmem=" + toString(UAI_memory); if( task == "MPE" ) ia = newInfAlgFromString( "JTREE[inference=MAXPROD,updates=HUGIN" + maxmemstr + ",verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else ia = newInfAlgFromString( "JTREE[inference=SUMPROD,updates=HUGIN" + maxmemstr + ",verbose=" + toString(ia_verbose) + "]", fgs[ev] ); } else if( solver == 2 ) { // the decent one double remtime = (UAI_time - (toc() - starttic)); if( remtime < 1.0 ) remtime = 1.0; double maxtime = 0.95 * remtime / (ev2go.size() - _ev); if( verbose ) { cout << " Past time: " << (toc() - starttic) << endl; cout << " Remaining time:" << remtime << endl; cout << " Allotted time: " << maxtime << endl; } if( task == "MPE" ) maxtime /= fgs[ev].nrVars(); string maxtimestr; if( maxtime != INFINITY ) maxtimestr = ",maxtime=" + toString(maxtime); if( task == "MPE" ) ia = newInfAlgFromString( "DECMAP[ianame=BP,iaopts=[inference=MAXPROD,updates=SEQRND,logdomain=1,tol=1e-9,maxiter=10000" + maxtimestr + ",damping=" + toString(MPEdamping) + ",verbose=0],reinit=1,verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else { if( couldBeGrid ) ia = newInfAlgFromString( "HAK[doubleloop=1,clusters=LOOP,init=UNIFORM,loopdepth=4,tol=1e-9" + maxtimestr + ",maxiter=100000,verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else { if( task == "PR" ) ia = newInfAlgFromString( "HAK[doubleloop=1,clusters=MIN,init=UNIFORM,tol=1e-9" + maxtimestr + ",maxiter=100000,verbose=" + toString(ia_verbose) + "]", fgs[ev] ); else ia = newInfAlgFromString( "GIBBS[maxiter=1000000000,burnin=1000,restart=10000000" + maxtimestr + ",verbose=" + toString(ia_verbose) + "]", fgs[ev] ); } } } // initialize if( verbose ) cout << " Initializing inference algorithm..." << endl; ia->init(); // run if( verbose ) cout << " Running inference algorithm..." << endl; ia->run(); if( verbose ) cout << " Inference algorithm finished..." << endl; } catch( Exception &e ) { failed = true; if( verbose ) { cout << " Inference algorithm failed...!" << endl; cout << " Exception: " << e.what() << endl; } } if( verbose ) cout << " Used time: " << toc() - tic << endl; if( !failed && verbose ) { try { cout << " Number of iterations: " << ia->Iterations() << endl; } catch( Exception &e ) { cout << " Number of iterations: N/A" << endl; } try { cout << " Final maxdiff: " << ia->maxDiff() << endl; } catch( Exception &e ) { cout << " Final maxdiff: N/A" << endl; } } // update results for inference task if( !failed ) { if( task == "PR" ) { PRbest cur; // calculate PR value cur.value = ia->logZ() / dai::log((Real)10.0); // get maxdiff try { cur.maxdiff = ia->maxDiff(); } catch( Exception &e ) { cur.maxdiff = 1e-9; } // only update if this run has converged if( ((cur.maxdiff <= 1e-9) || (cur.maxdiff <= bestPR[ev].maxdiff)) && !dai::isnan(cur.value) ) { // if this was exact inference, we are ready if( solver == 1 ) { ev2go.erase( ev2go.begin() + _ev ); _ev--; cur.ready = true; } if( verbose ) cout << " Replacing best PR value so far (" << bestPR[ev].value << ") with new value " << cur.value << endl; bestPR[ev] = cur; improved = true; } else { if( verbose ) cout << " Discarding PR value " << cur.value << endl; } } else if( task == "MAR" ) { MARbest cur; // get variable beliefs bool hasnans = false; cur.beliefs.reserve( fgs[ev].nrVars() ); for( size_t i = 0; i < fgs[ev].nrVars(); i++ ) { cur.beliefs.push_back( ia->beliefV(i) ); if( cur.beliefs.back().hasNaNs() ) hasnans = true; } // get maxdiff try { cur.maxdiff = ia->maxDiff(); } catch( Exception &e ) { cur.maxdiff = 1e-9; } // only update if this run has converged if( ((cur.maxdiff <= 1e-9) || (cur.maxdiff <= bestMAR[ev].maxdiff)) && !hasnans ) { // if this was exact inference, we are ready if( solver == 1 ) { ev2go.erase( ev2go.begin() + _ev ); _ev--; cur.ready = true; } if( verbose ) cout << " Replacing best beliefs so far with new beliefs" << endl; bestMAR[ev] = cur; improved = true; } else { if( verbose ) cout << " Discarding beliefs" << endl; } } else if( task == "MPE" ) { MPEbest cur; // calculate MPE state cur.state = ia->findMaximum(); // calculate MPE value cur.value = fgs[ev].logScore( cur.state ); // update best MPE state and value if( cur.value > bestMPE[ev].value && !dai::isnan(cur.value) ) { // if this was exact inference, we are ready if( solver == 1 ) { ev2go.erase( ev2go.begin() + _ev ); _ev--; cur.ready = true; } if( verbose ) cout << " Replacing best MPE value so far (" << bestMPE[ev].value << ") with new value " << cur.value << endl; bestMPE[ev] = cur; improved = true; } else { if( verbose ) cout << " New MPE value " << cur.value << " not better than best one so far " << bestMPE[ev].value << endl; } } } // remove inference algorithm if( verbose ) cout << " Cleaning up..." << endl; if( !failed ) delete ia; // write current best output to stream if( improved ) { if( verbose ) cout << " Writing output..." << endl; if( first ) first = false; else os << "-BEGIN-" << endl; os << evid.size() << endl; for( size_t ev = 0; ev < evid.size(); ev++ ) { if( task == "PR" ) { // output probability of evidence os << bestPR[ev].value << endl; } else if( task == "MAR" ) { // output variable marginals os << bestMAR[ev].beliefs.size() << " "; for( size_t i = 0; i < bestMAR[ev].beliefs.size(); i++ ) { os << bestMAR[ev].beliefs[i].nrStates() << " "; for( size_t s = 0; s < bestMAR[ev].beliefs[i].nrStates(); s++ ) os << bestMAR[ev].beliefs[i][s] << " "; } os << endl; } else if( task == "MPE" ) { // output MPE state os << fgs[ev].nrVars() << " "; for( size_t i = 0; i < fgs[ev].nrVars(); i++ ) os << bestMPE[ev].state[i] << " "; os << endl; } } os.flush(); } if( verbose ) cout << " Done..." << endl; if( !improved ) subsolver++; if( improved || subsolver >= nrsubsolvers[solver] || couldBeGrid ) { subsolver = 0; _ev++; } } if( task == "MPE" && solver == 2 && (toc() - starttic) < UAI_time && MPEdamping != 0.0 ) { MPEdamping /= 2.0; solver--; // repeat this one } if( ev2go.size() == 0 ) break; } // close output file if( verbose ) cout << "Closing output file..." << endl; os.close(); if( verbose ) cout << "Done!" << endl; } return 0; }
/// Run the algorithm and store its results void doDAI() { double tic = toc(); if( obj != NULL ) { // Initialize obj->init(); // Run obj->run(); // Record the time time += toc() - tic; // Store logarithm of the partition sum (if supported) try { logZ = obj->logZ(); has_logZ = true; } catch( Exception &e ) { if( e.getCode() == Exception::NOT_IMPLEMENTED ) has_logZ = false; else throw; } // Store maximum difference encountered in last iteration (if supported) try { maxdiff = obj->maxDiff(); has_maxdiff = true; } catch( Exception &e ) { if( e.getCode() == Exception::NOT_IMPLEMENTED ) has_maxdiff = false; else throw; } // Store number of iterations needed (if supported) try { iters = obj->Iterations(); has_iters = true; } catch( Exception &e ) { if( e.getCode() == Exception::NOT_IMPLEMENTED ) has_iters = false; else throw; } // Store variable marginals varMarginals.clear(); for( size_t i = 0; i < obj->fg().nrVars(); i++ ) varMarginals.push_back( obj->beliefV( i ) ); // Store factor marginals facMarginals.clear(); for( size_t I = 0; I < obj->fg().nrFactors(); I++ ) try { facMarginals.push_back( obj->beliefF( I ) ); } catch( Exception &e ) { if( e.getCode() == Exception::BELIEF_NOT_AVAILABLE ) facMarginals.push_back( Factor( obj->fg().factor(I).vars(), INFINITY ) ); else throw; } // Store all marginals calculated by the method allMarginals = obj->beliefs(); }; }