Documented all exceptions and did some general cleanups
[libdai.git] / src / emalg.cpp
index cd222be..e14ebc1 100644 (file)
@@ -16,6 +16,7 @@
 namespace dai {
 
 
 namespace dai {
 
 
+// Initialize static private member of ParameterEstimation
 std::map<std::string, ParameterEstimation::ParamEstFactory> *ParameterEstimation::_registry = NULL;
 
 
 std::map<std::string, ParameterEstimation::ParamEstFactory> *ParameterEstimation::_registry = NULL;
 
 
@@ -62,10 +63,8 @@ Prob CondProbEstimation::estimate() {
     // normalize pseudocounts
     for( size_t parent = 0; parent < _stats.size(); parent += _target_dim ) {
         // calculate norm
     // normalize pseudocounts
     for( size_t parent = 0; parent < _stats.size(); parent += _target_dim ) {
         // calculate norm
-        Real norm = 0.0;
         size_t top = parent + _target_dim;
         size_t top = parent + _target_dim;
-        for( size_t i = parent; i < top; ++i )
-            norm += _stats[i];
+        Real norm = std::accumulate( &(_stats[parent]), &(_stats[top]), 0.0 );
         if( norm != 0.0 )
             norm = 1.0 / norm;
         // normalize
         if( norm != 0.0 )
             norm = 1.0 / norm;
         // normalize
@@ -79,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 );
 }
 
 
 }
 
 
@@ -116,8 +99,16 @@ void SharedParameters::setPermsAndVarSetsFromVarOrders() {
 }
 
 
 }
 
 
-SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varlookup )
-  : _varsets(), _perms(), _varorders(), _estimation(NULL), _deleteEstimation(true)
+SharedParameters::SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool ownPE )
+  : _varsets(), _perms(), _varorders(varorders), _estimation(estimation), _ownEstimation(ownPE)
+{
+    // Calculate the necessary permutations and varsets
+    setPermsAndVarSetsFromVarOrders();
+}
+
+
+SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg )
+  : _varsets(), _perms(), _varorders(), _estimation(NULL), _ownEstimation(true)
 {
     // Read the desired parameter estimation method from the stream
     std::string est_method;
 {
     // Read the desired parameter estimation method from the stream
     std::string est_method;
@@ -141,14 +132,14 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varl
 
         // Lookup the factor in the factorgraph
         if( fields.size() < 1 )
 
         // 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;
         std::istringstream iss;
         iss.str( fields[0] );
         size_t factor;
         iss >> factor;
-        const VarSet &vs = fg_varlookup.factor(factor).vars();
+        const VarSet &vs = fg.factor(factor).vars();
         if( fields.size() != vs.size() + 1 )
         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;
 
         // Construct the vector of Vars
         std::vector<Var> var_order;
@@ -163,7 +154,7 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varl
                 if( vsi->label() == label )
                     break;
             if( vsi == vs.end() )
                 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;
             var_order.push_back( *vsi );
         }
         _varorders[factor] = var_order;
@@ -174,23 +165,6 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varl
 }
 
 
 }
 
 
-SharedParameters::SharedParameters( const SharedParameters &sp )
-  : _varsets(sp._varsets), _perms(sp._perms), _varorders(sp._varorders), _estimation(sp._estimation), _deleteEstimation(sp._deleteEstimation)
-{
-    // If sp owns its _estimation object, we should clone it instead
-    if( _deleteEstimation )
-        _estimation = _estimation->clone();
-}
-
-
-SharedParameters::SharedParameters( const FactorOrientations &varorders, ParameterEstimation *estimation, bool deletePE )
-  : _varsets(), _perms(), _varorders(varorders), _estimation(estimation), _deleteEstimation(deletePE)
-{
-    // Calculate the necessary permutations
-    setPermsAndVarSetsFromVarOrders();
-}
-
-
 void SharedParameters::collectSufficientStatistics( InfAlg &alg ) {
     for( std::map< FactorIndex, Permute >::iterator i = _perms.begin(); i != _perms.end(); ++i ) {
         Permute &perm = i->second;
 void SharedParameters::collectSufficientStatistics( InfAlg &alg ) {
     for( std::map< FactorIndex, Permute >::iterator i = _perms.begin(); i != _perms.end(); ++i ) {
         Permute &perm = i->second;
@@ -199,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 )
         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 );
     }
 }
         _estimation->addSufficientStatistics( p );
     }
 }
@@ -220,22 +194,6 @@ void SharedParameters::setParameters( FactorGraph &fg ) {
 }
 
 
 }
 
 
-void SharedParameters::collectParameters( const FactorGraph &fg, std::vector<Real> &outVals, std::vector<Var> &outVarOrder ) {
-    FactorOrientations::iterator it = _varorders.begin();
-    if( it == _varorders.end() )
-        return;
-    FactorIndex I = it->first;
-    for( std::vector<Var>::const_iterator var_it = _varorders[I].begin(); var_it != _varorders[I].end(); ++var_it )
-        outVarOrder.push_back( *var_it );
-
-    const Factor &f = fg.factor(I);
-    DAI_ASSERT( f.vars() == _varsets[I] );
-    const Permute &perm = _perms[I];
-    for( size_t val_index = 0; val_index < f.states(); ++val_index )
-        outVals.push_back( f[perm.convertLinearIndex(val_index)] );
-}
-
-
 MaximizationStep::MaximizationStep( std::istream &is, const FactorGraph &fg_varlookup ) : _params() {
     size_t num_params = -1;
     is >> num_params;
 MaximizationStep::MaximizationStep( std::istream &is, const FactorGraph &fg_varlookup ) : _params() {
     size_t num_params = -1;
     is >> num_params;
@@ -317,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( 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();
             clamped->clamp( clamped->fg().findVar(i->first), i->second );
         clamped->init();
         clamped->run();