Improved properties.h/cpp and added unit tests
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Fri, 26 Mar 2010 15:35:19 +0000 (16:35 +0100)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Fri, 26 Mar 2010 15:35:19 +0000 (16:35 +0100)
* Improved properties.h/cpp:
  - Renamed PropertySet::Set() -> PropertySet::set()
  - Renamed PropertySet::Get() -> PropertySet::get()
  - Renamed PropertySet::GetAs<T>() -> PropertySet::getAs<T>()
  - Renamed PropertySet::ConvertTo<T>() -> PropertySet::convertTo<T>()
  - Added PropertySet::size()
  - Added PropertySet::clear()
  - Added PropertySet::erase()
  - Fixed bug in PropertySet::setAsString<T>()

26 files changed:
ChangeLog
Makefile
examples/example.cpp
examples/example_sprinkler_em.cpp
examples/example_sprinkler_gibbs.cpp
include/dai/exceptions.h
include/dai/properties.h
scripts/regenerate-properties
src/alldai.cpp
src/bbp.cpp
src/bp.cpp
src/cbp.cpp
src/exactinf.cpp
src/gibbs.cpp
src/hak.cpp
src/jtree.cpp
src/lc.cpp
src/mf.cpp
src/mr.cpp
src/properties.cpp
src/treeep.cpp
src/trwbp.cpp
tests/testbbp.cpp
tests/testem/testem.cpp
tests/unit/properties.cpp [new file with mode: 0644]
utils/createfg.cpp

index 810817f..95aaea9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,15 @@
 git HEAD
 --------
 
+* Improved properties.h/cpp:
+  - Renamed PropertySet::Set() -> PropertySet::set()
+  - Renamed PropertySet::Get() -> PropertySet::get()
+  - Renamed PropertySet::GetAs<T>() -> PropertySet::getAs<T>()
+  - Renamed PropertySet::ConvertTo<T>() -> PropertySet::convertTo<T>()
+  - Added PropertySet::size()
+  - Added PropertySet::clear()
+  - Added PropertySet::erase()
+  - Fixed bug in PropertySet::setAsString<T>()
 * Improved util.h/cpp:
   - Fixed a bug in rnd_seed()
   - Removed Real max( const std::vector<Real> &v )
@@ -39,7 +48,7 @@ git HEAD
 * Removed RandomDRegularGraph()
 * Compressed Makefile
 * Added unit tests for var, smallset, varset, graph, bipgraph,
-  weightedgraph, enum, util
+  weightedgraph, enum, util, properties
 * Added unit testing framework
 * Added initialization of TRWBP weights by sampling spanning trees
 * Cleaned up MR code:
index 840956b..beea6c6 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -122,16 +122,17 @@ examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example
 
 matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
 
-unittests : tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/enum$(EE) tests/unit/util$(EE)
+unittests : tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/enum$(EE) tests/unit/util$(EE) tests/unit/properties$(EE)
        echo Running unit tests...
-       tests/unit/var
-       tests/unit/smallset
-       tests/unit/varset
-       tests/unit/graph
-       tests/unit/bipgraph
-       tests/unit/weightedgraph
-       tests/unit/enum
-       tests/unit/util
+       tests/unit/var$(EE)
+       tests/unit/smallset$(EE)
+       tests/unit/varset$(EE)
+       tests/unit/graph$(EE)
+       tests/unit/bipgraph$(EE)
+       tests/unit/weightedgraph$(EE)
+       tests/unit/enum$(EE)
+       tests/unit/util$(EE)
+       tests/unit/properties$(EE)
 
 tests : tests/testdai$(EE) tests/testem/testem$(EE) tests/testbbp$(EE) $(unittests)
 
@@ -209,6 +210,8 @@ tests/unit/enum$(EE) : tests/unit/enum.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
 tests/unit/util$(EE) : tests/unit/util.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
+tests/unit/properties$(EE) : tests/unit/properties.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
 
 
 # TESTS
