Removed stuff from InfAlg, moved it to individual inference algorithms
[libdai.git] / src / mf.cpp
index e95006e..6da2bd4 100644 (file)
@@ -37,79 +37,78 @@ using namespace std;
 const char *MF::Name = "MF";
 
 
-bool MF::checkProperties() {
-    if( !HasProperty("tol") )
-        return false;
-    if (!HasProperty("maxiter") )
-        return false;
-    if (!HasProperty("verbose") )
-        return false;
-    
-    ConvertPropertyTo<double>("tol");
-    ConvertPropertyTo<size_t>("maxiter");
-    ConvertPropertyTo<size_t>("verbose");
-
-    return true;
+void MF::setProperties( const PropertySet &opts ) {
+    assert( opts.hasKey("tol") );
+    assert( opts.hasKey("maxiter") );
+    assert( opts.hasKey("verbose") );
+
+    props.tol = opts.getStringAs<double>("tol");
+    props.maxiter = opts.getStringAs<size_t>("maxiter");
+    props.verbose = opts.getStringAs<size_t>("verbose");
 }
 
 
-void MF::Regenerate() {
-    DAIAlgFG::Regenerate();
+PropertySet MF::getProperties() const {
+    PropertySet opts;
+    opts.Set( "tol", props.tol );
+    opts.Set( "maxiter", props.maxiter );
+    opts.Set( "verbose", props.verbose );
+    return opts;
+}
+
 
+void MF::create() {
     // clear beliefs
     _beliefs.clear();
     _beliefs.reserve( nrVars() );
 
     // create beliefs
-    for( vector<Var>::const_iterator i = vars().begin(); i != vars().end(); i++ ) 
-        _beliefs.push_back(Factor(*i));
+    for( size_t i = 0; i < nrVars(); ++i )
+        _beliefs.push_back(Factor(var(i)));
 }
 
 
 string MF::identify() const { 
     stringstream result (stringstream::out);
-    result << Name << GetProperties();
+    result << Name << getProperties();
     return result.str();
 }
 
 
 void MF::init() {
-    assert( checkProperties() );
-
     for( vector<Factor>::iterator qi = _beliefs.begin(); qi != _beliefs.end(); qi++ )
         qi->fill(1.0);
 }
 
 
 double MF::run() {
-    clock_t tic = toc();
+    double tic = toc();
 
-    if( Verbose() >= 1 )
+    if( props.verbose >= 1 )
         cout << "Starting " << identify() << "...";
 
     size_t pass_size = _beliefs.size();
     Diffs diffs(pass_size * 3, 1.0);
 
     size_t t=0;
-    for( t=0; t < (MaxIter()*pass_size) && diffs.max() > Tol(); t++ ) {
+    for( t=0; t < (props.maxiter*pass_size) && diffs.maxDiff() > props.tol; t++ ) {
         // choose random Var i
         size_t i = (size_t) (nrVars() * rnd_uniform());
 
         Factor jan;
         Factor piet;
-        for( _nb_cit I = nb1(i).begin(); I != nb1(i).end(); I++ ) {
-
+        foreach( const Neighbor &I, nbV(i) ) {
             Factor henk;
-            for( _nb_cit j = nb2(*I).begin(); j != nb2(*I).end(); j++ ) // for all j in I \ i
-                if( *j != i )
-                    henk *= _beliefs[*j];
-            piet = factor(*I).log0();
+            foreach( const Neighbor &j, nbF(I) ) // for all j in I \ i
+                if( j != i )
+                    henk *= _beliefs[j];
+            piet = factor(I).log0();
             piet *= henk;
             piet = piet.part_sum(var(i));
             piet = piet.exp();
             jan *= piet; 
         }
-            
+
         jan.normalize( _normtype );
 
         if( jan.hasNaNs() ) {
@@ -122,25 +121,26 @@ double MF::run() {
         _beliefs[i] = jan;
     }
 
-    updateMaxDiff( diffs.max() );
+    if( diffs.maxDiff() > maxdiff )
+        maxdiff = diffs.maxDiff();
 
-    if( Verbose() >= 1 ) {
-        if( diffs.max() > Tol() ) {
-            if( Verbose() == 1 )
+    if( props.verbose >= 1 ) {
+        if( diffs.maxDiff() > props.tol ) {
+            if( props.verbose == 1 )
                 cout << endl;
-            cout << "MF::run:  WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.max() << endl;
+            cout << "MF::run:  WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
         } else {
-            if( Verbose() >= 2 )
+            if( props.verbose >= 2 )
                 cout << "MF::run:  ";
             cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " clocks)." << endl;
         }
     }
 
-    return diffs.max();
+    return diffs.maxDiff();
 }
 
 
-Factor MF::belief1 (size_t i) const {
+Factor MF::beliefV (size_t i) const {
     Factor piet;
     piet = _beliefs[i];
     piet.normalize( Prob::NORMPROB );
@@ -159,14 +159,14 @@ Factor MF::belief (const VarSet &ns) const {
 
 
 Factor MF::belief (const Var &n) const {
-    return( belief1( findVar( n) ) );
+    return( beliefV( findVar( n ) ) );
 }
 
 
 vector<Factor> MF::beliefs() const {
     vector<Factor> result;
     for( size_t i = 0; i < nrVars(); i++ )
-        result.push_back( belief1(i) );
+        result.push_back( beliefV(i) );
     return result;
 }
 
@@ -175,11 +175,11 @@ Complex MF::logZ() const {
     Complex sum = 0.0;
     
     for(size_t i=0; i < nrVars(); i++ )
-        sum -= belief1(i).entropy();
+        sum -= beliefV(i).entropy();
     for(size_t I=0; I < nrFactors(); I++ ) {
         Factor henk;
-        for( _nb_cit j = nb2(I).begin(); j != nb2(I).end(); j++ )   // for all j in I
-            henk *= _beliefs[*j];
+        foreach( const Neighbor &j, nbF(I) )  // for all j in I
+            henk *= _beliefs[j];
         henk.normalize( Prob::NORMPROB );
         Factor piet;
         piet = factor(I).log0();
@@ -193,7 +193,7 @@ Complex MF::logZ() const {
 
 void MF::init( const VarSet &ns ) {
     for( size_t i = 0; i < nrVars(); i++ ) {
-        if( ns && var(i) )
+        if( ns.contains(var(i) ) )
             _beliefs[i].fill( 1.0 );
     }
 }