Added some functionality to create various standard factors and renamed "Clamped...
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 10 Feb 2010 08:50:48 +0000 (09:50 +0100)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 10 Feb 2010 08:50:48 +0000 (09:50 +0100)
ChangeLog
Makefile
README
include/dai/cbp.h
include/dai/doc.h
include/dai/factor.h
src/factor.cpp [new file with mode: 0644]
utils/createfg.cpp

index 40129cf..0c058e6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* Added some functionality to create various standard factors to factor.cpp
+* Renamed "Clamped BP" into "Conditioned BP"
 * Improved documentation
 * Documented tests/testdai
 * Moved platform independent build options into Makefile.ALL
 * Improved documentation
 * Documented tests/testdai
 * Moved platform independent build options into Makefile.ALL
index b592e2c..c26f14a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -168,6 +168,9 @@ lc$(OE) : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)
 mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
        $(CC) -c $(SRC)/mf.cpp
 
 mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
        $(CC) -c $(SRC)/mf.cpp
 
+factor$(OE) : $(SRC)/factor.cpp $(INC)/factor.h $(HEADERS)
+       $(CC) -c $(SRC)/factor.cpp
+
 factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
        $(CC) -c $(SRC)/factorgraph.cpp
 
 factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
        $(CC) -c $(SRC)/factorgraph.cpp
 
@@ -286,14 +289,16 @@ utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
 # LIBRARY
 ##########
 
 # LIBRARY
 ##########
 
+OBJECTS:=bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factor$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS) 
+
 ifneq ($(OS),WINDOWS)
 ifneq ($(OS),WINDOWS)
-$(LIB)/libdai$(LE) : bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+$(LIB)/libdai$(LE) : $(OBJECTS)
        -mkdir -p lib
        -mkdir -p lib
-       ar rcus $(LIB)/libdai$(LE) bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+       ar rcus $(LIB)/libdai$(LE) $(OBJECTS)
 else
 else
-$(LIB)/libdai$(LE) : bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+$(LIB)/libdai$(LE) : $(OBJECTS)
        -mkdir lib
        -mkdir lib
-       lib /out:$(LIB)/libdai$(LE) bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+       lib /out:$(LIB)/libdai$(LE) $(OBJECTS)
 endif
 
 
 endif
 
 
diff --git a/README b/README
index 58403ae..7245cb8 100644 (file)
--- a/README
+++ b/README
@@ -80,7 +80,7 @@ Currently, libDAI supports the following (approximate) inference methods:
   * Double-loop GBP [HAK03];
   * Various variants of Loop Corrected Belief Propagation [MoK07, MoR05];
   * Gibbs sampler;
   * Double-loop GBP [HAK03];
   * Various variants of Loop Corrected Belief Propagation [MoK07, MoR05];
   * Gibbs sampler;