@@ -315,7 +318,7 @@ clean :
        -rm matlab/*$(ME)
        -rm examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_permute$(EE) examples/example_sprinkler$(EE) examples/example_sprinkler_gibbs$(EE) examples/example_sprinkler_em$(EE)
        -rm tests/testdai$(EE) tests/testem/testem$(EE) tests/testbbp$(EE)
-       -rm tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/util$(EE)
+       -rm tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/util$(EE) tests/unit/properties$(EE)
        -rm utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE)
        -rm -R doc
        -rm -R lib
@@ -350,6 +353,7 @@ clean :
        -del tests\unit\weightedgraph$(EE)
        -del tests\unit\enum$(EE)
        -del tests\unit\util$(EE)
+       -del tests\unit\properties$(EE)
        -del $(LIB)\libdai$(LE)
        -rmdir lib
 endif
index 210a293..68e509f 100644 (file)
@@ -35,9 +35,9 @@ int main( int argc, char *argv[] ) {
 
         // Store the constants in a PropertySet object
         PropertySet opts;
-        opts.Set("maxiter",maxiter);  // Maximum number of iterations
-        opts.Set("tol",tol);          // Tolerance for convergence
-        opts.Set("verbose",verb);     // Verbosity (amount of output generated)
+        opts.set("maxiter",maxiter);  // Maximum number of iterations
+        opts.set("tol",tol);          // Tolerance for convergence
+        opts.set("verbose",verb);     // Verbosity (amount of output generated)
 
         // Construct a JTree (junction tree) object from the FactorGraph fg
         // using the parameters specified by opts and an additional property
index fee9f19..6c9c7ce 100644 (file)
@@ -31,8 +31,8 @@ int main() {
 
     // Prepare junction-tree object for doing exact inference for E-step
     PropertySet infprops;
-    infprops.Set( "verbose", (size_t)1 );
-    infprops.Set( "updates", string("HUGIN") );
+    infprops.set( "verbose", (size_t)1 );
+    infprops.set( "updates", string("HUGIN") );
     InfAlg* inf = newInfAlg( "JTREE", SprinklerNetwork, infprops );
     inf->init();
 
index 8d90b4e..b5b02e8 100644 (file)
@@ -37,9 +37,9 @@ int main() {
 
     // Prepare a Gibbs sampler
     PropertySet gibbsProps;
-    gibbsProps.Set("iters", size_t(100));   // number of Gibbs sampler iterations
-    gibbsProps.Set("burnin", size_t(0));
-    gibbsProps.Set("verbose", size_t(0));
+    gibbsProps.set("iters", size_t(100));   // number of Gibbs sampler iterations
+    gibbsProps.set("burnin", size_t(0));
+    gibbsProps.set("verbose", size_t(0));
     Gibbs gibbsSampler( SprinklerNetwork, gibbsProps );
 
     // Open a .tab file for writing
index b52ac27..8e03342 100644 (file)
@@ -103,7 +103,7 @@ class Exception : public std::runtime_error {
         /// Constructor
         Exception( Code _code, const std::string& msg="", const std::string& detailedMsg="" ) : std::runtime_error(ErrorStrings[_code] + " [" +  msg + "]"), errorcode(_code) {
             if( !detailedMsg.empty() )
-                std::cerr << "ERROR: " << detailedMsg << std::endl;
+                std::cerr << "EXCEPTION: " << detailedMsg << std::endl;
         }
 
         /// Returns error code of this exception
index 1b6fdff..289b7a3 100644 (file)
@@ -4,7 +4,7 @@
  *  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) 2006-2010  Joris Mooij  [joris dot mooij at libdai dot org]
  *  Copyright (C) 2006-2007  Radboud University Nijmegen, The Netherlands
  */
 
@@ -42,6 +42,10 @@ typedef std::pair<PropertyKey, PropertyValue> Property;
 
 
 /// Writes a Property object (key-value pair) to an output stream
+/** \note Not all value types are automatically supported; if a type is unknown, an 
+ *  UNKNOWN_PROPERTY_TYPE exception is thrown. Adding support for a new type can 
+ *  be done by changing this function body.
+ */
 std::ostream& operator<< ( std::ostream & os, const Property &p );
 
 
