Cleaned up error handling by introducing the DAI_THROWE macro.
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 7 Sep 2009 13:44:13 +0000 (15:44 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 7 Sep 2009 13:44:13 +0000 (15:44 +0200)
18 files changed:
include/dai/cbp.h
include/dai/enum.h
include/dai/exceptions.h
include/dai/properties.h
include/dai/util.h
scripts/regenerate-properties
src/alldai.cpp
src/bbp.cpp
src/cbp.cpp
src/emalg.cpp
src/evidence.cpp
src/exceptions.cpp
src/factorgraph.cpp
src/hak.cpp
src/mr.cpp
src/properties.cpp
src/treeep.cpp
tests/testdai.cpp

index 2a562e1..d0a03d7 100644 (file)
@@ -209,7 +209,7 @@ class CBP : public DAIAlgFG {
             double rec_tol;
             /// Maximum number of levels of recursion (\a recurse is REC_FIXED)
             size_t max_levels;
-            /// If choose=CHOOSE_BBP and maximum adjoint is less than this value, don't recurse
+            /// If choose==CHOOSE_BBP and maximum adjoint is less than this value, don't recurse
             double min_max_adj;
             /// Heuristic for choosing clamping variable
             ChooseMethodType choose;
index 491cd35..637291e 100644 (file)
         x(value w) : v(w) {}\
 \
         x(char const *w) {\
-            static char const* labelstring = #val0 "," #__VA_ARGS__ ",";\
+            static char const* labelstring = #val0 "," #__VA_ARGS__;\
             size_t pos_begin = 0;\
             size_t i = 0;\
-            for( size_t pos_end = 0; labelstring[pos_end] != '\0'; pos_end++ )\
-                if( (labelstring[pos_end] == ',') ) {\
+            for( size_t pos_end = 0; ; pos_end++ ) {\
+                if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\
                     if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\
                         v = (value)i;\
                         return;\
                         pos_begin = pos_end + 1;\
                     }\
                 }\
-            DAI_THROW(UNKNOWN_ENUM_VALUE);\
+                if( labelstring[pos_end] == '\0' )\
+                    break;\
+            }\
+            DAI_THROWE(UNKNOWN_ENUM_VALUE,"'" + std::string(w) + "' is not in [" + std::string(labelstring) + "]");\
         }\
 \
         operator value() const { return v; }\
index 6023df0..e13120f 100644 (file)
@@ -32,6 +32,7 @@
 #include <exception>
 #include <stdexcept>
 #include <string>
+#include <iostream>
 
 
 /// Used by DAI_THROW
 /// Used by DAI_THROW
 #define DAI_TOSTRING(x) DAI_QUOTE(x)
 
-/// Macro that simplifies throwing an exceptions with a useful error message
+/// Macro that simplifies throwing an exception with a useful error message.
 /** \param cod Corresponds to one of the enum values in dai::Exception::codes
  *
- * Example:
+ *  Example:
  *  \code
  *  DAI_THROW(NOT_IMPLEMENTED);
  *  \endcode
  */
 #define DAI_THROW(cod) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)))
 
+/// Macro that simplifies throwing an exception with a useful error message. It also allows for writing a detailed error message to stderr.
+/** \param cod Corresponds to one of the enum values in dai::Exception::codes
+ *  \param msg Detailed error message that will be written to std::cerr.
+ *
+ *  Example:
+ *  \code
+ *  DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message");
+ *  \endcode
+ */
+#define DAI_THROWE(cod,msg) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)), msg)
+
 
 namespace dai {
 
@@ -71,18 +83,19 @@ class Exception : public std::runtime_error {
                    FACTORGRAPH_NOT_CONNECTED,
                    IMPOSSIBLE_TYPECAST,
                    INTERNAL_ERROR,
+                   RUNTIME_ERROR,
                    NOT_NORMALIZABLE,
                    INVALID_EVIDENCE_FILE,
-                   INVALID_EVIDENCE_LINE,
-                   INVALID_EVIDENCE_OBSERVATION,
-                   INVALID_SHARED_PARAMETERS_ORDER,
-                   INVALID_SHARED_PARAMETERS_INPUT_LINE,
+                   INVALID_EMALG_FILE,
                    UNKNOWN_PARAMETER_ESTIMATION_METHOD,
                    NUM_ERRORS};  // NUM_ERRORS should be the last entry
 
         /// Constructor
-        Exception( Code _code, const std::string& msg="" ) : std::runtime_error(ErrorStrings[_code] + " [" +  msg + "]"), errorcode(_code) {}
-
+        Exception( Code _code, const std::string& msg="", const std::string& detailedMsg="" ) : std::runtime_error(ErrorStrings[_code] + " [" +  msg + "]"), errorcode(_code) { 
+            if( !detailedMsg.empty() ) 
+                std::cerr << "EXCEPTION: " << detailedMsg << std::endl; 
+        }
+        
         /// Copy constructor
         Exception( const Exception &e ) : std::runtime_error(e), errorcode(e.errorcode) {}
 
index 6ad5f2a..00efd07 100644 (file)
@@ -37,6 +37,7 @@
 #include <typeinfo>
 #include <dai/exceptions.h>
 #include <dai/util.h>
+#include <boost/lexical_cast.hpp>
 
 
 namespace dai {
@@ -86,9 +87,8 @@ class PropertySet : private std::map<PropertyKey, PropertyValue> {
         /// Set properties according to those in newProps, overriding properties that already exist with new values
         PropertySet & Set( const PropertySet &newProps ) {
             const std::map<PropertyKey, PropertyValue> *m = &newProps;
-            foreach(value_type i, *m) {
-                Set(i.first, i.second);
-            }
+            foreach(value_type i, *m)
+                Set( i.first, i.second );
             return *this;
         }
 
@@ -98,9 +98,8 @@ class PropertySet : private std::map<PropertyKey, PropertyValue> {
             try {
                 return boost::any_cast<ValueType>(Get(key));
             } catch( const boost::bad_any_cast & ) {
-                std::cerr << "Cannot cast property " << key << " to ";
-                std::cerr << typeid(ValueType).name() << std::endl;
-                return boost::any_cast<ValueType>(Get(key));
+                DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property " + key + " to desired type.");
+                return ValueType();
             }
         }
 
@@ -110,13 +109,11 @@ class PropertySet : private std::map<PropertyKey, PropertyValue> {
             PropertyValue val = Get(key);
             if( val.type() != typeid(ValueType) ) {
                 assert( val.type() == typeid(std::string) );
-
-                std::stringstream ss;
-                ss << GetAs<std::string>(key);
-                ValueType result;
-                ss >> result;
-
-                Set(key, result);
+                try {
+                    Set(key, boost::lexical_cast<ValueType>(GetAs<std::string>(key)));
+                } catch(boost::bad_lexical_cast &) {
+                    DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property " + key + " from string to desired type.");
+                }
             }
         }
 
@@ -127,26 +124,23 @@ class PropertySet : private std::map<PropertyKey, PropertyValue> {
             if( val.type() == typeid(ValueType) ) {
                 return boost::any_cast<ValueType>(val);
             } else if( val.type() == typeid(std::string) ) {
-                std::stringstream ss;
-                ss << GetAs<std::string>(key);
-                ValueType result;
-                ss >> result;
-                return result;
-            } else {
-                DAI_THROW(IMPOSSIBLE_TYPECAST);
-                return ValueType();
-            }
+                try {
+                    return boost::lexical_cast<ValueType>(GetAs<std::string>(key));
+                } catch(boost::bad_lexical_cast &) {
+                    DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property " + key + " from string to desired type.");
+                }
+            } else
+                DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property " + key + " from string to desired type.");
+            return ValueType();
         }
 
         /// Converts a property from ValueType to string (if necessary)
         template<typename ValueType>
         PropertySet & setAsString(const PropertyKey &key, ValueType &val) { 
-            if( val.type() == typeid(std::string) ) {
-                return Set(key, val);
-            } else {
-                std::stringstream ss (std::stringstream::out);
-                ss << val;
-                return Set(key, ss.str());
+            try {
+                return Set( key, boost::lexical_cast<std::string>(val) );
+            } catch( boost::bad_lexical_cast & ) {
+                DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property " + key + " to string.");
             }
         }
 
index d697586..3f61623 100644 (file)
 #define __defined_libdai_util_h
 
 
+#include <string>
 #include <vector>
 #include <set>
 #include <map>
 #include <iostream>
-#include <cstdio>
 #include <boost/foreach.hpp>
 #include <boost/functional/hash.hpp>
 #include <algorithm>
@@ -190,6 +190,9 @@ std::vector<T> concat( const std::vector<T>& u, const std::vector<T>& v ) {
     return w;
 }
 
+/// Split a string into tokens
+void tokenizeString( const std::string& s, std::vector<std::string>& outTokens, const std::string& delim="\t\n" );
+
 /// Used to keep track of the progress made by iterative algorithms
 class Diffs : public std::vector<double> {
     private:
@@ -224,8 +227,7 @@ class Diffs : public std::vector<double> {
                 } else {
                     _maxpos = begin();
                 }
-            }
-            else {
+            } else {
                 if( _pos == end() )
                     _pos = begin();
                 if( _maxpos == _pos ) {
@@ -243,12 +245,6 @@ class Diffs : public std::vector<double> {
 };
 
 
-/// Split a string into tokens
-void tokenizeString( const std::string& s,
-                   std::vector<std::string>& outTokens,
-                   const std::string& delim="\t\n" );
-
-
 } // end of namespace dai
 
 
index 1c3b45a..f3601b9 100755 (executable)
@@ -194,7 +194,6 @@ void ${class}::Properties::set(const PropertySet &opts)
 {
     const std::set<PropertyKey> &keys = opts.allKeys();
     std::set<PropertyKey>::const_iterator i;
-    bool die=false;
     for(i=keys.begin(); i!=keys.end(); i++) {
 EOF
   for my $v (@vars) {
@@ -204,29 +203,20 @@ EOF
 EOF
   }
   $stext .= <<EOF;
-        cerr << "$class: Unknown property " << *i << endl;
-        die=true;
-    }
-    if(die) {
-        DAI_THROW(UNKNOWN_PROPERTY_TYPE);
+        DAI_THROWE(UNKNOWN_PROPERTY_TYPE, "$class: Unknown property " + *i);
     }
 EOF
   for my $v (@vars) {
     my ($type,$name,$default,$cmt) = @$v;
     if(!defined $default) {
       $stext .= <<EOF;
-    if(!opts.hasKey("$name")) {
-        cerr << "$class: Missing property \\\"$name\\\" for method \\\"\Q$class\E\\\"" << endl;
-        die=true;
-    }
+    if(!opts.hasKey("$name"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"$class: Missing property \\\"$name\\\" for method \\\"\Q$class\E\\\"");
 EOF
     }
 
   }
   $stext .= <<EOF;
-    if(die) {
-        DAI_THROW(NOT_ALL_PROPERTIES_SPECIFIED);
-    }
 EOF
   for my $v (@vars) {
     my ($type,$name,$default,$cmt) = @$v;
index 3c5fbba..1e8733f 100644 (file)
@@ -71,7 +71,7 @@ InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const Propert
     if( name == CBP::Name )
         return new CBP (fg, opts);
 #endif
-    DAI_THROW(UNKNOWN_DAI_ALGORITHM);
+    DAI_THROWE(UNKNOWN_DAI_ALGORITHM,"Unknown libDAI algorithm: " + name);
 }
 
 
index 7314a26..1f0161c 100644 (file)
@@ -729,10 +729,8 @@ void BBP::run() {
             const BP *bp = static_cast<const BP*>(_ia);
             vector<pair<size_t, size_t> > sentMessages = bp->getSentMessages();
             size_t totalMessages = sentMessages.size();
-            if( totalMessages == 0 ) {
-                cerr << "Asked for updates = " << updates << " but no BP messages; did you forget to set recordSentMessages?" << endl;
-                DAI_THROW(INTERNAL_ERROR);
-            }
+            if( totalMessages == 0 )
+                DAI_THROWE(INTERNAL_ERROR, "Asked for updates=" + std::string(updates) + " but no BP messages; did you forget to set recordSentMessages?");
             if( updates==UT::SEQ_BP_FWD )
                 reverse( sentMessages.begin(), sentMessages.end() );
 //          DAI_PV(sentMessages.size());
@@ -1031,7 +1029,7 @@ void initBBPCostFnAdj( BBP &bbp, const InfAlg &ia, bbp_cfn_t cfn_type, const vec
                         delta[state[i]] = exp(b); 
                         break;
                     default: 
-                        DAI_THROW(INTERNAL_ERROR);
+                        DAI_THROW(UNKNOWN_ENUM_VALUE);
                 }
                 b1_adj.push_back( delta );
             }
@@ -1069,7 +1067,7 @@ void initBBPCostFnAdj( BBP &bbp, const InfAlg &ia, bbp_cfn_t cfn_type, const vec
                         delta[x_I] = exp( b );
                         break;
                     default: 
-                        DAI_THROW(INTERNAL_ERROR);
+                        DAI_THROW(UNKNOWN_ENUM_VALUE);
                 }
                 b2_adj.push_back( delta );
             }
@@ -1116,7 +1114,7 @@ Real getCostFn( const InfAlg &ia, bbp_cfn_t cfn_type, const vector<size_t> *stat
                         cf += exp( b );
                         break;
                     default:
-                        DAI_THROW(INTERNAL_ERROR);
+                        DAI_THROW(UNKNOWN_ENUM_VALUE);
                 }
             }
             break;
@@ -1140,13 +1138,12 @@ Real getCostFn( const InfAlg &ia, bbp_cfn_t cfn_type, const vector<size_t> *stat
                         cf += exp( b );
                         break;
                     default:
-                        DAI_THROW(INTERNAL_ERROR);
+                        DAI_THROW(UNKNOWN_ENUM_VALUE);
                 }
             }
             break;
         } default: 
-            cerr << "Unknown cost function " << cfn_type << endl;
-            DAI_THROW(UNKNOWN_ENUM_VALUE);
+            DAI_THROWE(UNKNOWN_ENUM_VALUE, "Unknown cost function " + std::string(cfn_type));
     }
     return cf;
 }
@@ -1164,42 +1161,24 @@ void BBP::Properties::set(const PropertySet &opts)
 {
     const std::set<PropertyKey> &keys = opts.allKeys();
     std::set<PropertyKey>::const_iterator i;
-    bool die=false;
     for(i=keys.begin(); i!=keys.end(); i++) {
         if(*i == "verbose") continue;
         if(*i == "maxiter") continue;
         if(*i == "tol") continue;
         if(*i == "damping") continue;
         if(*i == "updates") continue;
-        cerr << "BBP: Unknown property " << *i << endl;
-        die=true;
-    }
-    if(die) {
-        DAI_THROW(UNKNOWN_PROPERTY_TYPE);
-    }
-    if(!opts.hasKey("verbose")) {
-        cerr << "BBP: Missing property \"verbose\" for method \"BBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("maxiter")) {
-        cerr << "BBP: Missing property \"maxiter\" for method \"BBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("tol")) {
-        cerr << "BBP: Missing property \"tol\" for method \"BBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("damping")) {
-        cerr << "BBP: Missing property \"damping\" for method \"BBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("updates")) {
-        cerr << "BBP: Missing property \"updates\" for method \"BBP\"" << endl;
-        die=true;
-    }
-    if(die) {
-        DAI_THROW(NOT_ALL_PROPERTIES_SPECIFIED);
+        DAI_THROWE(UNKNOWN_PROPERTY_TYPE, "BBP: Unknown property " + *i);
     }
+    if(!opts.hasKey("verbose"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"BBP: Missing property \"verbose\" for method \"BBP\"");
+    if(!opts.hasKey("maxiter"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"BBP: Missing property \"maxiter\" for method \"BBP\"");
+    if(!opts.hasKey("tol"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"BBP: Missing property \"tol\" for method \"BBP\"");
+    if(!opts.hasKey("damping"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"BBP: Missing property \"damping\" for method \"BBP\"");
+    if(!opts.hasKey("updates"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"BBP: Missing property \"updates\" for method \"BBP\"");
     verbose = opts.getStringAs<size_t>("verbose");
     maxiter = opts.getStringAs<size_t>("maxiter");
     tol = opts.getStringAs<double>("tol");
@@ -1222,7 +1201,7 @@ string BBP::Properties::toString() const {
     s << "maxiter=" << maxiter << ",";
     s << "tol=" << tol << ",";
     s << "damping=" << damping << ",";
-    s << "updates=" << updates << ",";
+    s << "updates=" << updates;
     s << "]";
     return s.str();
 }
index a641746..a4a5511 100644 (file)
@@ -405,7 +405,7 @@ bool CBP::chooseNextClampVar( InfAlg *bp, vector<size_t> &clamped_vars_list, siz
             assert(/*0<=xi &&*/ xi < factor(i).states() );
         DAI_IFVERB(2, "CHOOSE_BBP (num clamped = " << clamped_vars_list.size() << ") chose " << i << " state " << xi << endl);
     } else
-        DAI_THROW(INTERNAL_ERROR);
+        DAI_THROW(UNKNOWN_ENUM_VALUE);
     clamped_vars_list.push_back( i );
     return true;
 }
@@ -535,7 +535,6 @@ void CBP::Properties::set(const PropertySet &opts)
 {
     const std::set<PropertyKey> &keys = opts.allKeys();
     std::set<PropertyKey>::const_iterator i;
-    bool die=false;
     for(i=keys.begin(); i!=keys.end(); i++) {
         if(*i == "verbose") continue;
         if(*i == "tol") continue;
@@ -551,55 +550,28 @@ void CBP::Properties::set(const PropertySet &opts)
         if(*i == "bbp_cfn") continue;
         if(*i == "rand_seed") continue;
         if(*i == "clamp_outfile") continue;
-        cerr << "CBP: Unknown property " << *i << endl;
-        die=true;
-    }
-    if(die) {
-        DAI_THROW(UNKNOWN_PROPERTY_TYPE);
-    }
-    if(!opts.hasKey("tol")) {
-        cerr << "CBP: Missing property \"tol\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("updates")) {
-        cerr << "CBP: Missing property \"updates\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("maxiter")) {
-        cerr << "CBP: Missing property \"maxiter\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("rec_tol")) {
-        cerr << "CBP: Missing property \"rec_tol\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("min_max_adj")) {
-        cerr << "CBP: Missing property \"min_max_adj\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("choose")) {
-        cerr << "CBP: Missing property \"choose\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("recursion")) {
-        cerr << "CBP: Missing property \"recursion\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("clamp")) {
-        cerr << "CBP: Missing property \"clamp\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("bbp_props")) {
-        cerr << "CBP: Missing property \"bbp_props\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(!opts.hasKey("bbp_cfn")) {
-        cerr << "CBP: Missing property \"bbp_cfn\" for method \"CBP\"" << endl;
-        die=true;
-    }
-    if(die) {
-        DAI_THROW(NOT_ALL_PROPERTIES_SPECIFIED);
+        DAI_THROWE(UNKNOWN_PROPERTY_TYPE, "CBP: Unknown property " + *i);
     }
+    if(!opts.hasKey("tol"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"tol\" for method \"CBP\"");
+    if(!opts.hasKey("updates"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"updates\" for method \"CBP\"");
+    if(!opts.hasKey("maxiter"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"maxiter\" for method \"CBP\"");
+    if(!opts.hasKey("rec_tol"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"rec_tol\" for method \"CBP\"");
+    if(!opts.hasKey("min_max_adj"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"min_max_adj\" for method \"CBP\"");
+    if(!opts.hasKey("choose"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"choose\" for method \"CBP\"");
+    if(!opts.hasKey("recursion"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"recursion\" for method \"CBP\"");
+    if(!opts.hasKey("clamp"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"clamp\" for method \"CBP\"");
+    if(!opts.hasKey("bbp_props"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"bbp_props\" for method \"CBP\"");
+    if(!opts.hasKey("bbp_cfn"))
+        DAI_THROWE(NOT_ALL_PROPERTIES_SPECIFIED,"CBP: Missing property \"bbp_cfn\" for method \"CBP\"");
     if(opts.hasKey("verbose")) {
         verbose = opts.getStringAs<size_t>("verbose");
     } else {
index 8e93700..dff6913 100644 (file)
@@ -40,7 +40,7 @@ ParameterEstimation* ParameterEstimation::construct( const std::string &method,
         loadDefaultRegistry();
     std::map<std::string, ParamEstFactory>::iterator i = _registry->find(method);
     if( i == _registry->end() )
-        DAI_THROW(UNKNOWN_PARAMETER_ESTIMATION_METHOD);
+        DAI_THROWE(UNKNOWN_PARAMETER_ESTIMATION_METHOD, "Unknown parameter estimation method: " + method);
     ParamEstFactory factory = i->second;
     return factory(p);
 }
@@ -59,8 +59,7 @@ ParameterEstimation* CondProbEstimation::factory( const PropertySet &p ) {
 CondProbEstimation::CondProbEstimation( size_t target_dimension, const Prob &pseudocounts ) 
   : _target_dim(target_dimension), _stats(pseudocounts), _initial_stats(pseudocounts) 
 {
-    if( _stats.size() % _target_dim )
-        DAI_THROW(MALFORMED_PROPERTY);
+    assert( !(_stats.size() % _target_dim) );
 }
 
 
@@ -115,16 +114,14 @@ Permute SharedParameters::calculatePermutation( const std::vector<Var> &varorder
 void SharedParameters::setPermsAndVarSetsFromVarOrders() {
     if( _varorders.size() == 0 )
         return;
-    if( _estimation == NULL )
-        DAI_THROW(INVALID_SHARED_PARAMETERS_ORDER);
+    assert( _estimation != NULL );
 
     // Construct the permutation objects and the varsets
     for( FactorOrientations::const_iterator foi = _varorders.begin(); foi != _varorders.end(); ++foi ) {
         VarSet vs;
         _perms[foi->first] = calculatePermutation( foi->second, vs );
         _varsets[foi->first] = vs;
-        if( _estimation->probSize() != vs.nrStates() )
-            DAI_THROW(INVALID_SHARED_PARAMETERS_ORDER);
+        assert( _estimation->probSize() == vs.nrStates() );
     }
 }
 
@@ -154,14 +151,14 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varl
 
         // Lookup the factor in the factorgraph
         if( fields.size() < 1 )
-            DAI_THROW(INVALID_SHARED_PARAMETERS_INPUT_LINE);
+            DAI_THROW(INVALID_EMALG_FILE);
         std::istringstream iss;
         iss.str( fields[0] );
         size_t factor;
         iss >> factor;
         const VarSet &vs = fg_varlookup.factor(factor).vars();
         if( fields.size() != vs.size() + 1 )
-            DAI_THROW(INVALID_SHARED_PARAMETERS_INPUT_LINE);
+            DAI_THROW(INVALID_EMALG_FILE);
 
         // Construct the vector of Vars
         std::vector<Var> var_order;
@@ -176,7 +173,7 @@ SharedParameters::SharedParameters( std::istream &is, const FactorGraph &fg_varl
                 if( vsi->label() == label ) 
                     break;
             if( vsi == vs.end() )
-                DAI_THROW(INVALID_SHARED_PARAMETERS_INPUT_LINE);
+                DAI_THROW(INVALID_EMALG_FILE);
             var_order.push_back( *vsi );
         }
         _varorders[factor] = var_order;
index 10185ec..69fe9ae 100644 (file)
@@ -62,7 +62,7 @@ void Evidence::addEvidenceTabFile( std::istream &is, std::map<std::string, Var>
     tokenizeString( line, header_fields );
     std::vector<std::string>::const_iterator p_field = header_fields.begin();
     if( p_field == header_fields.end() ) 
-        DAI_THROW(INVALID_EVIDENCE_LINE);
+        DAI_THROW(INVALID_EVIDENCE_FILE);
 
     std::vector<Var> vars;
     for( ; p_field != header_fields.end(); ++p_field ) {
@@ -77,16 +77,16 @@ void Evidence::addEvidenceTabFile( std::istream &is, std::map<std::string, Var>
         std::vector<std::string> fields;
         tokenizeString( line, fields );
         if( fields.size() != vars.size() ) 
-            DAI_THROW(INVALID_EVIDENCE_LINE);
+            DAI_THROW(INVALID_EVIDENCE_FILE);
         
         Observation sampleData;
         for( size_t i = 0; i < vars.size(); ++i ) {
             if( fields[i].size() > 0 ) { // skip if missing observation
                 if( fields[i].find_first_not_of("0123456789") != std::string::npos )
-                    DAI_THROW(INVALID_EVIDENCE_OBSERVATION);
+                    DAI_THROW(INVALID_EVIDENCE_FILE);
                 size_t state = atoi( fields[i].c_str() );
                 if( state >= vars[i].states() )
-                    DAI_THROW(INVALID_EVIDENCE_OBSERVATION);
+                    DAI_THROW(INVALID_EVIDENCE_FILE);
                 sampleData.addObservation( vars[i], state );
             }
         }
index 84b2e22..3530c32 100644 (file)
@@ -40,12 +40,10 @@ namespace dai {
         "FactorGraph is not connected",
         "Impossible typecast",
         "Internal error",
+        "Runtime error",
         "Quantity not normalizable",
-        "Cannot parse Evidence file",
-        "Cannot parse Evidence line",
-        "Invalid observation in Evidence file",
-        "Invalid variable order in SharedParameters",
-        "Variable order line in EM file is invalid",
+        "Invalid Evidence file",
+        "Invalid Expectation-Maximization file",
         "Unrecognized parameter estimation method"
     }; 
 
index 11ea17f..263b186 100644 (file)
@@ -32,6 +32,7 @@
 #include <dai/factorgraph.h>
 #include <dai/util.h>
 #include <dai/exceptions.h>
+#include <boost/lexical_cast.hpp>
 
 
 namespace dai {
@@ -121,7 +122,7 @@ istream& operator >> (istream& is, FactorGraph& fg) {
         getline(is,line);
     is >> nr_Factors;
     if( is.fail() )
-        DAI_THROW(INVALID_FACTORGRAPH_FILE);
+        DAI_THROWE(INVALID_FACTORGRAPH_FILE,"Cannot read number of factors");
     if( verbose >= 2 )
         cerr << "Reading " << nr_Factors << " factors..." << endl;
 
@@ -169,7 +170,7 @@ istream& operator >> (istream& is, FactorGraph& fg) {
             if( vdi != vardims.end() ) {
                 // check whether dimensions are consistent
                 if( vdi->second != dims[mi] )
-                    DAI_THROW(INVALID_FACTORGRAPH_FILE);
+                    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]);
@@ -262,7 +263,7 @@ void FactorGraph::ReadFromFile( const char *filename ) {
         infile >> *this;
         infile.close();
     } else
-        DAI_THROW(CANNOT_READ_FILE);
+        DAI_THROWE(CANNOT_READ_FILE,"Cannot read from file " + std::string(filename));
 }
 
 
@@ -274,7 +275,7 @@ void FactorGraph::WriteToFile( const char *filename, size_t precision ) const {
         outfile << *this;
         outfile.close();
     } else
-        DAI_THROW(CANNOT_WRITE_FILE);
+        DAI_THROWE(CANNOT_WRITE_FILE,"Cannot write to file " + std::string(filename));
 }
 
 
@@ -356,7 +357,7 @@ void FactorGraph::clampFactor( size_t I, const vector<size_t> &is, bool backup )
 void FactorGraph::backupFactor( size_t I ) {
     map<size_t,Factor>::iterator it = _backup.find( I );
     if( it != _backup.end() )
-        DAI_THROW( MULTIPLE_UNDO );
+        DAI_THROW(MULTIPLE_UNDO);
     _backup[I] = factor(I);
 }
 
index 250e9d9..44878f7 100644 (file)
@@ -161,7 +161,7 @@ HAK::HAK(const FactorGraph & fg, const PropertySet &opts) : DAIAlgRG(), _Qa(), _
                 cerr << *cli << endl;
         }
     } else
-        DAI_THROW(INTERNAL_ERROR);
+        DAI_THROW(UNKNOWN_ENUM_VALUE);
 
     RegionGraph rg(fg,cl);
     RegionGraph::operator=(rg);
index 1888b48..61ed067 100644 (file)
@@ -499,11 +499,11 @@ void MR::init_cor() {
     for( size_t i = 0; i < nrVars(); i++ ) {
         vector<Factor> pairq;
         if( props.inits == Properties::InitType::CLAMPING ) {
-            BP bpcav(*this, PropertySet()("updates", string("SEQMAX"))("tol", string("1e-9"))("maxiter", string("10000UL"))("verbose", string("0UL"))("logdomain", string("0")));
+            BP bpcav(*this, PropertySet()("updates", string("SEQMAX"))("tol", 1.0e-9)("maxiter", 10000UL)("verbose", 0UL)("logdomain", false));
             bpcav.makeCavity( i );
             pairq = calcPairBeliefs( bpcav, delta(i), false );
         } else if( props.inits == Properties::InitType::EXACT ) {
-            JTree jtcav(*this, PropertySet()("updates", string("HUGIN"))("verbose", string("0UL")) );
+            JTree jtcav(*this, PropertySet()("updates", string("HUGIN"))("verbose", 0UL) );
             jtcav.makeCavity( i );
             pairq = calcPairBeliefs( jtcav, delta(i), false );
         }
index bf6d7a0..d035076 100644 (file)
@@ -68,7 +68,7 @@ std::istream& operator >> (std::istream& is, PropertySet & ps) {
 
     // Check whether s is of the form "[.*]"
     if( (s.length() < 2) || (s.at(0) != '[') || (s.at(s.length()-1)) != ']' )
-        DAI_THROW(MALFORMED_PROPERTY);
+        DAI_THROWE(MALFORMED_PROPERTY,"Malformed PropertySet: " + s);
 
     size_t N = s.length() - 1;
     for( size_t token_start = 1; token_start < N; ) {
@@ -78,10 +78,10 @@ std::istream& operator >> (std::istream& is, PropertySet & ps) {
         for( token_end = token_start + 1; token_end < N; token_end++ )
             if( s[token_end] == '=' )
                 break;
-        if( token_end == N )
-            DAI_THROW(MALFORMED_PROPERTY);
         // we found a key
         std::string key = s.substr(token_start, token_end - token_start);
+        if( token_end == N )
+            DAI_THROWE(MALFORMED_PROPERTY,"Malformed Property: " + key);
 
         token_start = token_end + 1;
         // scan until matching ',' is found
@@ -95,7 +95,7 @@ std::istream& operator >> (std::istream& is, PropertySet & ps) {
                 break;
         }
         if( !(level == 0) )
-            DAI_THROW(MALFORMED_PROPERTY);
+            DAI_THROWE(MALFORMED_PROPERTY,"Malformed Property: " + s.substr(token_start, token_end - token_start));
         // we found a vlue
         std::string value = s.substr(token_start, token_end - token_start);
 
index 2c88f98..b9e19e3 100644 (file)
@@ -247,7 +247,7 @@ TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opt
             // find maximal spanning tree
             ConstructRG( MaxSpanningTreePrims( wg ) );
         } else
-            DAI_THROW(INTERNAL_ERROR);
+            DAI_THROW(UNKNOWN_ENUM_VALUE);
     }
 }
 
index 918ec52..1600fe6 100644 (file)
@@ -197,7 +197,7 @@ pair<string, PropertySet> parseMethod( const string &_s, const map<string,string
         if( ps.first == DAINames[n] )
             break;
     if( strlen( DAINames[n] ) == 0 && (ps.first != "LDPC") )
-        throw std::runtime_error(string("Unknown DAI algorithm \"") + ps.first + string("\" in \"") + _s + string("\""));
+        DAI_THROWE(UNKNOWN_DAI_ALGORITHM,string("Unknown DAI algorithm \"") + ps.first + string("\" in \"") + _s + string("\""));
 
     return ps;
 }
@@ -274,7 +274,7 @@ int main( int argc, char *argv[] ) {
                     if( (!line.empty()) && (line[0] != '#') ) {
                         string::size_type pos = line.find(':',0);
                         if( pos == string::npos )
-                            throw string("Invalid alias");
+                            DAI_THROWE(RUNTIME_ERROR,"Invalid alias");
                         else {
                             string::size_type posl = line.substr(0, pos).find_last_not_of(" \t");
                             string key = line.substr(0, posl + 1);
@@ -286,7 +286,7 @@ int main( int argc, char *argv[] ) {
                 }
                 infile.close();
             } else
-                throw string("Error opening aliases file");
+                DAI_THROWE(RUNTIME_ERROR,"Error opening aliases file");
         }
 
         FactorGraph fg;