Implemented workaround for bug in State() class found by Jerome Maye
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 18 May 2011 09:33:08 +0000 (11:33 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 18 May 2011 09:33:08 +0000 (11:33 +0200)
ChangeLog
examples/example.cpp [changed from file to symlink]
include/dai/index.h

index ce5a257..4d7cc14 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* Jerome Maye found a bug in the State() class in index.h; implemented
+  a workaround for the moment
 * Fixed bug in findMaximum(): inconsistent max-beliefs are now detected,
   instead of returning a MAP state with zero joint probability
   (reported by Hynek Urban)
deleted file mode 100644 (file)
index ac6efd0a973ee61006b27fb5f2be10a7a5da4cac..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*  This file is part of libDAI - http://www.libdai.org/
- *
- *  libDAI is licensed under the terms of the GNU General Public License version
- *  2, or (at your option) any later version. libDAI is distributed without any
- *  warranty. See the file COPYING for more details.
- *
- *  Copyright (C) 2006-2009  Joris Mooij  [joris dot mooij at libdai dot org]
- *  Copyright (C) 2006-2007  Radboud University Nijmegen, The Netherlands
- */
-
-
-#include <iostream>
-#include <map>
-#include <dai/alldai.h>  // Include main libDAI header file
-#include <dai/jtree.h>
-#include <dai/bp.h>
-#include <dai/decmap.h>
-
-
-using namespace dai;
-using namespace std;
-
-
-int main( int argc, char *argv[] ) {
-    if ( argc != 2 ) {
-        cout << "Usage: " << argv[0] << " <filename.fg>" << endl << endl;
-        cout << "Reads factor graph <filename.fg> and runs" << endl;
-        cout << "Belief Propagation and JunctionTree on it." << endl << endl;
-        return 1;
-    } else {
-        // 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)
-
-        // Construct a JTree (junction tree) object from the FactorGraph fg
-        // using the parameters specified by opts and an additional property
-        // that specifies the type of updates the JTree algorithm should perform
-        JTree jt( fg, opts("updates",string("HUGIN")) );
-        // Initialize junction tree algorithm
-        jt.init();
-        // Run junction tree algorithm
-        jt.run();
-
-        // 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();
-
-        // 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("SEQRND"))("logdomain",false));
-        // Initialize belief propagation algorithm
-        bp.init();
-        // Run belief propagation algorithm
-        bp.run();
-
-        // 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
-        //
-        // Note that inference is set to MAXPROD, which means that the object
-        // will perform the max-product algorithm instead of the sum-product algorithm
-        BP mp(fg, opts("updates",string("SEQRND"))("logdomain",false)("inference",string("MAXPROD"))("damping",string("0.1")));
-        // Initialize max-product algorithm
-        mp.init();
-        // Run max-product algorithm
-        mp.run();
-        // Calculate joint state of all variables that has maximum probability
-        // based on the max-product result
-        vector<size_t> mpstate = mp.findMaximum();
-
-        // Construct a decimation algorithm object from the FactorGraph fg
-        // using the parameters specified by opts and three additional properties,
-        // specifying that the decimation algorithm should use the max-product
-        // algorithm and should completely reinitalize its state at every step
-        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();
-
-        // Report variable marginals for fg, calculated by the junction tree algorithm
-        cout << "Exact variable marginals:" << endl;
-        for( size_t i = 0; i < fg.nrVars(); i++ ) // iterate over all variables in fg
-            cout << jt.belief(fg.var(i)) << endl; // display the "belief" of jt for that variable
-
-        // Report variable marginals for fg, calculated by the belief propagation algorithm
-        cout << "Approximate (loopy belief propagation) variable marginals:" << 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
-
-        // Report factor marginals for fg, calculated by the junction tree algorithm
-        cout << "Exact factor marginals:" << endl;
-        for( size_t I = 0; I < fg.nrFactors(); I++ ) // iterate over all factors in fg
-            cout << jt.belief(fg.factor(I).vars()) << endl;  // display the "belief" of jt for the variables in that factor
-
-        // Report factor marginals for fg, calculated by the belief propagation algorithm
-        cout << "Approximate (loopy belief propagation) factor marginals:" << endl;
-        for( size_t I = 0; I < fg.nrFactors(); I++ ) // iterate over all factors in fg
-            cout << bp.belief(fg.factor(I).vars()) << endl; // display the belief of bp for the variables in that factor
-
-        // Report log partition sum (normalizing constant) of fg, calculated by the junction tree algorithm
-        cout << "Exact log partition sum: " << jt.logZ() << endl;
-
-        // Report log partition sum of fg, approximated by the belief propagation algorithm
-        cout << "Approximate (loopy belief propagation) log partition sum: " << bp.logZ() << endl;
-
-        // 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 max-product variable marginals
-        cout << "Approximate (max-product) MAP variable marginals:" << endl;
-        for( size_t i = 0; i < fg.nrVars(); i++ )
-            cout << mp.belief(fg.var(i)) << endl;
-
-        // Report exact MAP factor marginals
-        cout << "Exact MAP factor marginals:" << endl;
-        for( size_t I = 0; I < fg.nrFactors(); I++ )
-            cout << jtmap.belief(fg.factor(I).vars()) << " == " << jtmap.beliefF(I) << endl;
-
-        // Report max-product factor marginals
-        cout << "Approximate (max-product) MAP factor marginals:" << endl;
-        for( size_t I = 0; I < fg.nrFactors(); I++ )
-            cout << mp.belief(fg.factor(I).vars()) << " == " << mp.beliefF(I) << endl;
-
-        // Report exact MAP joint state
-        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;
-
-        // Report max-product MAP joint state
-        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;
-
-        // Report DecMAP joint state
-        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;
-}
new file mode 120000 (symlink)
index 0000000000000000000000000000000000000000..74fce9bb274aa978756e427406d8323b8e0e6012
--- /dev/null
@@ -0,0 +1 @@
+/tmp/testFG.cpp
\ No newline at end of file
index e301b24..78bd390 100644 (file)
@@ -354,6 +354,11 @@ class multifor {
  *  (and document it clearly, explaining the concept of state); 
  *  add more optimized variants of the State class like IndexFor 
  *  (e.g. for TFactor<>::slice()).
+ *
+ *  \todo The State class is dangerous because currently it represents a state both as
+ *  an integer and as a map<Var, size_t>; if the cardinality of the joint state space
+ *  becomes too large, the state no longer fits into an integer, and the two representations
+ *  are no longer consistent... this should be fixed!
  */
 class State {
     private:
@@ -423,7 +428,6 @@ class State {
 
         /// Return current state of variable \a v, or 0 if \a v is not in \c *this
         size_t operator() ( const Var &v ) const {
-            DAI_ASSERT( valid() );
             states_type::const_iterator entry = states.find( v );
             if( entry == states.end() )
                 return 0;
@@ -433,7 +437,6 @@ class State {
 
         /// Return linear state of variables in \a vs, assuming that variables that are not in \c *this are in state 0
         size_t operator() ( const VarSet &vs ) const {
-            DAI_ASSERT( valid() );
             size_t vs_state = 0;
             size_t prod = 1;
             for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) {