@@ -89,16 +93,16 @@ class PropertySet : private std::map<PropertyKey, PropertyValue> {
     /// \name Setting property keys/values
     //@{
         /// Sets a property (a key \a key with a corresponding value \a val)
-        PropertySet& Set( const PropertyKey& key, const PropertyValue& val ) { 
+        PropertySet& set( const PropertyKey& key, const PropertyValue& val ) { 
             this->operator[](key) = val; 
             return *this; 
         }
 
         /// Set properties according to \a newProps, overriding properties that already exist with new values
-        PropertySet& Set( const PropertySet& newProps ) {
+        PropertySet& set( const PropertySet& newProps ) {
             const std::map<PropertyKey, PropertyValue> *m = &newProps;
             foreach(value_type i, *m)
-                Set( i.first, i.second );
+                set( i.first, i.second );
             return *this;
         }
 
@@ -110,7 +114,7 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
          */
         PropertySet operator()( const PropertyKey& key, const PropertyValue& val ) const { 
             PropertySet copy = *this; 
-            return copy.Set(key,val); 
+            return copy.set(key,val); 
         }
 
         /// Sets a property (a key \a key with a corresponding value \a val, which is first converted from \a ValueType to string)
@@ -119,9 +123,9 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
          *  \throw IMPOSSIBLE_TYPECAST if the type cast cannot be done
          */
         template<typename ValueType>
-        PropertySet& setAsString( const PropertyKey& key, ValueType& val ) {
+        PropertySet& setAsString( const PropertyKey& key, const ValueType& val ) {
             try {
-                return Set( key, boost::lexical_cast<std::string>(val) );
+                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.");
             }
@@ -133,12 +137,12 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
          *  \throw IMPOSSIBLE_TYPECAST if the type cast cannot be done
          */
         template<typename ValueType>
-        void ConvertTo( const PropertyKey& key ) { 
-            PropertyValue val = Get(key);
+        void convertTo( const PropertyKey& key ) { 
+            PropertyValue val = get(key);
             if( val.type() != typeid(ValueType) ) {
                 DAI_ASSERT( val.type() == typeid(std::string) );
                 try {
-                    Set(key, boost::lexical_cast<ValueType>(GetAs<std::string>(key)));
+                    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.");
                 }
@@ -150,6 +154,21 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
 
     /// \name Queries
     //@{
+        /// Return number of key-value pairs
+        size_t size() const {
+            return std::map<PropertyKey, PropertyValue>::size();
+        }
+
+        /// Removes all key-value pairs
+        void clear() {
+            std::map<PropertyKey, PropertyValue>::clear();
+        }
+
+        /// Removes key-value pair with given \a key
+        size_t erase( const PropertyKey &key ) {
+            return std::map<PropertyKey, PropertyValue>::erase( key );
+        }
+
         /// Check if a property with the given \a key is defined
         bool hasKey( const PropertyKey& key ) const { 
             PropertySet::const_iterator x = find(key); 
@@ -168,10 +187,10 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
         /// Gets the value corresponding to \a key
         /** \throw OBJECT_NOT_FOUND if the key cannot be found in \c *this
          */
-        const PropertyValue& Get( const PropertyKey& key ) const {
+        const PropertyValue& get( const PropertyKey& key ) const {
             PropertySet::const_iterator x = find(key);
             if( x == this->end() )
-                DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::Get cannot find property '" + key + "'");
+                DAI_THROWE(OBJECT_NOT_FOUND,"PropertySet::get cannot find property '" + key + "'");
             return x->second;
         }
 
@@ -181,9 +200,9 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
          *  \throw IMPOSSIBLE_TYPECAST if the type cast cannot be done
          */
         template<typename ValueType>
-        ValueType GetAs( const PropertyKey& key ) const {
+        ValueType getAs( const PropertyKey& key ) const {
             try {
-                return boost::any_cast<ValueType>(Get(key));
+                return boost::any_cast<ValueType>(get(key));
             } catch( const boost::bad_any_cast & ) {
                 DAI_THROWE(IMPOSSIBLE_TYPECAST,"Cannot cast value of property '" + key + "' to desired type.");
                 return ValueType();
@@ -200,12 +219,12 @@ PropertySet p()("method","BP")("verbose",1)("tol",1e-9)
          */
         template<typename ValueType>
         ValueType getStringAs( const PropertyKey& key ) const { 
-            PropertyValue val = Get(key);
+            PropertyValue val = get(key);
             if( val.type() == typeid(ValueType) ) {
                 return boost::any_cast<ValueType>(val);
             } else if( val.type() == typeid(std::string) ) {
                 try {
-                    return boost::lexical_cast<ValueType>(GetAs<std::string>(key));
+                    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.");
                 }
index 16f9d46..52b39d1 100755 (executable)
@@ -262,7 +262,7 @@ EOF
     my ($type,$name,$default,$cmt) = @$v;
 #     $text .= qq{opts.set("$name", $name);};
     $stext .= <<EOF;
-    opts.Set("$name", $name);
+    opts.set("$name", $name);
 EOF
 
   }
index b7a2421..04ea599 100644 (file)
@@ -113,7 +113,7 @@ std::pair<std::string, PropertySet> parseNameProperties( const std::string &s, c
         if( aps.first == ps.first )
             looped = true;
         // override aps properties by ps properties
-        aps.second.Set( ps.second );
+        aps.second.set( ps.second );
         // replace ps by aps
         ps = aps;
         // repeat until method name == alias name ('looped'), or
index bd41b72..b0e0139 100644 (file)
@@ -1172,11 +1172,11 @@ void BBP::Properties::set(const PropertySet &opts)
 }
 PropertySet BBP::Properties::get() const {
     PropertySet opts;
-    opts.Set("verbose", verbose);
-    opts.Set("maxiter", maxiter);
-    opts.Set("tol", tol);
-    opts.Set("damping", damping);
-    opts.Set("updates", updates);
+    opts.set("verbose", verbose);
+    opts.set("maxiter", maxiter);
+    opts.set("tol", tol);
+    opts.set("damping", damping);
+    opts.set("updates", updates);
     return opts;
 }
 string BBP::Properties::toString() const {
index 799043a..91951a2 100644 (file)
@@ -60,13 +60,13 @@ void BP::setProperties( const PropertySet &opts ) {
 
 PropertySet BP::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "maxiter", props.maxiter );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "logdomain", props.logdomain );
-    opts.Set( "updates", props.updates );
-    opts.Set( "damping", props.damping );
-    opts.Set( "inference", props.inference );
+    opts.set( "tol", props.tol );
+    opts.set( "maxiter", props.maxiter );
+    opts.set( "verbose", props.verbose );
+    opts.set( "logdomain", props.logdomain );
+    opts.set( "updates", props.updates );
+    opts.set( "damping", props.damping );
+    opts.set( "inference", props.inference );
     return opts;
 }
 
index d609253..751938e 100644 (file)
@@ -152,12 +152,12 @@ Real CBP::run() {
 
 InfAlg* CBP::getInfAlg() {
     PropertySet bpProps;
-    bpProps.Set("updates", props.updates);
-    bpProps.Set("tol", props.tol);
-    bpProps.Set("maxiter", props.maxiter);
-    bpProps.Set("verbose", props.verbose);
-    bpProps.Set("logdomain", false);
-    bpProps.Set("damping", (Real)0.0);
+    bpProps.set("updates", props.updates);
+    bpProps.set("tol", props.tol);
+    bpProps.set("maxiter", props.maxiter);
+    bpProps.set("verbose", props.verbose);
+    bpProps.set("logdomain", false);
+    bpProps.set("damping", (Real)0.0);
     BP *bp = new BP( *this, bpProps );
     bp->recordSentMessages = true;
     bp->init();
@@ -597,20 +597,20 @@ void CBP::Properties::set(const PropertySet &opts)
 }
 PropertySet CBP::Properties::get() const {
     PropertySet opts;
-    opts.Set("verbose", verbose);
-    opts.Set("tol", tol);
-    opts.Set("updates", updates);
-    opts.Set("maxiter", maxiter);
-    opts.Set("rec_tol", rec_tol);
-    opts.Set("max_levels", max_levels);
-    opts.Set("min_max_adj", min_max_adj);
-    opts.Set("choose", choose);
-    opts.Set("recursion", recursion);
-    opts.Set("clamp", clamp);
-    opts.Set("bbp_props", bbp_props);
-    opts.Set("bbp_cfn", bbp_cfn);
-    opts.Set("rand_seed", rand_seed);
-    opts.Set("clamp_outfile", clamp_outfile);
+    opts.set("verbose", verbose);
+    opts.set("tol", tol);
+    opts.set("updates", updates);
+    opts.set("maxiter", maxiter);
+    opts.set("rec_tol", rec_tol);
+    opts.set("max_levels", max_levels);
+    opts.set("min_max_adj", min_max_adj);
+    opts.set("choose", choose);
+    opts.set("recursion", recursion);
+    opts.set("clamp", clamp);
+    opts.set("bbp_props", bbp_props);
+    opts.set("bbp_cfn", bbp_cfn);
+    opts.set("rand_seed", rand_seed);
+    opts.set("clamp_outfile", clamp_outfile);
     return opts;
 }
 string CBP::Properties::toString() const {
index 875b728..080f2e5 100644 (file)
@@ -31,7 +31,7 @@ void ExactInf::setProperties( const PropertySet &opts ) {
 
 PropertySet ExactInf::getProperties() const {
     PropertySet opts;
-    opts.Set( "verbose", props.verbose );
+    opts.set( "verbose", props.verbose );
     return opts;
 }
 
index 65e8603..cc18e14 100644 (file)
@@ -46,9 +46,9 @@ void Gibbs::setProperties( const PropertySet &opts ) {
 
 PropertySet Gibbs::getProperties() const {
     PropertySet opts;
-    opts.Set( "iters", props.iters );
-    opts.Set( "burnin", props.burnin );
-    opts.Set( "verbose", props.verbose );
+    opts.set( "iters", props.iters );
+    opts.set( "burnin", props.burnin );
+    opts.set( "verbose", props.verbose );
     return opts;
 }
 
@@ -235,9 +235,9 @@ Factor Gibbs::belief( const VarSet &ns ) const {
 
 std::vector<size_t> getGibbsState( const FactorGraph &fg, size_t iters ) {
     PropertySet gibbsProps;
-    gibbsProps.Set("iters", iters);
-    gibbsProps.Set("burnin", size_t(0));
-    gibbsProps.Set("verbose", size_t(0));
+    gibbsProps.set("iters", iters);
+    gibbsProps.set("burnin", size_t(0));
+    gibbsProps.set("verbose", size_t(0));
     Gibbs gibbs( fg, gibbsProps );
     gibbs.run();
     return gibbs.state();
index b19c936..60d072b 100644 (file)
@@ -73,14 +73,14 @@ void HAK::setProperties( const PropertySet &opts ) {
 
 PropertySet HAK::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "maxiter", props.maxiter );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "doubleloop", props.doubleloop );
-    opts.Set( "clusters", props.clusters );
-    opts.Set( "init", props.init );
-    opts.Set( "loopdepth", props.loopdepth );
-    opts.Set( "damping", props.damping );
+    opts.set( "tol", props.tol );
+    opts.set( "maxiter", props.maxiter );
+    opts.set( "verbose", props.verbose );
+    opts.set( "doubleloop", props.doubleloop );
+    opts.set( "clusters", props.clusters );
+    opts.set( "init", props.init );
+    opts.set( "loopdepth", props.loopdepth );
+    opts.set( "damping", props.damping );
     return opts;
 }
 
index 294e72e..c4d13fb 100644 (file)
@@ -42,10 +42,10 @@ void JTree::setProperties( const PropertySet &opts ) {
 
 PropertySet JTree::getProperties() const {
     PropertySet opts;
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "updates", props.updates );
-    opts.Set( "inference", props.inference );
-    opts.Set( "heuristic", props.heuristic );
+    opts.set( "verbose", props.verbose );
+    opts.set( "updates", props.updates );
+    opts.set( "inference", props.inference );
+    opts.set( "heuristic", props.heuristic );
     return opts;
 }
 
index c8f3bbf..5aa3dbf 100644 (file)
@@ -54,15 +54,15 @@ void LC::setProperties( const PropertySet &opts ) {
 
 PropertySet LC::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "maxiter", props.maxiter );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "cavity", props.cavity );
-    opts.Set( "updates", props.updates );
-    opts.Set( "cavainame", props.cavainame );
-    opts.Set( "cavaiopts", props.cavaiopts );
-    opts.Set( "reinit", props.reinit );
-    opts.Set( "damping", props.damping );
+    opts.set( "tol", props.tol );
+    opts.set( "maxiter", props.maxiter );
+    opts.set( "verbose", props.verbose );
+    opts.set( "cavity", props.cavity );
+    opts.set( "updates", props.updates );
+    opts.set( "cavainame", props.cavainame );
+    opts.set( "cavaiopts", props.cavaiopts );
+    opts.set( "reinit", props.reinit );
+    opts.set( "damping", props.damping );
     return opts;
 }
 
index 227b11a..a143608 100644 (file)
@@ -45,10 +45,10 @@ void MF::setProperties( const PropertySet &opts ) {
 
 PropertySet MF::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "maxiter", props.maxiter );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "damping", props.damping );
+    opts.set( "tol", props.tol );
+    opts.set( "maxiter", props.maxiter );
+    opts.set( "verbose", props.verbose );
+    opts.set( "damping", props.damping );
     return opts;
 }
 
index 0b051ac..763ee66 100644 (file)
@@ -45,10 +45,10 @@ void MR::setProperties( const PropertySet &opts ) {
 
 PropertySet MR::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "updates", props.updates );
-    opts.Set( "inits", props.inits );
+    opts.set( "tol", props.tol );
+    opts.set( "verbose", props.verbose );
+    opts.set( "updates", props.updates );
+    opts.set( "inits", props.inits );
     return opts;
 }
 
index 628ef98..df1f0a5 100644 (file)
@@ -21,6 +21,8 @@ std::ostream& operator<< (std::ostream & os, const Property & p) {
     os << p.first << "=";
     if( p.second.type() == typeid(size_t) )
         os << boost::any_cast<size_t>(p.second);
+    else if( p.second.type() == typeid(int) )
+        os << boost::any_cast<int>(p.second);
     else if( p.second.type() == typeid(std::string) )
         os << boost::any_cast<std::string>(p.second);
     else if( p.second.type() == typeid(double) )
@@ -91,7 +93,7 @@ std::istream& operator>> (std::istream& is, PropertySet & ps) {
         std::string value = s.substr(token_start, token_end - token_start);
 
         // store the key,value pair
-        ps.Set(key,value);
+        ps.set(key,value);
 
         // go on with the next one
         token_start = token_end + 1;
index 9edb75d..b9f17df 100644 (file)
@@ -41,10 +41,10 @@ void TreeEP::setProperties( const PropertySet &opts ) {
 
 PropertySet TreeEP::getProperties() const {
     PropertySet opts;
-    opts.Set( "tol", props.tol );
-    opts.Set( "maxiter", props.maxiter );
-    opts.Set( "verbose", props.verbose );
-    opts.Set( "type", props.type );
+    opts.set( "tol", props.tol );
+    opts.set( "maxiter", props.maxiter );
+    opts.set( "verbose", props.verbose );
+    opts.set( "type", props.type );
     return opts;
 }
 
@@ -67,7 +67,7 @@ TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opt
        DAI_THROW(FACTORGRAPH_NOT_CONNECTED);
 
     if( opts.hasKey("tree") ) {
-        construct( opts.GetAs<RootedTree>("tree") );
+        construct( opts.getAs<RootedTree>("tree") );
     } else {
         if( props.type == Properties::TypeType::ORG || props.type == Properties::TypeType::ALT ) {
             // ORG: construct weighted graph with as weights a crude estimate of the
index 13d951e..34c2943 100644 (file)
@@ -35,7 +35,7 @@ void TRWBP::setProperties( const PropertySet &opts ) {
 
 PropertySet TRWBP::getProperties() const {
     PropertySet opts = BP::getProperties();
-    opts.Set( "nrtrees", nrtrees );
+    opts.set( "nrtrees", nrtrees );
     return opts;
 }
 
index 91952dc..5747d84 100644 (file)
@@ -37,10 +37,10 @@ int main( int argc, char *argv[] ) {
 
         // Store the constants in a PropertySet object
         PropertySet opts;
-        opts.Set("verbose",verbose);  // Verbosity (amount of output generated)
-        opts.Set("tol",tol);          // Tolerance for convergence
-        opts.Set("maxiter",maxiter);  // Maximum number of iterations
-        opts.Set("damping",damping);  // Amount of damping applied
+        opts.set("verbose",verbose);  // Verbosity (amount of output generated)
+        opts.set("tol",tol);          // Tolerance for convergence
+        opts.set("maxiter",maxiter);  // Maximum number of iterations
+        opts.set("damping",damping);  // Amount of damping applied
 
         // Construct a BP (belief propagation) object from the FactorGraph fg
         BP bp(fg, opts("updates",string("SEQFIX"))("logdomain",false));
index 919b0d7..c55296e 100644 (file)
@@ -38,8 +38,8 @@ int main( int argc, char** argv ) {
     fg.ReadFromFile( argv[1] );
 
     PropertySet infprops;
-    infprops.Set( "verbose", (size_t)1 );
-    infprops.Set( "updates", string("HUGIN") );
+    infprops.set( "verbose", (size_t)1 );
+    infprops.set( "updates", string("HUGIN") );
     InfAlg* inf = newInfAlg( "JTREE", fg, infprops );
     inf->init();
 
diff --git a/tests/unit/properties.cpp b/tests/unit/properties.cpp
new file mode 100644 (file)
index 0000000..bb7e55f
--- /dev/null
@@ -0,0 +1,235 @@
+/*  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) 2010  Joris Mooij      [joris dot mooij at libdai dot org]
+ */
+
+
+#define BOOST_TEST_DYN_LINK
+
+
+#include <dai/properties.h>
+#include <strstream>
+
+
+using namespace dai;
+
+
+#define BOOST_TEST_MODULE PropertiesTest
+
+
+#include <boost/test/unit_test.hpp>
+
+
+BOOST_AUTO_TEST_CASE( PropertyTest ) {
+    std::stringstream str1, str2, str3, str4, str5, str6, str7, str8;
+    std::string s;
+
+    Property p;
+    p.first = "key";
+
+    p.second = (int)-5;
+    str1 << p;
+    str1 >> s;
+    BOOST_CHECK_EQUAL( s, "key=-5" );
+
+    p.second = (size_t)5;
+    str2 << p;
+    str2 >> s;
+    BOOST_CHECK_EQUAL( s, "key=5" );
+
+    p.second = std::string("value");
+    str3 << p;
+    str3 >> s;
+    BOOST_CHECK_EQUAL( s, "key=value" );
+
+    p.second = 3.141;
+    str4 << p;
+    str4 >> s;
+    BOOST_CHECK_EQUAL( s, "key=3.141" );
+
+    p.second = (long double)3.141;
+    str5 << p;
+    str5 >> s;
+    BOOST_CHECK_EQUAL( s, "key=3.141" );
+
+    p.second = false;
+    str6 << p;
+    str6 >> s;
+    BOOST_CHECK_EQUAL( s, "key=0" );
+
+    p.second = PropertySet()("prop2",(size_t)5)("prop1",std::string("hi"));
+    str7 << p;
+    str7 >> s;
+    BOOST_CHECK_EQUAL( s, "key=[prop1=hi,prop2=5]" );
+
+    p.second = std::vector<int>();
+    BOOST_CHECK_THROW( str7 << p, Exception );
+}
+
+
+BOOST_AUTO_TEST_CASE( ConstructorsTest ) {
+    PropertySet x;
+    PropertySet y("[key1=val1,key2=5,key3=[key3a=val,key3b=7.0],key4=1.0]");
+    PropertySet z = PropertySet()("key1",std::string("val1"))("key2",5)("key3",PropertySet("[key3a=val,key3b=7.0]"))("key4",1.0);
+
+    BOOST_CHECK( !x.hasKey("key") );
+    BOOST_CHECK( !y.hasKey("key") );
+    BOOST_CHECK( !z.hasKey("key") );
+    BOOST_CHECK( y.hasKey("key1") );
+    BOOST_CHECK( y.hasKey("key2") );
+    BOOST_CHECK( y.hasKey("key3") );
+    BOOST_CHECK( !y.hasKey("key3a") );
+    BOOST_CHECK( !y.hasKey("key3b") );
+    BOOST_CHECK( y.hasKey("key4") );
+    BOOST_CHECK( z.hasKey("key1") );
+    BOOST_CHECK( z.hasKey("key2") );
+    BOOST_CHECK( z.hasKey("key3") );
+    BOOST_CHECK( !z.hasKey("key3a") );
+    BOOST_CHECK( !z.hasKey("key3b") );
+    BOOST_CHECK( z.hasKey("key4") );
+
+    BOOST_CHECK_EQUAL( x.size(), 0 );
+    BOOST_CHECK_EQUAL( y.size(), 4 );
+    BOOST_CHECK_EQUAL( z.size(), 4 );
+    std::set<std::string> keys;
+    keys.insert( "key1" );
+    keys.insert( "key2" );
+    keys.insert( "key3" );
+    keys.insert( "key4" );
+    BOOST_CHECK( y.keys() == keys );
+    BOOST_CHECK( z.keys() == keys );
+
+    BOOST_CHECK_THROW( x.get( "key" ), Exception );
+    BOOST_CHECK_THROW( y.get( "key" ), Exception );
+    BOOST_CHECK_THROW( z.get( "key" ), Exception );
+    BOOST_CHECK_THROW( x.getAs<std::string>( "key" ), Exception );
+    BOOST_CHECK_THROW( y.getAs<int>( "key" ), Exception );
+    BOOST_CHECK_THROW( z.getAs<double>( "key" ), Exception );
+    BOOST_CHECK_THROW( x.getStringAs<int>( "key" ), Exception );
+    BOOST_CHECK_THROW( y.getStringAs<int>( "key" ), Exception );
+    BOOST_CHECK_THROW( z.getStringAs<int>( "key" ), Exception );
+
+    BOOST_CHECK_EQUAL( boost::any_cast<std::string>(y.get( "key1" )), std::string("val1") );
+    BOOST_CHECK_EQUAL( boost::any_cast<std::string>(y.get( "key2" )), std::string("5") );
+    BOOST_CHECK_EQUAL( boost::any_cast<std::string>(y.get( "key3" )), std::string("[key3a=val,key3b=7.0]") );
+    BOOST_CHECK_EQUAL( boost::any_cast<std::string>(y.get( "key4" )), std::string("1.0") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key2" ), std::string("5") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key3" ), std::string("[key3a=val,key3b=7.0]") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key4" ), std::string("1.0") );
+    BOOST_CHECK_EQUAL( y.getStringAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( y.getStringAs<size_t>( "key2" ), 5 );
+    BOOST_CHECK_EQUAL( y.getStringAs<int>( "key2" ), 5 );
+    BOOST_CHECK_EQUAL( y.getStringAs<double>( "key4" ), 1.0 );
+    PropertySet key3val = y.getStringAs<PropertySet>( "key3" );
+    BOOST_CHECK_EQUAL( key3val.size(), 2 );
+    BOOST_CHECK( key3val.hasKey( "key3a" ) );
+    BOOST_CHECK( key3val.hasKey( "key3b" ) );
+    BOOST_CHECK_EQUAL( key3val.getStringAs<std::string>( "key3a" ), std::string("val") );
+    BOOST_CHECK_EQUAL( key3val.getStringAs<double>( "key3b" ), 7.0 );
+    BOOST_CHECK_THROW( y.getAs<int>( "key2" ), Exception );
+    BOOST_CHECK_THROW( y.getStringAs<int>( "key4" ), Exception );
+
+    BOOST_CHECK_EQUAL( boost::any_cast<std::string>(z.get( "key1" )), std::string("val1") );
+    BOOST_CHECK_EQUAL( boost::any_cast<int>(z.get( "key2" )), 5 );
+    BOOST_CHECK_EQUAL( boost::any_cast<PropertySet>(z.get( "key3" )).size(), 2 );
+    BOOST_CHECK_EQUAL( boost::any_cast<double>(z.get( "key4" )), 1.0 );
+    BOOST_CHECK_EQUAL( z.getAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( z.getAs<int>( "key2" ), 5 );
+    BOOST_CHECK_EQUAL( z.getAs<PropertySet>( "key3" ).size(), 2 );
+    BOOST_CHECK_EQUAL( z.getAs<double>( "key4" ), 1.0 );
+    BOOST_CHECK_EQUAL( z.getStringAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( z.getStringAs<int>( "key2" ), 5 );
+    BOOST_CHECK_EQUAL( z.getStringAs<double>( "key4" ), 1.0 );
+    key3val = z.getAs<PropertySet>( "key3" );
+    BOOST_CHECK_EQUAL( key3val.size(), 2 );
+    BOOST_CHECK( key3val.hasKey( "key3a" ) );
+    BOOST_CHECK( key3val.hasKey( "key3b" ) );
+    BOOST_CHECK_EQUAL( key3val.getStringAs<std::string>( "key3a" ), std::string("val") );
+    BOOST_CHECK_EQUAL( key3val.getStringAs<double>( "key3b" ), 7.0 );
+    BOOST_CHECK_THROW( z.getAs<size_t>( "key2" ), Exception );
+    BOOST_CHECK_THROW( z.getStringAs<size_t>( "key4" ), Exception );
+}
+
+
+BOOST_AUTO_TEST_CASE( SetTest ) {
+    PropertySet x;
+    PropertySet y("[key1=val1,key2=5]");
+
+    x.set( "key1", 5 );
+    BOOST_CHECK( x.hasKey( "key1" ) );
+    BOOST_CHECK( !x.hasKey( "key2" ) );
+    BOOST_CHECK_EQUAL( x.getAs<int>( "key1" ), 5 );
+    BOOST_CHECK_THROW( x.getAs<double>( "key1" ), Exception );
+    BOOST_CHECK_THROW( x.getAs<int>( "key2" ), Exception );
+
+    x.set( y );
+    BOOST_CHECK( x.hasKey( "key1" ) );
+    BOOST_CHECK( x.hasKey( "key2" ) );
+    BOOST_CHECK( !x.hasKey( "key" ) );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key2" ), std::string("5") );
+    x.setAsString<int>( "key1", 5 );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("5") );
+    x.convertTo<size_t>( "key1" );
+    BOOST_CHECK_EQUAL( x.getAs<size_t>( "key1" ), 5 );
+    x.setAsString( "key1", -5 );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("-5") );
+    BOOST_CHECK_THROW( x.convertTo<size_t>( "key1" ), Exception );
+    x.convertTo<int>( "key1" );
+    BOOST_CHECK_EQUAL( x.getAs<int>( "key1" ), -5 );
+    x.setAsString( "key1", 1.234 );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("1.234") );
+    BOOST_CHECK_THROW( x.convertTo<int>( "key1" ), Exception );
+    x.convertTo<double>( "key1" );
+    BOOST_CHECK_EQUAL( x.getAs<double>( "key1" ), 1.234 );
+    x.setAsString( "key1", "val1");
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_THROW( x.convertTo<int>( "key1" ), Exception );
+    x.convertTo<std::string>( "key1" );
+    BOOST_CHECK_EQUAL( x.getAs<std::string>( "key1" ), std::string("val1") );
+
+    BOOST_CHECK_EQUAL( x.erase( "key1" ), 1 );
+    BOOST_CHECK( !x.hasKey( "key1" ) );
+}
+
+
+BOOST_AUTO_TEST_CASE( StreamTest ) {
+    std::stringstream ss1, ss2, ss3;
+    std::string s;
+
+    PropertySet z = PropertySet()("key1",std::string("val1"))("key2",5)("key3",PropertySet("[key3a=val,key3b=7.0]"))("key4",1.0);
+    ss1 << z;
+    ss1 >> s;
+    BOOST_CHECK_EQUAL( s, std::string("[key1=val1,key2=5,key3=[key3a=val,key3b=7.0],key4=1]") );
+    PropertySet y;
+    ss2 << z;
+    ss2 >> y;
+    BOOST_CHECK( y.hasKey( "key1" ) );
+    BOOST_CHECK( y.hasKey( "key2" ) );
+    BOOST_CHECK( y.hasKey( "key3" ) );
+    BOOST_CHECK( y.hasKey( "key4" ) );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key1" ), std::string("val1") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key2" ), std::string("5") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key3" ), std::string("[key3a=val,key3b=7.0]") );
+    BOOST_CHECK_EQUAL( y.getAs<std::string>( "key4" ), std::string("1") );
+
+    z.set( "key5", std::vector<int>() );
+    BOOST_CHECK_THROW( ss1 << z, Exception );
+
+    y.clear();
+    BOOST_CHECK_EQUAL( y.size(), 0 );
+    ss3 << "[]";
+    ss3 >> y;
+    BOOST_CHECK_EQUAL( y.size(), 0 );
+    ss3 << "";
+    BOOST_CHECK_THROW( ss3 >> y, Exception );
+    ss3 << "[key1 = val1]";
+    BOOST_CHECK_THROW( ss3 >> y, Exception );
+    ss3 << "[key1=val1";
+    BOOST_CHECK_THROW( ss3 >> y, Exception );
+}
index 6135349..ee1e2ec 100644 (file)
@@ -47,7 +47,7 @@ FactorGraph createFG( const GraphAL &G, FactorType ft, size_t states, const Prop
     // Get inverse temperature
     Real beta = 1.0;
     if( ft != FactorType::ISING ) 
-        beta = props.GetAs<Real>("beta");
+        beta = props.getAs<Real>("beta");
 
     // Get properties for Ising factors
     Real mean_h = 0.0;
@@ -55,10 +55,10 @@ FactorGraph createFG( const GraphAL &G, FactorType ft, size_t states, const Prop
     Real mean_J = 0.0;
     Real sigma_J = 0.0;
     if( ft == FactorType::ISING ) {
-        mean_h = props.GetAs<Real>("mean_th");
-        sigma_h = props.GetAs<Real>("sigma_th");
-        mean_J = props.GetAs<Real>("mean_w");
-        sigma_J = props.GetAs<Real>("sigma_w");
+        mean_h = props.getAs<Real>("mean_th");
+        sigma_h = props.getAs<Real>("sigma_th");
+        mean_J = props.getAs<Real>("mean_w");
+        sigma_J = props.getAs<Real>("sigma_w");
     }
     
     // Create variables
@@ -448,15 +448,15 @@ int main( int argc, char *argv[] ) {
         // Store some options in a PropertySet object
         PropertySet options;
         if( vm.count("mean_th") )
-            options.Set("mean_th", mean_th);
+            options.set("mean_th", mean_th);
         if( vm.count("sigma_th") )
-            options.Set("sigma_th", sigma_th);
+            options.set("sigma_th", sigma_th);
         if( vm.count("mean_w") )
-            options.Set("mean_w", mean_w);
+            options.set("mean_w", mean_w);
         if( vm.count("sigma_w") )
-            options.Set("sigma_w", sigma_w);
+            options.set("sigma_w", sigma_w);
         if( vm.count("beta") )
-            options.Set("beta", beta);
+            options.set("beta", beta);
 
         // Output some comments
         cout << "# Factor graph made by " << argv[0] << endl;