-  * Clamped Belief Propagation [EaG09].
+  * Conditioned Belief Propagation [EaG09].
 
 These inference methods can be used to calculate partition sums, marginals over
 subsets of variables, and MAP states (the joint state of variables that has
 
 These inference methods can be used to calculate partition sums, marginals over
 subsets of variables, and MAP states (the joint state of variables that has
index 35bc771..57f9281 100644 (file)
@@ -9,7 +9,7 @@
 
 
 /// \file
 
 
 /// \file
-/// \brief Defines class CBP, which implements Clamped Belief Propagation
+/// \brief Defines class CBP, which implements Conditioned Belief Propagation
 
 
 #ifndef __defined_libdai_cbp_h
 
 
 #ifndef __defined_libdai_cbp_h
@@ -26,7 +26,7 @@
 namespace dai {
 
 
 namespace dai {
 
 
-/// Class for CBP (Clamped Belief Propagation) [\ref EaG09]
+/// Class for CBP (Conditioned Belief Propagation) [\ref EaG09]
 /** This approximate inference algorithm uses configurable heuristics to choose a variable
  *  \f$ x_i \f$ and a state \f$ x_i^* \f$. Inference is done with \f$ x_i \f$ "clamped" to \f$ x_i^* \f$
  *  (i.e., conditional on \f$ x_i = x_i^* \f$), and also with the negation of this condition. 
 /** This approximate inference algorithm uses configurable heuristics to choose a variable
  *  \f$ x_i \f$ and a state \f$ x_i^* \f$. Inference is done with \f$ x_i \f$ "clamped" to \f$ x_i^* \f$
  *  (i.e., conditional on \f$ x_i = x_i^* \f$), and also with the negation of this condition. 
index 254a0b8..7d6383a 100644 (file)
@@ -82,7 +82,7 @@
  *  - Various variants of Loop Corrected Belief Propagation
  *    [\ref MoK07, \ref MoR05];
  *  - Gibbs sampler;
  *  - Various variants of Loop Corrected Belief Propagation
  *    [\ref MoK07, \ref MoR05];
  *  - Gibbs sampler;
- *  - Clamped Belief Propagation [\ref EaG09].
+ *  - Conditioned Belief Propagation [\ref EaG09].
  *
  *  These inference methods can be used to calculate partition sums, marginals
  *  over subsets of variables, and MAP states (the joint state of variables that
  *
  *  These inference methods can be used to calculate partition sums, marginals
  *  over subsets of variables, and MAP states (the joint state of variables that
  *  - Double-loop GBP: dai::HAK [\ref HAK03]
  *  - Loop Corrected Belief Propagation: dai::MR [\ref MoR05] and dai::LC [\ref MoK07]
  *  - Gibbs sampling: dai::Gibbs
  *  - Double-loop GBP: dai::HAK [\ref HAK03]
  *  - Loop Corrected Belief Propagation: dai::MR [\ref MoR05] and dai::LC [\ref MoK07]
  *  - Gibbs sampling: dai::Gibbs
- *  - Clamped Belief Propagation: dai::CBP [\ref EaG09]
+ *  - Conditioned Belief Propagation: dai::CBP [\ref EaG09]
  *
  *  Not all inference tasks are implemented by each method: calculating MAP states
  *  is only possible with dai::JTree and dai::BP, calculating partition sums is
  *
  *  Not all inference tasks are implemented by each method: calculating MAP states
  *  is only possible with dai::JTree and dai::BP, calculating partition sums is
index 4602317..50cc961 100644 (file)
@@ -591,6 +591,45 @@ template<typename T> T MutualInfo(const TFactor<T> &f) {
 typedef TFactor<Real> Factor;
 
 
 typedef TFactor<Real> Factor;
 
 
+/// Returns a binary single-variable factor \f$ \exp(hx) \f$ where \f$ x = \pm 1 \f$
+/** \param x Variable (should be binary)
+ *  \param h Field strength
+ */
+Factor BinaryFactor( const Var &x, Real h );
+
+
+/// Returns a binary pairwise factor \f$ \exp(J x_1 x_2) \f$ where \f$ x_1, x_2 = \pm 1 \f$
+/** \param x1 First variable (should be binary)
+ *  \param x2 Second variable (should be binary)
+ *  \param J Coupling strength
+ */
+Factor BinaryFactor( const Var &x1, const Var &x2, Real J );
+
+
+/// Returns a random factor on the variables \a vs with strength \a beta
+/** Each entry are set by drawing a normally distributed random with mean
+ *  0 and standard-deviation \a beta, and taking its exponent.
+ *  \param vs Variables
+ *  \param beta Factor strength (inverse temperature)
+ */
+Factor RandomFactor( const VarSet &vs, Real beta );
+
+
+/// Returns a pairwise Potts factor \f$ \exp( J \delta_{x_1, x_2} ) \f$
+/** \param x1 First variable
+ *  \param x2 Second variable (should have the same number of states as \a x1)
+ *  \param J  Factor strength
+ */
+Factor PottsFactor( const Var &x1, const Var &x2, Real J );
+
+
+/// Returns a Kronecker delta point mass
+/** \param v Variable
+ *  \param state The state of \a v that should get value 1
+ */
+Factor DeltaFactor( const Var &v, size_t state );
+
+
 } // end of namespace dai
 
 
 } // end of namespace dai
 
 
diff --git a/src/factor.cpp b/src/factor.cpp
new file mode 100644 (file)
index 0000000..b4f69de
--- /dev/null
@@ -0,0 +1,66 @@
+/*  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-2010  Joris Mooij  [joris dot mooij at libdai dot org]
+ *  Copyright (C) 2006-2007  Radboud University Nijmegen, The Netherlands
+ */
+
+
+#include <dai/factor.h>
+
+
+namespace dai {
+
+
+using namespace std;
+
+
+Factor BinaryFactor( const Var &n, Real h ) {
+    DAI_ASSERT( n.states() == 2 );
+    Real buf[2];
+    buf[0] = std::exp(-h);
+    buf[1] = std::exp(h);
+    return Factor(n, &buf[0]);
+}
+
+
+Factor BinaryFactor( const Var &n1, const Var &n2, Real J ) {
+    DAI_ASSERT( n1.states() == 2 );
+    DAI_ASSERT( n2.states() == 2 );
+    DAI_ASSERT( n1 != n2 );
+    Real buf[4];
+    buf[0] = (buf[3] = std::exp(J));
+    buf[1] = (buf[2] = std::exp(-J));
+    return Factor( VarSet(n1, n2), &buf[0] );
+}
+
+
+Factor RandomFactor( const VarSet &ns, Real beta ) {
+    Factor fac( ns );
+    for( size_t t = 0; t < fac.states(); t++ )
+        fac[t] = std::exp(rnd_stdnormal() * beta);
+    return fac;
+}
+
+
+Factor PottsFactor( const Var &n1, const Var &n2, Real J ) {
+    Factor fac( VarSet( n1, n2 ), 1.0 );
+    DAI_ASSERT( n1.states() == n2.states() );
+    for( size_t s = 0; s < n1.states(); s++ )
+        fac[ s * (n1.states() + 1) ] = std::exp(J);
+    return fac;
+}
+
+
+Factor DeltaFactor( const Var &v, size_t state ) {
+    Factor fac( v, 0.0 );
+    DAI_ASSERT( state < v.states() );
+    fac[state] = 1.0;
+    return fac;
+}
+
+
+} // end of namespace dai
index 627b978..9dfd1ca 100644 (file)
@@ -30,40 +30,35 @@ typedef matrix::value_array_type::const_iterator matrix_vcit;
 typedef matrix::index_array_type::const_iterator matrix_icit;
 
 
 typedef matrix::index_array_type::const_iterator matrix_icit;
 
 
-Factor BinaryFactor( const Var &n, Real field ) {
-    DAI_ASSERT( n.states() == 2 );
-    Real buf[2];
-    buf[0] = std::exp(-field);
-    buf[1] = std::exp(field);
-    return Factor(n, &buf[0]);
-}
-
-
-Factor BinaryFactor( const Var &n1, const Var &n2, Real coupling ) {
-    DAI_ASSERT( n1.states() == 2 );
-    DAI_ASSERT( n2.states() == 2 );
-    DAI_ASSERT( n1 != n2 );
-    Real buf[4];
-    buf[0] = (buf[3] = std::exp(coupling));
-    buf[1] = (buf[2] = std::exp(-coupling));
-    return Factor( VarSet(n1, n2), &buf[0] );
-}
+// w should be upper triangular or lower triangular
+void WTh2FG( const matrix &w, const vector<Real> &th, FactorGraph &fg ) {
+    vector<Var>    vars;
+    vector<Factor> factors;
 
 
+    size_t N = th.size();
+    DAI_ASSERT( (w.size1() == N) && (w.size2() == N) );
 
 
-Factor RandomFactor( const VarSet &ns, Real beta ) {
-    Factor fac( ns );
-    for( size_t t = 0; t < fac.states(); t++ )
-        fac[t] = std::exp(rnd_stdnormal() * beta);
-    return fac;
-}
+    vars.reserve(N);
+    for( size_t i = 0; i < N; i++ )
+        vars.push_back(Var(i,2));
 
 
+    factors.reserve( w.nnz() + N );
+    // walk through the sparse array structure
+    // this is similar to matlab sparse arrays
+    // index2 gives the column index (similar to ir in matlab)
+    // index1 gives the starting indices for each row (similar to jc in matlab)
+    size_t i = 0;
+    for( size_t pos = 0; pos < w.nnz(); pos++ ) {
+        while( pos == w.index1_data()[i+1] )
+            i++;
+        size_t j = w.index2_data()[pos];
+        Real w_ij = w.value_data()[pos];
+        factors.push_back( BinaryFactor( vars[i], vars[j], w_ij ) );
+    }
+    for( size_t i = 0; i < N; i++ )
+        factors.push_back( BinaryFactor( vars[i], th[i] ) );
 
 
-Factor PottsFactor( const Var &n1, const Var &n2, Real beta ) {
-    Factor fac( VarSet( n1, n2 ), 1.0 );
-    DAI_ASSERT( n1.states() == n2.states() );
-    for( size_t s = 0; s < n1.states(); s++ )
-        fac[ s * (n1.states() + 1) ] = std::exp(beta);
-    return fac;
+    fg = FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() );
 }
 
 
 }
 
 
@@ -94,38 +89,6 @@ void MakeHOIFG( size_t N, size_t M, size_t k, Real sigma, FactorGraph &fg ) {
 }
 
 
 }
 
 
