Added builtinInfAlgs() and builtinInfAlgNames()
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 11 Jul 2011 15:43:22 +0000 (17:43 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Mon, 11 Jul 2011 15:43:22 +0000 (17:43 +0200)
18 files changed:
ChangeLog
examples/example.cpp
include/dai/alldai.h
include/dai/bp.h
include/dai/cbp.h
include/dai/daialg.h
include/dai/decmap.h
include/dai/exactinf.h
include/dai/fbp.h
include/dai/gibbs.h
include/dai/hak.h
include/dai/jtree.h
include/dai/lc.h
include/dai/mf.h
include/dai/mr.h
include/dai/treeep.h
include/dai/trwbp.h
src/alldai.cpp

index 3a809ce..5bf27c3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* Added builtinInfAlgs() and builtinInfAlgNames()
 * Now uses GMP big integer type to represent linear states and the number of
   states of VarSets (in some cases). This fixes a bug Jerome Maye found in the 
   State() class in index.h. Unfortunately, the supplied Makefile.WINDOWS now
index 061ddb2..cada3e5 100644 (file)
@@ -27,6 +27,9 @@ int main( int argc, char *argv[] ) {
         cout << "total number of states less than <maxstates> (where 0 means unlimited)." << endl << endl;
         return 1;
     } else {
+        // Report inference algorithms built into libDAI
+        cout << "Builtin inference algorithms: " << builtinInfAlgNames() << endl << endl;
+
         // Read FactorGraph from the file specified by the first command line argument
         FactorGraph fg;
         fg.ReadFromFile(argv[1]);
index f7750b0..f7bcb89 100644 (file)
 namespace dai {
 
 
+/// Returns a map that contains for each built-in inference algorithm its name and a pointer to an object of that type
+std::map<std::string, InfAlg *>& builtinInfAlgs();
+
+
+/// Returns a set of names of all available inference algorithms
+/*  These are the names of the algorithms that were compiled in and can be 
+ *  given to \ref newInfAlg and \ref newInfAlgFromString.  
+ *  \return A set of strings, each one corresponding with the name of an available inference algorithm.
+ *  \note The set is returned by value because it will be reasonably small 
+ *  enough and this function is expected to be called infrequently.
+ */
+std::set<std::string> builtinInfAlgNames();
+
+
 /// Constructs a new inference algorithm.
 /** \param name The name of the inference algorithm.
  *  \param fg The FactorGraph that the algorithm should be applied to.
index 8c0a7b2..0769fc3 100644 (file)
@@ -184,6 +184,7 @@ class BP : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual BP* clone() const { return new BP(*this); }
+        virtual BP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new BP( fg, opts ); }
         virtual std::string name() const { return "BP"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &vs ) const;
index 054e369..ccc53ef 100644 (file)
@@ -73,6 +73,7 @@ class CBP : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual CBP* clone() const { return new CBP(*this); }
+        virtual CBP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new CBP( fg, opts ); }
         virtual std::string name() const { return "CBP"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet & ) const { DAI_THROW(NOT_IMPLEMENTED); }
index 703de27..975084c 100644 (file)
@@ -40,6 +40,12 @@ class InfAlg {
 
         /// Returns a pointer to a new, cloned copy of \c *this (i.e., virtual copy constructor)
         virtual InfAlg* clone() const = 0;
+
+        /// Returns a pointer to a newly constructed inference algorithm
+        /** \param fg Factor graph on which to perform the inference algorithm;
+         *  \param opts Parameters passed to constructor of inference algorithm;
+         */
+        virtual InfAlg* construct( const FactorGraph &fg, const PropertySet &opts ) const = 0;
     //@}
 
     /// \name Queries
index ba0a36c..7f7a671 100644 (file)
@@ -66,6 +66,7 @@ class DecMAP : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual DecMAP* clone() const { return new DecMAP(*this); }
+        virtual DecMAP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new DecMAP( fg, opts ); }
         virtual std::string name() const { return "DECMAP"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &/*vs*/ ) const;
index 5b6cfe2..764d787 100644 (file)
@@ -64,6 +64,7 @@ class ExactInf : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual ExactInf* clone() const { return new ExactInf(*this); }
+        virtual ExactInf* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new ExactInf( fg, opts ); }
         virtual std::string name() const { return "EXACT"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &vs ) const;
index 51600a2..3a237cc 100644 (file)
@@ -76,6 +76,7 @@ class FBP : public BP {
     /// \name General InfAlg interface
     //@{
         virtual FBP* clone() const { return new FBP(*this); }
+        virtual FBP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new FBP( fg, opts ); }
         virtual std::string name() const { return "FBP"; }
         virtual Real logZ() const;
     //@}
index f9149bf..4f5b633 100644 (file)
@@ -82,6 +82,7 @@ class Gibbs : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual Gibbs* clone() const { return new Gibbs(*this); }
+        virtual Gibbs* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new Gibbs( fg, opts ); }
         virtual std::string name() const { return "GIBBS"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &vs ) const;
