Documented all exceptions and did some general cleanups
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Thu, 12 Nov 2009 09:52:51 +0000 (10:52 +0100)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Thu, 12 Nov 2009 09:52:51 +0000 (10:52 +0100)
23 files changed:
TODO
doxygen.conf
include/dai/alldai.h
include/dai/bbp.h
include/dai/bipgraph.h
include/dai/cbp.h
include/dai/clustergraph.h
include/dai/daialg.h
include/dai/doc.h
include/dai/emalg.h
include/dai/evidence.h
include/dai/exceptions.h
include/dai/factorgraph.h
include/dai/jtree.h
include/dai/mr.h
include/dai/prob.h
include/dai/properties.h
include/dai/regiongraph.h
include/dai/treeep.h
scripts/regenerate-properties
src/emalg.cpp
src/factorgraph.cpp
src/treeep.cpp

diff --git a/TODO b/TODO
index 516ca72..f7b87e6 100644 (file)
--- a/TODO
+++ b/TODO
@@ -6,8 +6,6 @@ Improve documentation:
 
 Improve documentation of all .props structs.
 
-Improve documentation of inference algorithm constructors (indicate constraints on factor graph)
-
 Write a concept/notations page for the documentation,
 explaining the concepts of "state" (index into a 
 multi-dimensional array, e.g., one corresponding
index 4514775..7bbf0d0 100644 (file)
@@ -92,7 +92,7 @@ ABBREVIATE_BRIEF       =
 # Doxygen will generate a detailed section even if there is only a brief 
 # description.
 
-ALWAYS_DETAILED_SEC    = NO
+ALWAYS_DETAILED_SEC    = YES
 
 # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
 # inherited members of a class in the documentation of that class as if those 
@@ -170,7 +170,7 @@ SEPARATE_MEMBER_PAGES  = NO
 # The TAB_SIZE tag can be used to set the number of spaces in a tab. 
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
-TAB_SIZE               = 8
+TAB_SIZE               = 4
 
 # This tag can be used to specify a number of aliases that acts 
 # as commands in the documentation. An alias has the form "name=value". 
@@ -302,7 +302,7 @@ EXTRACT_ALL            = NO
 # If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
 # will be included in the documentation.
 
-EXTRACT_PRIVATE        = NO
+EXTRACT_PRIVATE        = YES
 
 # If the EXTRACT_STATIC tag is set to YES all static members of a file 
 # will be included in the documentation.
@@ -343,7 +343,7 @@ HIDE_UNDOC_MEMBERS     = NO
 # If set to NO (the default) these classes will be included in the various 
 # overviews. This option has no effect if EXTRACT_ALL is enabled.
 
-HIDE_UNDOC_CLASSES     = NO
+HIDE_UNDOC_CLASSES     = YES
 
 # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
 # friend (class|struct|union) declarations. 
@@ -1257,15 +1257,14 @@ PREDEFINED             = DAI_WITH_BP \
                          DAI_WITH_JTREE \
                          DAI_WITH_MR \
                          DAI_WITH_CBP \
-                         DAI_DEBUG \
-                         DAI_DEBASSERT
+                         DAI_DEBUG
 
 # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
 # this tag can be used to specify a list of macro names that should be expanded. 
 # The macro definition that is found in the sources will be used. 
 # Use the PREDEFINED tag if you want to use a different macro definition.
 
-EXPAND_AS_DEFINED      = DAI_ENUM
+EXPAND_AS_DEFINED      =
 
 # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
 # doxygen's preprocessor will remove all function-like macros that are alone 
index 1998a24..ca96326 100644 (file)
@@ -61,6 +61,7 @@ namespace dai {
  *  \param fg The FactorGraph that the algorithm should be applied to.
  *  \param opts A PropertySet specifying the options for the algorithm.
  *  \return Returns a pointer to the new InfAlg object; it is the responsibility of the caller to delete it later.
+ *  \throw UNKNOWN_DAI_ALGORITHM if the requested name is not known/compiled in.
  */
 InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts );
 
@@ -69,7 +70,8 @@ InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const Propert
 /** \param nameOpts The name and options of the inference algorithm (should be in the format "name[key1=val1,key2=val2,...,keyn=valn]").
  *  \param fg The FactorGraph that the algorithm should be applied to.
  *  \return Returns a pointer to the new InfAlg object; it is the responsibility of the caller to delete it later.
- *  \todo Support aliases like in testdai
+ *  \throw UNKNOWN_DAI_ALGORITHM if the requested name is not known/compiled in.
+ *  \todo Support aliases like in testdai.cpp
  */
 InfAlg *newInfAlgFromString( const std::string &nameOpts, const FactorGraph &fg );
 
index 741ff2c..59ba043 100644 (file)
@@ -369,6 +369,9 @@ class BBP {
             UpdateType updates;
 
             /// Set members from PropertySet
+            /** \throw UNKNOWN_PROPERTY_TYPE if a Property key is not recognized
+             *  \throw NOT_ALL_PROPERTIES_SPECIFIED if an expected Property is missing
+             */
             void set(const PropertySet &opts);
             /// Get members into PropertySet
             PropertySet get() const;
index feff3c8..25f20b2 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines the BipartiteGraph class
+/// \brief Defines the BipartiteGraph class, which represents a bipartite graph
 
 
 #ifndef __defined_libdai_bipgraph_h
@@ -133,8 +133,10 @@ class BipartiteGraph {
 
         /// Used internally by isTree()
         struct levelType {
-            std::vector<size_t> ind1;       // indices of nodes of type 1
-            std::vector<size_t> ind2;       // indices of nodes of type 2
+            /// Indices of nodes of type 1
+            std::vector<size_t> ind1;       
+            /// Indices of nodes of type 2
+            std::vector<size_t> ind2;
         };
 
     // OBSOLETE
index e996506..b15e16f 100644 (file)
@@ -177,6 +177,9 @@ class CBP : public DAIAlgFG {
             std::string clamp_outfile;
 
             /// Set members from PropertySet
+            /** \throw UNKNOWN_PROPERTY_TYPE if a Property key is not recognized
+             *  \throw NOT_ALL_PROPERTIES_SPECIFIED if an expected Property is missing
+             */
             void set(const PropertySet &opts);
             /// Get members into PropertySet
             PropertySet get() const;
@@ -211,8 +214,9 @@ class CBP : public DAIAlgFG {
         /// \todo At present, CBP::getInfAlg() only returns a BP instance
         InfAlg* getInfAlg();
 
-        /// Sets variable beliefs, factor beliefs and log partition sum
+        /// Sets variable beliefs, factor beliefs and log partition sum to the specified values
         /** \param bs should be a concatenation of the variable beliefs followed by the factor beliefs
+         *  \param logZ log partition sum
          */
         void setBeliefs( const std::vector<Factor> &bs, Real logZ );
 
index 439aeb9..cfa5dbe 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines class ClusterGraph, which is mainly useful for the junction tree algorithm
+/// \brief Defines class ClusterGraph, which is used by JTree, TreeEP and HAK
 
 
 #ifndef __defined_libdai_clustergraph_h
index 205b74d..793d039 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines abstract base class InfAlg, its descendant DAIAlg<>, the specializations DAIAlgFG and DAIAlgRG and some generic inference methods.
+/// \brief Defines the general interface for inference methods in libDAI (classes InfAlg, DaiAlg<>, DaiAlgFG and DaiAlgRG).
 
 
 #ifndef __defined_libdai_daialg_h
@@ -67,6 +67,7 @@ class InfAlg {
         /// Initializes all data structures corresponding to some set of variables.
         /** This method can be used to do a partial initialization after a part of the factor graph has changed.
          *  Instead of initializing all data structures, it only initializes those involving the variables in \a vs.
+         *  \throw NOT_IMPLEMENTED if not implemented/supported
          */
         virtual void init( const VarSet &vs ) = 0;
 
@@ -82,6 +83,7 @@ class InfAlg {
 
         /// Returns the (approximate) marginal probability distribution of a set of variables.
         /** \note Before this method is called, run() should have been called.
+         *  \throw NOT_IMPLEMENTED if not implemented/supported
          */
         virtual Factor belief( const VarSet &vs ) const = 0;
 
@@ -141,8 +143,12 @@ class InfAlg {
     /// \name Backup/restore mechanism for factors
     //@{
         /// Make a backup copy of factor \a I
+        /** \throw MULTIPLE_UNDO if a backup already exists
+         */
         virtual void backupFactor( size_t I ) = 0;
         /// Make backup copies of all factors involving the variables in \a vs
+        /** \throw MULTIPLE_UNDO if a backup already exists
+         */
         virtual void backupFactors( const VarSet &vs ) = 0;
 
         /// Restore factor \a I from its backup copy
index cc51c53..a0a6c22 100644 (file)
  *  where each of those sections follows the format described in the next
  *  subsection.
  *
- *  \subsection fileformats-sharedparameters Shared parameters section in EM file
+ *  \subsection fileformats-emalg-sharedparameters Shared parameters section in EM file
  *
  *  A shared parameters section of an .em file starts with a single line
  *  consisting of the name of a ParameterEstimation subclass
  *  Then, each of these factors is specified on separate lines (possibly 
  *  seperated by empty lines), where each line consists of several fields
  *  seperated by a space or a tab character. The first field contains 
- *  the index of the factor in the factor graph. The 
- *  following fields specify the ordering of the variables on which that
- *  factor depends, i.e., they form a permutation of the labels of the
- *  variables belonging to that factor. The permutation corresponds to the
- *  mapping from the ordering of the variables that is used in the 
- *  SharedParameters object to the canonical ordering of the variables
- *  (i.e., sorted ascendingly according to their labels) which is used in
- *  the internal representation of the Factor object.
+ *  the index of the factor in the factor graph. The following fields should
+ *  contain the variable labels of the variables on which that factor depends, 
+ *  in a specific ordering. This ordering can be different from the canonical 
+ *  ordering of the variables used internally in libDAI (which would be sorted 
+ *  ascendingly according to the variable labels). The odering of the variables
+ *  specifies the implicit ordering of the shared parameters: when iterating
+ *  over all shared parameters, the corresponding index of the first variable
+ *  changes fastest (in the inner loop), and the corresponding index of the
+ *  last variable changes slowest (in the outer loop). By choosing the right
+ *  ordering, it is possible to let different factors (depending on different
+ *  variables) share parameters in parameter learning using EM.
  */
 
 /** \page license License
index 31c3524..05b3bf1 100644 (file)
@@ -24,7 +24,7 @@
 
 
 /// \file
-/// \brief Defines classes related to Expectation Maximization: EMAlg, ParameterEstimation, CondProbEstimation and SharedParameters
+/// \brief Defines classes related to Expectation Maximization (EMAlg, ParameterEstimation, CondProbEstimation and SharedParameters)
 
 
 namespace dai {
@@ -64,6 +64,7 @@ class ParameterEstimation {
         /** \param method Name of the subclass that should be constructed;
          *  \param p Parameters passed to constructor of subclass.
          *  \note \a method should either be in the default registry or should be registered first using registerMethod().
+         *  \throw UNKNOWN_PARAMETER_ESTIMATION_METHOD if the requested \a method is not registered.
          */
         static ParameterEstimation* construct( const std::string &method, const PropertySet &p );
 
@@ -164,7 +165,7 @@ class SharedParameters {
     private:
         /// Maps factor indices to the corresponding VarSets
         std::map<FactorIndex, VarSet> _varsets;
-        /// Maps factor indices to the corresponding Permute objects that permute the desired ordering into the canonical ordering
+        /// Maps factor indices to the corresponding Permute objects that permute the canonical ordering into the desired ordering
         std::map<FactorIndex, Permute> _perms;
         /// Maps factor indices to the corresponding desired variable orderings
         FactorOrientations _varorders;
@@ -173,12 +174,12 @@ class SharedParameters {
         /// Indicates whether \c *this gets ownership of _estimation
         bool _ownEstimation;
 
-        /// Calculates the permutation that permutes the variables in varorder into the canonical ordering
-        /** \param varorder Given ordering of variables
-         *  \param outVS Contains variables in \varorder represented as a VarSet
-         *  \return Permute object for permuting variables in varorder into the canonical libDAI ordering
+        /// Calculates the permutation that permutes the canonical ordering into the desired ordering
+        /** \param varOrder Desired ordering of variables
+         *  \param outVS Contains variables in \a varOrder represented as a VarSet
+         *  \return Permute object for permuting variables in varOrder from the canonical libDAI ordering into the desired ordering
          */
-        static Permute calculatePermutation( const std::vector<Var> &varorder, VarSet &outVS );
+        static Permute calculatePermutation( const std::vector<Var> &varOrder, VarSet &outVS );
 
         /// Initializes _varsets and _perms from _varorders and checks whether their state spaces correspond with _estimation.probSize()
         void setPermsAndVarSetsFromVarOrders();
@@ -193,6 +194,7 @@ class SharedParameters {
 
         /// Construct a SharedParameters object from an input stream \a is and a factor graph \a fg
         /** \see \ref fileformats-emalg-sharedparameters
+         *  \throw INVALID_EMALG_FILE if the input stream is not valid
          */
         SharedParameters( std::istream &is, const FactorGraph &fg );
 
@@ -234,6 +236,7 @@ class SharedParameters {
  */
 class MaximizationStep {
     private:
+        /// Vector of parameter estimation tasks of which this maximization step consists
         std::vector<SharedParameters> _params;
 
     public:
index 187300d..9413b18 100644 (file)
 namespace dai {
 
 
-/// Stores joint state of a set of variables
-typedef std::map<Var, size_t> Observation;
-
-
 /// Stores a data set consisting of multiple samples, where each sample is the observed joint state of some variables.
 /** \note Each sample can describe the joint state of a different set of variables,
  *  in order to be able to deal with missing data.
@@ -35,6 +31,10 @@ typedef std::map<Var, size_t> Observation;
  *  \author Charles Vaske
  */
 class Evidence {
+    public:
+        /// Stores joint state of a set of variables
+        typedef std::map<Var, size_t> Observation;
+
     private:
         /// Each sample is an observed joint state of some variables
         std::vector<Observation> _samples;
@@ -50,6 +50,7 @@ class Evidence {
         /** \param is Input stream in .tab file format, describing joint observations of variables in \a fg
          *  \param fg Factor graph describing the corresponding variables
          *  \see \ref fileformats-evidence
+         *  \throw INVALID_EVIDENCE_FILE if the input stream is not valid
          */
         void addEvidenceTabFile( std::istream& is, FactorGraph& fg );
 
index 2ea3da3..7f710b5 100644 (file)
@@ -60,7 +60,7 @@
 /// Assertion mechanism similar to DAI_ASSERT which is only active if DAI_DEBUG is defined
 #define DAI_DEBASSERT(x) do {DAI_ASSERT(x);} while(0)
 #else
-#define DAI_DEBASSERT(X) do {} while(0)
+#define DAI_DEBASSERT(x) do {} while(0)
 #endif
 
 
index 7a40309..7330e1e 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines the FactorGraph class
+/// \brief Defines the FactorGraph class, which represents factor graphs (e.g., Bayesian networks or Markov random fields)
 
 
 #ifndef __defined_libdai_factorgraph_h
@@ -246,18 +246,24 @@ class FactorGraph {
         }
 
         /// Makes a backup of the \a I 'th factor
+        /** \throw MULTIPLE_UNDO if a backup already exists
+         */
         void backupFactor( size_t I );
 
         /// Restores the \a I 'th factor from the backup (it should be backed up first)
         void restoreFactor( size_t I );
 
         /// Backup the factors specified by indices in \a facs
+        /** \throw MULTIPLE_UNDO if a backup already exists
+         */
         virtual void backupFactors( const std::set<size_t> & facs );
 
         /// Restore all factors to the backup copies
         virtual void restoreFactors();
 
         /// Makes a backup of all factors connected to a set of variables
+        /** \throw MULTIPLE_UNDO if a backup already exists
+         */
         void backupFactors( const VarSet &ns );
 
         /// Restores all factors connected to a set of variables from their backups
@@ -321,11 +327,14 @@ class FactorGraph {
     //@{
         /// Reads a factor graph from a file
         /** \see \ref fileformats-factorgraph
+         *  \throw CANNOT_READ_FILE if the file cannot be opened
+         *  \throw INVALID_FACTORGRAPH_FILE if the file is not valid
          */
         void ReadFromFile( const char *filename );
 
         /// Writes a factor graph to a file
         /** \see \ref fileformats-factorgraph
+         *  \throw CANNOT_WRITE_FILE if the file cannot be written
          */
         void WriteToFile( const char *filename, size_t precision=15 ) const;
 
@@ -336,6 +345,7 @@ class FactorGraph {
 
         /// Reads a factor graph from an input stream
         /** \see \ref fileformats-factorgraph
+         *  \throw INVALID_FACTORGRAPH_FILE if the input stream is not valid
          */
         friend std::istream& operator>> (std::istream &is, FactorGraph &fg );
 
index a67988a..b92d3e5 100644 (file)
@@ -90,6 +90,7 @@ class JTree : public DAIAlgRG {
         /** \param fg factor graph (which has to be connected);
          *  \param opts parameters;
          *  \param automatic if \c true, construct the junction tree automatically, using the MinFill heuristic.
+         *  \throw FACTORGRAPH_NOT_CONNECTED if \a fg is not connected
          */
         JTree( const FactorGraph &fg, const PropertySet &opts, bool automatic=true );
     //@}
index 528def6..10e7201 100644 (file)
@@ -104,6 +104,9 @@ class MR : public DAIAlgFG {
         MR() : DAIAlgFG(), supported(), con(), nb(), tJ(), theta(), M(), kindex(), cors(), N(), Mag(), _maxdiff(), _iters(), props() {}
 
         /// Construct from FactorGraph \a fg and PropertySet \a opts
+        /** \note This implementation only deals with binary variables and pairwise interactions.
+         *  \throw NOT_IMPLEMENTED if \a fg has factors depending on three or more variables or has variables with more than two possible states.
+         */
         MR( const FactorGraph &fg, const PropertySet &opts );
 
 
@@ -185,6 +188,8 @@ class MR : public DAIAlgFG {
         /// Calculate sum over all even/odd subsets B of \a A of _tJ(j,B) appM(j,B)
         /** \param j variable index
          *  \param A subset of neighbors of variable \a j
+         *  \param sum_even on return, will contain the sum over all even subsets
+         *  \param sum_odd on return, will contain the sum over all odd subsets
          */
         void sum_subs(size_t j, sub_nb A, Real *sum_even, Real *sum_odd);
 };
index d382478..60f5b6d 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines TProb<> and Prob classes which represent (probability) vectors
+/// \brief Defines TProb<> and Prob classes which represent (probability) vectors (e.g., probability distributions of discrete random variables)
 
 
 #ifndef __defined_libdai_prob_h
@@ -424,6 +424,8 @@ template <typename T> class TProb {
         }
 
         /// Returns normalized copy of \c *this, using the specified norm
+        /** \throw NOT_NORMALIZABLE if the norm is zero
+         */
         TProb<T> normalized( NormType norm = NORMPROB ) const {
             T Z = 0;
             if( norm == NORMPROB )
@@ -475,6 +477,8 @@ template <typename T> class TProb {
         }
 
         /// Normalizes vector using the specified norm
+        /** \throw NOT_NORMALIZABLE if the norm is zero
+         */
         T normalize( NormType norm=NORMPROB ) {
             T Z = 0;
             if( norm == NORMPROB )
index 406477a..1b6fdff 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines the Property and PropertySet classes
+/// \brief Defines the Property and PropertySet classes, which are mainly used for managing parameters of inference algorithms
 
 
 #ifndef __defined_libdai_properties_h
@@ -228,6 +228,7 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
         /// Reads a PropertySet object from an input stream.
         /** It expects a string in the format <tt>"[key1=val1,key2=val2,...,keyn=valn]"</tt>.
          *  Values are stored as strings.
+         *  \throw MALFORMED_PROPERTY if the string is not in the expected format
          */
         friend std::istream& operator>> ( std::istream& is, PropertySet& ps );
     //@}
index 46690e7..bb5224f 100644 (file)
@@ -10,7 +10,7 @@
 
 
 /// \file
-/// \brief Defines classes Region, FRegion and RegionGraph.
+/// \brief Defines classes Region, FRegion and RegionGraph, which implement a particular subclass of region graphs.
 
 
 #ifndef __defined_libdai_regiongraph_h
index 07a7897..6499a18 100644 (file)
@@ -72,6 +72,7 @@ class TreeEP : public JTree {
 
     private:
         /// Stores the data structures needed to efficiently update the approximation of an off-tree factor
+        /// \todo Write documentation
         class TreeEPSubTree {
             private:
                 std::vector<Factor>  _Qa;
@@ -142,6 +143,9 @@ class TreeEP : public JTree {
         }
 
         /// Construct from FactorGraph \a fg and PropertySet \a opts
+        /** \note The factor graph has to be connected.
+         *  \throw FACTORGRAPH_NOT_CONNECTED if \a fg is not connected
+         */
         TreeEP( const FactorGraph &fg, const PropertySet &opts );
 
 
index 4da817c..c0c8e39 100755 (executable)
@@ -189,6 +189,9 @@ EOF
   $text .= <<EOF;
 
             /// Set members from PropertySet
+            /** \\throw UNKNOWN_PROPERTY_TYPE if a Property key is not recognized
+             *  \\throw NOT_ALL_PROPERTIES_SPECIFIED if an expected Property is missing
+             */
             void set(const PropertySet &opts);
             /// Get members into PropertySet
             PropertySet get() const;
index cb1a449..e14ebc1 100644 (file)
@@ -78,25 +78,9 @@ Prob CondProbEstimation::estimate() {
 }
 
 
-Permute SharedParameters::calculatePermutation( const std::vector<Var> &varorder, VarSet &outVS ) {
-    // Collect all labels and dimensions, and order them in vs
-    std::vector<size_t> dims;
-    dims.reserve( varorder.size() );
-    std::vector<long> labels;
-    labels.reserve( varorder.size() );
-    for( size_t i = 0; i < varorder.size(); i++ ) {
-        dims.push_back( varorder[i].states() );
-        labels.push_back( varorder[i].label() );
-        outVS |= varorder[i];
-    }
-
-    // Construct the sigma array for the permutation object
-    std::vector<size_t> sigma;
-    sigma.reserve( dims.size() );
-    for( VarSet::iterator set_iterator = outVS.begin(); sigma.size() < dims.size(); ++set_iterator )
-        sigma.push_back( find(labels.begin(), labels.end(), set_iterator->label()) - labels.begin() );
-
-    return Permute( dims, sigma );
+Permute SharedParameters::calculatePermutation( const std::vector<Var> &varOrder, VarSet &outVS ) {
+    outVS = VarSet( varOrder.begin(), varOrder.end(), varOrder.size() );
+    return Permute( varOrder );
 }
 
 
@@ -148,14 +132,14 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg )
 
         // Lookup the factor in the factorgraph
         if( fields.size() < 1 )
-            DAI_THROW(INVALID_EMALG_FILE);
+            DAI_THROWE(INVALID_EMALG_FILE,"Empty line unexpected");
         std::istringstream iss;
         iss.str( fields[0] );
         size_t factor;
         iss >> factor;
         const VarSet &vs = fg.factor(factor).vars();
         if( fields.size() != vs.size() + 1 )
-            DAI_THROW(INVALID_EMALG_FILE);
+            DAI_THROWE(INVALID_EMALG_FILE,"Number of fields does not match factor size");
 
         // Construct the vector of Vars
         std::vector<Var> var_order;
@@ -170,7 +154,7 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg )
                 if( vsi->label() == label )
                     break;
             if( vsi == vs.end() )
-                DAI_THROW(INVALID_EMALG_FILE);
+                DAI_THROWE(INVALID_EMALG_FILE,"Specified variables do not match the factor variables");
             var_order.push_back( *vsi );
         }
         _varorders[factor] = var_order;
@@ -189,7 +173,7 @@ void SharedParameters::collectSufficientStatistics( InfAlg &alg ) {
         Factor b = alg.belief(vs);
         Prob p( b.states(), 0.0 );
         for( size_t entry = 0; entry < b.states(); ++entry )
-            p[entry] = b[perm.convertLinearIndex(entry)];
+            p[entry] = b[perm.convertLinearIndex(entry)]; // apply inverse permutation
         _estimation->addSufficientStatistics( p );
     }
 }
@@ -291,7 +275,7 @@ Real EMAlg::iterate( MaximizationStep &mstep ) {
     for( Evidence::const_iterator e = _evidence.begin(); e != _evidence.end(); ++e ) {
         InfAlg* clamped = _estep.clone();
         // Apply evidence
-        for( Observation::const_iterator i = e->begin(); i != e->end(); ++i )
+        for( Evidence::Observation::const_iterator i = e->begin(); i != e->end(); ++i )
             clamped->clamp( clamped->fg().findVar(i->first), i->second );
         clamped->init();
         clamped->run();
index b737864..41088f5 100644 (file)
@@ -117,7 +117,7 @@ std::istream& operator>> ( std::istream& is, FactorGraph &fg ) {
 
     getline (is,line);
     if( is.fail() )
-        DAI_THROW(INVALID_FACTORGRAPH_FILE);
+        DAI_THROWE(INVALID_FACTORGRAPH_FILE,"Expecting empty line");
 
     map<long,size_t> vardims;
     for( size_t I = 0; I < nr_Factors; I++ ) {
@@ -153,7 +153,8 @@ std::istream& operator>> ( std::istream& is, FactorGraph &fg ) {
             cerr << "  dimensions: " << dims << endl;
 
         // add the Factor
-        VarSet I_vars;
+        vector<Var> Ivars;
+        Ivars.reserve( nr_members );
         for( size_t mi = 0; mi < nr_members; mi++ ) {
             map<long,size_t>::iterator vdi = vardims.find( labels[mi] );
             if( vdi != vardims.end() ) {
@@ -162,23 +163,12 @@ std::istream& operator>> ( std::istream& is, FactorGraph &fg ) {
                     DAI_THROWE(INVALID_FACTORGRAPH_FILE,"Variable with label " + boost::lexical_cast<string>(labels[mi]) + " has inconsistent dimensions.");
             } else
                 vardims[labels[mi]] = dims[mi];
-            I_vars |= Var(labels[mi], dims[mi]);
+            Ivars.push_back( Var(labels[mi], dims[mi]) );
         }
-        facs.push_back( Factor( I_vars, (Real)0 ) );
-
-        // calculate permutation sigma (internally, members are sorted)
-        vector<size_t> sigma(nr_members,0);
-        VarSet::iterator j = I_vars.begin();
-        for( size_t mi = 0; mi < nr_members; mi++,j++ ) {
-            long search_for = j->label();
-            vector<long>::iterator j_loc = find(labels.begin(),labels.end(),search_for);
-            sigma[mi] = j_loc - labels.begin();
-        }
-        if( verbose >= 3 )
-            cerr << "  sigma: " << sigma << endl;
+        facs.push_back( Factor( VarSet( Ivars.begin(), Ivars.end(), Ivars.size() ), (Real)0 ) );
 
-        // calculate multindices
-        Permute permindex( dims, sigma );
+        // calculate permutation object
+        Permute permindex( Ivars );
 
         // read values
         size_t nr_nonzeros;
@@ -197,8 +187,7 @@ std::istream& operator>> ( std::istream& is, FactorGraph &fg ) {
                 getline(is,line);
             is >> val;
 
-            // store value, but permute indices first according
-            // to internal representation
+            // store value, but permute indices first according to internal representation
             facs.back()[permindex.convertLinearIndex( li )] = val;
         }
     }
index 19d47f1..db6e9b8 100644 (file)
@@ -189,7 +189,8 @@ Real TreeEP::TreeEPSubTree::logZ( const std::vector<Factor> &Qa, const std::vect
 TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opts("updates",string("HUGIN")), false), _maxdiff(0.0), _iters(0), props(), _Q() {
     setProperties( opts );
 
-    DAI_ASSERT( fg.isConnected() );
+    if( !isConnected() )
+       DAI_THROW(FACTORGRAPH_NOT_CONNECTED);
 
     if( opts.hasKey("tree") ) {
         construct( opts.GetAs<RootedTree>("tree") );