-// w should be upper triangular or lower triangular
-void WTh2FG( const matrix &w, const vector<Real> &th, FactorGraph &fg ) {
-    vector<Var>    vars;
-    vector<Factor> factors;
-
-    size_t N = th.size();
-    DAI_ASSERT( (w.size1() == N) && (w.size2() == N) );
-
-    vars.reserve(N);
-    for( size_t i = 0; i < N; i++ )
-        vars.push_back(Var(i,2));
-
-    factors.reserve( w.nnz() + N );
-    // walk through the sparse array structure
-    // this is similar to matlab sparse arrays
-    // index2 gives the column index (similar to ir in matlab)
-    // index1 gives the starting indices for each row (similar to jc in matlab)
-    size_t i = 0;
-    for( size_t pos = 0; pos < w.nnz(); pos++ ) {
-        while( pos == w.index1_data()[i+1] )
-            i++;
-        size_t j = w.index2_data()[pos];
-        Real w_ij = w.value_data()[pos];
-        factors.push_back( BinaryFactor( vars[i], vars[j], w_ij ) );
-    }
-    for( size_t i = 0; i < N; i++ )
-        factors.push_back( BinaryFactor( vars[i], th[i] ) );
-
-    fg = FactorGraph( factors.begin(), factors.end(), vars.begin(), vars.end(), factors.size(), vars.size() );
-}
-
-
 void MakeFullFG( size_t N, Real mean_w, Real mean_th, Real sigma_w, Real sigma_th, FactorGraph &fg ) {
     matrix w(N,N,N*(N-1)/2);
     vector<Real> th(N,0.0);
 void MakeFullFG( size_t N, Real mean_w, Real mean_th, Real sigma_w, Real sigma_th, FactorGraph &fg ) {
     matrix w(N,N,N*(N-1)/2);
     vector<Real> th(N,0.0);