Replaced VarSet::calcState(),VarSet::calcStates() by non-members calcLinearState...
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 16 Nov 2009 12:14:56 +0000 (13:14 +0100)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 16 Nov 2009 12:14:56 +0000 (13:14 +0100)
ChangeLog
Makefile
OBSOLETE
README
TODO
examples/example_varset.cpp
include/dai/factor.h
include/dai/index.h
include/dai/varset.h
src/varset.cpp [new file with mode: 0644]

index 24b2d5a..83486bd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+* Replaced VarSet::calcState() by non-member calcLinearState()
+* Replaced VarSet::calcStates() by non-member calcState()
 * README is now created automatically from doxygen documentation
 * Makefile macros DAI_VERSION and DAI_DATE have been introduced,
   in order to store this information in a central place
index da640c0..2d3de41 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -120,6 +120,9 @@ lib: $(LIB)/libdai$(LE)
 bipgraph$(OE) : $(SRC)/bipgraph.cpp $(HEADERS)
        $(CC) -c $(SRC)/bipgraph.cpp
 
+varset$(OE) : $(SRC/varset.cpp $(HEADERS)
+       $(CC) -c $(SRC)/varset.cpp
+
 daialg$(OE) : $(SRC)/daialg.cpp $(HEADERS)
        $(CC) -c $(SRC)/daialg.cpp
 
@@ -257,13 +260,13 @@ utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
 ##########
 
 ifneq ($(OS),WINDOWS)
-$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+$(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)
        -mkdir -p lib
-       ar rcus $(LIB)/libdai$(LE) bipgraph$(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) bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
 else
-$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+$(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)
        -mkdir lib
-       lib /out:$(LIB)/libdai$(LE) bipgraph$(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) bipgraph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
 endif
 
 
index 0e52ff3..4cf4603 100644 (file)
--- a/OBSOLETE
+++ b/OBSOLETE
@@ -33,3 +33,5 @@ typedef UEdgeVec;
 typedef DEdgeVec;
 DEdgeVec GrowRootedTree( const Graph &T, size_t Root );
 const Factor& LC::belief(size_t);
+size_t VarSet::calcState( const std::map<Var, size_t> &state ) const;
+std::map<Var, size_t> VarSet::calcStates( size_t linearState ) const;
diff --git a/README b/README
index 1698c6f..70c3154 100644 (file)
--- a/README
+++ b/README
@@ -2,8 +2,8 @@ libDAI  -  A free/open source C++ library for Discrete Approximate Inference
 
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 
-Version:  git commit b088d4b1057d9105210d3f04c7ca66c21423158b
-Date:     Sun Nov 15 19:10:39 2009 +0100
+Version:  git commit 44d777200a6977fd8d8e40b0356cfe29bf830ae5
+Date:     Mon Nov 16 12:42:06 2009 +0100
 See also: http://www.libdai.org
 
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
diff --git a/TODO b/TODO
index 2b09913..062ee73 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
 To do for the next release (0.2.3):
 
-- Rename VarSet::calcState(), VarSet::calcStates() and make them non-member functions.
 - Update ChangeLog
 
 Finally:
index d272b0c..84e7b26 100644 (file)
@@ -40,23 +40,23 @@ int main() {
             states[x1] = s1;
 
             // output states of x0, x1 and corresponding state of X
-            cout << "    " << s0 << "              " << s1 << "              " << X.calcState(states) << endl;
+            cout << "    " << s0 << "              " << s1 << "              " << calcLinearState(X,states) << endl;
 
-            // VarSet::calcStates is the inverse of VarSet::calcState
-            DAI_ASSERT( X.calcStates(X.calcState(states)) == states );
+            // calcState() is the inverse of calcLinearState()
+            DAI_ASSERT( calcState(X, calcLinearState(X, states)) == states );
         }
 
     cout << endl << "And vice versa:" << endl;
     cout << "  state of x0:   state of x1:   (linear) state of X:" << endl;
     for( size_t S = 0; S < X.nrStates(); S++ ) { // for all (joint) states of X
         // calculate states of x0 and x1 corresponding to state S of X
-        map<Var,size_t> states = X.calcStates(S);
+        map<Var,size_t> states = calcState(X,S);
 
         // output state of X and corresponding states of x0, x1
         cout << "    " << states[x0] << "              " << states[x1] << "              " << S << endl;
 
-        // VarSet::calcState is the inverse of VarSet::calcStates
-        DAI_ASSERT( X.calcState(X.calcStates(S)) == S );
+        // calcLinearState() is the inverse of calcState()
+        DAI_ASSERT( calcLinearState(X, calcState(X,S)) == S );
     }
 
     cout << endl << "Iterating over all joint states using the State class:" << endl;
index b976b22..a3fe3ac 100644 (file)
@@ -49,7 +49,7 @@ namespace dai {
  *  ordering, which is defined by the one-to-one correspondence of a joint state
  *  in \f$\prod_{l\in L} X_l\f$ with a linear index in
  *  \f$\{0,1,\dots,\prod_{l\in L} S_l-1\}\f$ according to the mapping \f$\sigma\f$
- *  induced by VarSet::calcState(const std::map<Var,size_t> &).
+ *  induced by dai::calcLinearState().
  *
  *  \tparam T Should be a scalar that is castable from and to double and should support elementary arithmetic operations.
  *  \todo Define a better fileformat for .fg files (maybe using XML)?
index 2569e54..cf5d1c4 100644 (file)
@@ -36,8 +36,8 @@ namespace dai {
  *      IndexFor i( indexVars, forVars );
  *      size_t iter = 0;
  *      for( ; i.valid(); i++, iter++ ) {
- *          cout << "State of forVars: " << forVars.calcStates( iter ) << "; ";
- *          cout << "state of indexVars: " << indexVars.calcStates( long(i) ) << endl;
+ *          cout << "State of forVars: " << calcState( forVars, iter ) << "; ";
+ *          cout << "state of indexVars: " << calcState( indexVars, long(i) ) << endl;
  *      }
  *  \endcode
  *  loops over all joint states of the variables in \a forVars,
@@ -320,12 +320,12 @@ class multifor {
  *  }
  *  \endcode
  *
- *  \note The same functionality could be achieved by simply iterating over the linear state and using VarSet::calcStates,
+ *  \note The same functionality could be achieved by simply iterating over the linear state and using dai::calcState(),
  *  but the State class offers a more efficient implementation.
  *
  *  \note A State is very similar to a \link multifor \endlink, but tailored for Var 's and VarSet 's.
  *
- *  \see VarSet::calcState(), VarSet::calcStates()
+ *  \see dai::calcLinearState(), dai::calcState()
  *
  *  \idea Make the State class a more prominent part of libDAI 
  *  (and document it clearly, explaining the concept of state); 
index b4a9b93..3f1a8d3 100644 (file)
 namespace dai {
 
 
+// Predefine for definitions of calcLinearState() and calcState()
+class VarSet;
+
+
+/// Calculates the linear index in the Cartesian product of the variables in \a vs that corresponds to a particular joint assignment of the variables, specified by \a state.
+/** \param vs Set of variables for which the linear state should be calculated;
+ *  \param state Specifies the states of some variables.
+ *  \return The linear index in the Cartesian product of the variables in \a vs
+ *  corresponding with the joint assignment specified by \a state, where variables
+ *  for which no state is specified are assumed to be in state 0.
+ *
+ *  The linear index is calculated as follows. The variables in \a vs are
+ *  ordered according to their label (in ascending order); say \a vs corresponds with
+ *  the set \f$\{x_{l(0)},x_{l(1)},\dots,x_{l(n-1)}\}\f$ with \f$l(0) < l(1) < \dots < l(n-1)\f$,
+ *  where variable \f$x_l\f$ has label \a l. Denote by \f$S_l\f$ the number of possible values
+ *  ("states") of variable \f$x_l\f$. The argument \a state corresponds
+ *  with a mapping \a s that assigns to each variable \f$x_l\f$ a state \f$s(x_l) \in \{0,1,\dots,S_l-1\}\f$,
+ *  where \f$s(x_l)=0\f$ if \f$x_l\f$ is not specified in \a state. The linear index \f$S\f$ corresponding
+ *  with \a state is now calculated by:
+ *  \f{eqnarray*}
+ *    S &:=& \sum_{i=0}^{n-1} s(x_{l(i)}) \prod_{j=0}^{i-1} S_{l(j)} \\
+ *      &= & s(x_{l(0)}) + s(x_{l(1)}) S_{l(0)} + s(x_{l(2)}) S_{l(0)} S_{l(1)} + \dots + s(x_{l(n-1)}) S_{l(0)} \cdots S_{l(n-2)}.
+ *  \f}
+ *
+ *  \note If \a vs corresponds with \f$\{x_l\}_{l\in L}\f$, and \a state specifies a state
+ *  for each variable \f$x_l\f$ for \f$l\in L\f$, calcLinearState() induces a mapping
+ *  \f$\sigma : \prod_{l\in L} X_l \to \{0,1,\dots,\prod_{l\in L} S_l-1\}\f$ that
+ *  maps a joint state to a linear index; this is the inverse of the mapping
+ *  \f$\sigma^{-1}\f$ induced by calcState().
+ *
+ *  \see calcState()
+ */
+size_t calcLinearState( const VarSet &vs, const std::map<Var, size_t> &state );
+
+
+/// Calculates the joint assignment of the variables in \a vs corresponding to the linear index \a linearState.
+/** \param vs Set of variables to which \a linearState refers
+ *  \param linearState should be smaller than vs.nrStates().
+ *  \return A mapping \f$s\f$ that maps each Var \f$x_l\f$ in \a vs to its state \f$s(x_l)\f$, as specified by \a linearState.
+ *
+ *  The variables in \a vs are ordered according to their label (in ascending order); say \a vs corresponds with
+ *  the set \f$\{x_{l(0)},x_{l(1)},\dots,x_{l(n-1)}\}\f$ with \f$l(0) < l(1) < \dots < l(n-1)\f$,
+ *  where variable \f$x_l\f$ has label \a l. Denote by \f$S_l\f$ the number of possible values
+ *  ("states") of variable \f$x_l\f$ with label \a l.
+ *  The mapping \f$s\f$ returned by this function is defined as:
+ *  \f{eqnarray*}
+ *    s(x_{l(i)}) = \left\lfloor\frac{S \mbox { mod } \prod_{j=0}^{i} S_{l(j)}}{\prod_{j=0}^{i-1} S_{l(j)}}\right\rfloor \qquad \mbox{for all $i=0,\dots,n-1$}.
+ *  \f}
+ *  where \f$S\f$ denotes the value of \a linearState.
+ *
+ *  \note If \a vs corresponds with \f$\{x_l\}_{l\in L}\f$, calcState() induces a mapping
+ *  \f$\sigma^{-1} : \{0,1,\dots,\prod_{l\in L} S_l-1\} \to \prod_{l\in L} X_l\f$ that
+ *  maps a linear index to a joint state; this is the inverse of the mapping \f$\sigma\f$
+ *  induced by calcLinearState().
+ *
+ *  \see calcLinearState()
+ */
+std::map<Var, size_t> calcState( const VarSet &vs, size_t linearState );
+
+
 /// Represents a set of variables.
 /** \note A VarSet is implemented using a SmallSet<Var> instead
  *  of the more natural std::set<Var> because of efficiency reasons.
- *  That is, internally, the variables in the set are sorted according
- *  to their labels: the set of variables \f$\{x_l\}_{l\in L}\f$ is
- *  represented as a vector \f$(x_{l(0)},x_{l(1)},\dots,x_{l(|L|-1)})\f$
- *  where \f$l(0) < l(1) < \dots < l(|L|-1)\f$
- *  and \f$L = \{l(0),l(1),\dots,l(|L|-1)\}\f$.
+ *  That is, internally, the variables in the set are sorted ascendingly
+ *  according to their labels.
  */
 class VarSet : public SmallSet<Var> {
     public:
@@ -81,71 +138,15 @@ class VarSet : public SmallSet<Var> {
             return states;
         }
 
-        /// Calculates the linear index in the Cartesian product of the variables in \c *this that corresponds to a particular joint assignment of the variables, specified by \a states.
-        /** \param states Specifies the states of some variables.
-         *  \return The linear index in the Cartesian product of the variables in \c *this
-         *  corresponding with the joint assignment specified by \a states, where variables
-         *  for which no state is specified are assumed to be in state 0.
-         *
-         *  The linear index is calculated as follows. The variables in \c *this are
-         *  ordered according to their label (in ascending order); say \c *this corresponds with
-         *  the set \f$\{x_{l(0)},x_{l(1)},\dots,x_{l(n-1)}\}\f$ with \f$l(0) < l(1) < \dots < l(n-1)\f$,
-         *  where variable \f$x_l\f$ has label \a l. Denote by \f$S_l\f$ the number of possible values
-         *  ("states") of variable \f$x_l\f$. The argument \a states corresponds
-         *  with a mapping \a s that assigns to each variable \f$x_l\f$ a state \f$s(x_l) \in \{0,1,\dots,S_l-1\}\f$,
-         *  where \f$s(x_l)=0\f$ if \f$x_l\f$ is not specified in \a states. The linear index \f$S\f$ corresponding
-         *  with \a states is now calculated by:
-         *  \f{eqnarray*}
-         *    S &:=& \sum_{i=0}^{n-1} s(x_{l(i)}) \prod_{j=0}^{i-1} S_{l(j)} \\
-         *      &= & s(x_{l(0)}) + s(x_{l(1)}) S_{l(0)} + s(x_{l(2)}) S_{l(0)} S_{l(1)} + \dots + s(x_{l(n-1)}) S_{l(0)} \cdots S_{l(n-2)}.
-         *  \f}
-         *
-         *  \note If \c *this corresponds with \f$\{x_l\}_{l\in L}\f$, and \a states specifies a state
-         *  for each variable \f$x_l\f$ for \f$l\in L\f$, calcState() induces a mapping
-         *  \f$\sigma : \prod_{l\in L} X_l \to \{0,1,\dots,\prod_{l\in L} S_l-1\}\f$ that
-         *  maps a joint state to a linear index; this is the inverse of the mapping
-         *  \f$\sigma^{-1}\f$ induced by calcStates().
+        /// Calculates the linear index in the Cartesian product of the variables in \c *this that corresponds to a particular joint assignment of the variables, specified by \a state.
+        /** \deprecated Please use dai::calcLinearState() instead
          */
-        size_t calcState( const std::map<Var, size_t> &states ) const {
-            size_t prod = 1;
-            size_t state = 0;
-            for( VarSet::const_iterator n = begin(); n != end(); n++ ) {
-                std::map<Var, size_t>::const_iterator m = states.find( *n );
-                if( m != states.end() )
-                    state += prod * m->second;
-                prod *= n->states();
-            }
-            return state;
-        }
+        size_t calcState( const std::map<Var, size_t> &state ) const { return dai::calcLinearState( *this, state ); }
 
         /// Calculates the joint assignment of the variables in \c *this corresponding to the linear index \a linearState.
-        /** \param linearState should be smaller than nrStates().
-         *  \return A mapping \f$s\f$ that maps each Var \f$x_l\f$ in \c *this to its state \f$s(x_l)\f$, as specified by \a linearState.
-         *
-         *  The variables in \c *this are ordered according to their label (in ascending order); say \c *this corresponds with
-         *  the set \f$\{x_{l(0)},x_{l(1)},\dots,x_{l(n-1)}\}\f$ with \f$l(0) < l(1) < \dots < l(n-1)\f$,
-         *  where variable \f$x_l\f$ has label \a l. Denote by \f$S_l\f$ the number of possible values
-         *  ("states") of variable \f$x_l\f$ with label \a l.
-         *  The mapping \f$s\f$ returned by this function is defined as:
-         *  \f{eqnarray*}
-         *    s(x_{l(i)}) = \left\lfloor\frac{S \mbox { mod } \prod_{j=0}^{i} S_{l(j)}}{\prod_{j=0}^{i-1} S_{l(j)}}\right\rfloor \qquad \mbox{for all $i=0,\dots,n-1$}.
-         *  \f}
-         *  where \f$S\f$ denotes the value of \a linearState.
-         *
-         *  \note If \c *this corresponds with \f$\{x_l\}_{l\in L}\f$, calcStates() induces a mapping
-         *  \f$\sigma^{-1} : \{0,1,\dots,\prod_{l\in L} S_l-1\} \to \prod_{l\in L} X_l\f$ that
-         *  maps a linear index to a joint state; this is the inverse of the mapping \f$\sigma\f$
-         *  induced by calcState().
+        /** \deprecated Please use dai::calcState() instead
          */
-        std::map<Var, size_t> calcStates( size_t linearState ) const {
-            std::map<Var, size_t> states;
-            for( VarSet::const_iterator n = begin(); n != end(); n++ ) {
-                states[*n] = linearState % n->states();
-                linearState /= n->states();
-            }
-            DAI_ASSERT( linearState == 0 );
-            return states;
-        }
+        std::map<Var, size_t> calcStates( size_t linearState ) const { return dai::calcState( *this, linearState ); }
     //@}
 
     /// \name Input and output
diff --git a/src/varset.cpp b/src/varset.cpp
new file mode 100644 (file)
index 0000000..9619384
--- /dev/null
@@ -0,0 +1,45 @@
+/*  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) 2002-2007  Radboud University Nijmegen, The Netherlands
+ */
+
+
+#include <dai/varset.h>
+
+
+namespace dai {
+
+
+using namespace std;
+
+
+size_t calcLinearState( const VarSet &vs, const std::map<Var, size_t> &state ) {
+    size_t prod = 1;
+    size_t st = 0;
+    for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) {
+        std::map<Var, size_t>::const_iterator m = state.find( *v );
+        if( m != state.end() )
+            st += prod * m->second;
+        prod *= v->states();
+    }
+    return st;
+}
+
+
+std::map<Var, size_t> calcState( const VarSet &vs, size_t linearState ) {
+    std::map<Var, size_t> state;
+    for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) {
+        state[*v] = linearState % v->states();
+        linearState /= v->states();
+    }
+    DAI_ASSERT( linearState == 0 );
+    return state;
+}
+
+
+} // end of namespace dai