index e0c2a8f..b62a8f8 100644 (file)
@@ -107,6 +107,7 @@ class HAK : public DAIAlgRG {
     /// \name General InfAlg interface
     //@{
         virtual HAK* clone() const { return new HAK(*this); }
+        virtual HAK* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new HAK( fg, opts ); }
         virtual std::string name() const { return "HAK"; }
         virtual Factor belief( const VarSet &vs ) const;
         virtual std::vector<Factor> beliefs() const;
index d52d05b..b7041e2 100644 (file)
@@ -118,6 +118,7 @@ class JTree : public DAIAlgRG {
     /// \name General InfAlg interface
     //@{
         virtual JTree* clone() const { return new JTree(*this); }
+        virtual JTree* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new JTree( fg, opts ); }
         virtual std::string name() const { return "JTREE"; }
         virtual Factor belief( const VarSet &vs ) const;
         virtual std::vector<Factor> beliefs() const;
index 0d8a262..56d04bc 100644 (file)
@@ -102,6 +102,7 @@ class LC : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual LC* clone() const { return new LC(*this); }
+        virtual LC* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new LC( fg, opts ); }
         virtual std::string name() const { return "LC"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &/*vs*/ ) const;
index 05db054..47ef3ea 100644 (file)
@@ -90,6 +90,7 @@ class MF : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual MF* clone() const { return new MF(*this); }
+        virtual MF* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new MF( fg, opts ); }
         virtual std::string name() const { return "MF"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &vs ) const;
index 62bb955..c8bfc80 100644 (file)
@@ -108,6 +108,7 @@ class MR : public DAIAlgFG {
     /// \name General InfAlg interface
     //@{
         virtual MR* clone() const { return new MR(*this); }
+        virtual MR* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new MR( fg, opts ); }
         virtual std::string name() const { return "MR"; }
         virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); }
         virtual Factor belief( const VarSet &/*vs*/ ) const;
index 3a9ea5a..a2e73ce 100644 (file)
@@ -179,6 +179,7 @@ class TreeEP : public JTree {
     /// \name General InfAlg interface
     //@{
         virtual TreeEP* clone() const { return new TreeEP(*this); }
+        virtual TreeEP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new TreeEP( fg, opts ); }
         virtual std::string name() const { return "TREEEP"; }
         virtual Real logZ() const;
         virtual void init();
index d49dd8b..c579417 100644 (file)
@@ -84,6 +84,7 @@ class TRWBP : public BP {
     /// \name General InfAlg interface
     //@{
         virtual TRWBP* clone() const { return new TRWBP(*this); }
+        virtual TRWBP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new TRWBP( fg, opts ); }
         virtual std::string name() const { return "TRWBP"; }
         virtual Real logZ() const;
         virtual void setProperties( const PropertySet &opts );
