Improved documentation of factor.h, ...
[libdai.git] / src / mf.cpp
index 582bd57..ae92182 100644 (file)
@@ -1,6 +1,7 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [j dot mooij at science dot ru dot nl]
-    Radboud University Nijmegen, The Netherlands
-    
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
     This file is part of libDAI.
 
     libDAI is free software; you can redistribute it and/or modify
@@ -24,7 +25,6 @@
 #include <map>
 #include <set>
 #include <dai/mf.h>
-#include <dai/diffs.h>
 #include <dai/util.h>
 
 
@@ -40,11 +40,17 @@ const char *MF::Name = "MF";
 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");
+    if( opts.hasKey("verbose") )
+        props.verbose = opts.getStringAs<size_t>("verbose");
+    else
+        props.verbose = 0U;
+    if( opts.hasKey("damping") )
+        props.damping = opts.getStringAs<double>("damping");
+    else
+        props.damping = 0.0;
 }
 
 
@@ -53,6 +59,7 @@ PropertySet MF::getProperties() const {
     opts.Set( "tol", props.tol );
     opts.Set( "maxiter", props.maxiter );
     opts.Set( "verbose", props.verbose );
+    opts.Set( "damping", props.damping );
     return opts;
 }
 
@@ -62,19 +69,18 @@ string MF::printProperties() const {
     s << "[";
     s << "tol=" << props.tol << ",";
     s << "maxiter=" << props.maxiter << ",";
-    s << "verbose=" << props.verbose << "]";
+    s << "verbose=" << props.verbose << ",";
+    s << "damping=" << props.damping << "]";
     return s.str();
 }
 
 
-void MF::create() {
-    // clear beliefs
+void MF::construct() {
+    // create beliefs
     _beliefs.clear();
     _beliefs.reserve( nrVars() );
-
-    // create beliefs
     for( size_t i = 0; i < nrVars(); ++i )
-        _beliefs.push_back(Factor(var(i)));
+        _beliefs.push_back( Factor( var(i) ) );
 }
 
 
@@ -110,37 +116,40 @@ double MF::run() {
             foreach( const Neighbor &j, nbF(I) ) // for all j in I \ i
                 if( j != i )
                     henk *= _beliefs[j];
-            piet = factor(I).log0();
+            piet = factor(I).log(true);
             piet *= henk;
-            piet = piet.part_sum(var(i));
+            piet = piet.marginal(var(i), false);
             piet = piet.exp();
             jan *= piet; 
         }
 
-        jan.normalize( Prob::NORMPROB );
+        jan.normalize();
 
         if( jan.hasNaNs() ) {
-            cout << "MF::run():  ERROR: jan has NaNs!" << endl;
+            cout << Name << "::run():  ERROR: jan has NaNs!" << endl;
             return 1.0;
         }
 
+        if( props.damping != 0.0 )
+            jan = (jan^(1.0 - props.damping)) * (_beliefs[i]^props.damping);
         diffs.push( dist( jan, _beliefs[i], Prob::DISTLINF ) );
 
         _beliefs[i] = jan;
     }
 
-    if( diffs.maxDiff() > maxdiff )
-        maxdiff = diffs.maxDiff();
+    _iters = t / pass_size;
+    if( diffs.maxDiff() > _maxdiff )
+        _maxdiff = diffs.maxDiff();
 
     if( props.verbose >= 1 ) {
         if( diffs.maxDiff() > props.tol ) {
             if( props.verbose == 1 )
                 cout << endl;
-            cout << "MF::run:  WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+            cout << Name << "::run:  WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " seconds)...final maxdiff:" << diffs.maxDiff() << endl;
         } else {
             if( props.verbose >= 2 )
-                cout << "MF::run:  ";
-            cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " clocks)." << endl;
+                cout << Name << "::run:  ";
+            cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " seconds)." << endl;
         }
     }
 
@@ -148,10 +157,10 @@ double MF::run() {
 }
 
 
-Factor MF::beliefV (size_t i) const {
+Factor MF::beliefV( size_t i ) const {
     Factor piet;
     piet = _beliefs[i];
-    piet.normalize( Prob::NORMPROB );
+    piet.normalize();
     return(piet);
 }
 
@@ -188,9 +197,9 @@ Real MF::logZ() const {
         Factor henk;
         foreach( const Neighbor &j, nbF(I) )  // for all j in I
             henk *= _beliefs[j];
-        henk.normalize( Prob::NORMPROB );
+        henk.normalize();
         Factor piet;
-        piet = factor(I).log0();
+        piet = factor(I).log(true);
         piet *= henk;
         sum -= piet.totalSum();
     }