index 10521c7..a2cd40c 100644 (file)
@@ -19,58 +19,70 @@ namespace dai {
 using namespace std;
 
 
-InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts ) {
-    if( name == ExactInf().name() )
-        return new ExactInf (fg, opts);
+std::map<std::string, InfAlg *>& builtinInfAlgs() {
+    // use Construct On First Use idiom
+    // see also http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14
+
+    class _builtinInfAlgs : public std::map<std::string, InfAlg *> { public: _builtinInfAlgs() {
+        operator[]( ExactInf().name() ) = new ExactInf;
 #ifdef DAI_WITH_BP
-    if( name == BP().name() )
-        return new BP (fg, opts);
+        operator[]( BP().name() ) = new BP;
 #endif
 #ifdef DAI_WITH_FBP
-    if( name == FBP().name() )
-        return new FBP (fg, opts);
+        operator[]( FBP().name() ) = new FBP;
 #endif
 #ifdef DAI_WITH_TRWBP
-    if( name == TRWBP().name() )
-        return new TRWBP (fg, opts);
+        operator[]( TRWBP().name() ) = new TRWBP;
 #endif
 #ifdef DAI_WITH_MF
-    if( name == MF().name() )
-        return new MF (fg, opts);
+        operator[]( MF().name() ) = new MF;
 #endif
 #ifdef DAI_WITH_HAK
-    if( name == HAK().name() )
-        return new HAK (fg, opts);
+        operator[]( HAK().name() ) = new HAK;
 #endif
 #ifdef DAI_WITH_LC
-    if( name == LC().name() )
-        return new LC (fg, opts);
+        operator[]( LC().name() ) = new LC;
 #endif
 #ifdef DAI_WITH_TREEEP
-    if( name == TreeEP().name() )
-        return new TreeEP (fg, opts);
+        operator[]( TreeEP().name() ) = new TreeEP;
 #endif
 #ifdef DAI_WITH_JTREE
-    if( name == JTree().name() )
-        return new JTree (fg, opts);
+        operator[]( JTree().name() ) = new JTree;
 #endif
 #ifdef DAI_WITH_MR
-    if( name == MR().name() )
-        return new MR (fg, opts);
+        operator[]( MR().name() ) = new MR;
 #endif
 #ifdef DAI_WITH_GIBBS
-    if( name == Gibbs().name() )
-        return new Gibbs (fg, opts);
+        operator[]( Gibbs().name() ) = new Gibbs;
 #endif
 #ifdef DAI_WITH_CBP
-    if( name == CBP().name() )
-        return new CBP (fg, opts);
+        operator[]( CBP().name() ) = new CBP;
 #endif
 #ifdef DAI_WITH_DECMAP
-    if( name == DecMAP().name() )
-        return new DecMAP (fg, opts);
+        operator[]( DecMAP().name() ) = new DecMAP;
 #endif
-    DAI_THROWE(UNKNOWN_DAI_ALGORITHM,"Unknown libDAI algorithm: " + name);
+    } };
+
+    static std::map<std::string, InfAlg *>* bia = new _builtinInfAlgs;
+
+    return *bia;
+}
+
+
+std::set<std::string> builtinInfAlgNames() {
+    std::set<std::string> algNames;
+    for( typename std::map<std::string, InfAlg*>::const_iterator it = builtinInfAlgs().begin(); it != builtinInfAlgs().end(); it++ )
+        algNames.insert( it->first );
+    return algNames;
+}
+
+
+InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts ) {
+    std::map<std::string, InfAlg*>::const_iterator i = builtinInfAlgs().find( name );
+    if( i == builtinInfAlgs().end() )
+        DAI_THROWE(UNKNOWN_DAI_ALGORITHM, "Unknown inference algorithm: " + name);
+    InfAlg *ia = i->second;
+    return ia->construct( fg, opts );
 }