double tol = 1e-9;
size_t verb = 1;
- Properties opts;
+ PropertySet opts;
opts.Set("maxiter",maxiter);
opts.Set("tol",tol);
opts.Set("verbose",verb);
#include <string>
#include <dai/daialg.h>
+#include <dai/properties.h>
#ifdef WITH_BP
#include <dai/bp.h>
#endif
/// newInfAlg constructs a new approximate inference algorithm named name for the
/// FactorGraph fg with optionts opts and returns a pointer to the new object.
/// The caller needs to delete it (maybe some sort of smart_ptr might be useful here).
-InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const Properties &opts );
+InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts );
/// DAINames contains the names of all approximate inference algorithms
#include <string>
#include <dai/daialg.h>
#include <dai/factorgraph.h>
+#include <dai/properties.h>
#include <dai/enum.h>
Prob newMessage;
double residual;
};
-
std::vector<std::vector<EdgeProp> > edges;
- bool logDomain;
-
+
public:
- ENUM4(UpdateType,SEQFIX,SEQRND,SEQMAX,PARALL)
- UpdateType Updates() const { return GetPropertyAs<UpdateType>("updates"); }
+ struct Properties {
+ size_t verbose;
+ size_t maxiter;
+ double tol;
+ bool logdomain;
+ ENUM4(UpdateType,SEQFIX,SEQRND,SEQMAX,PARALL)
+ UpdateType updates;
+ } props;
+ double maxdiff;
- // default constructor
- BP() : DAIAlgFG(), edges(), logDomain(false) {};
- // copy constructor
- BP(const BP & x) : DAIAlgFG(x), edges(x.edges), logDomain(x.logDomain) {};
+ public:
+ /// Default constructor
+ BP() : DAIAlgFG(), edges(), props(), maxdiff(0.0) {};
+ /// Copy constructor
+ BP( const BP & x ) : DAIAlgFG(x), edges(x.edges), props(x.props), maxdiff(x.maxdiff) {};
+ /// Clone *this
BP* clone() const { return new BP(*this); }
- // construct BP object from FactorGraph
- BP(const FactorGraph & fg, const Properties &opts) : DAIAlgFG(fg, opts), edges(), logDomain(false) {
- assert( checkProperties() );
+ /// Construct from FactorGraph fg and PropertySet opts
+ BP( const FactorGraph & fg, const PropertySet &opts ) : DAIAlgFG(fg), edges(), props(), maxdiff(0.0) {
+ setProperties( opts );
create();
}
- // assignment operator
- BP & operator=(const BP & x) {
- if(this!=&x) {
- DAIAlgFG::operator=(x);
+ /// Assignment operator
+ BP& operator=( const BP & x ) {
+ if( this != &x ) {
+ DAIAlgFG::operator=( x );
edges = x.edges;
- logDomain = x.logDomain;
+ props = x.props;
+ maxdiff = x.maxdiff;
}
return *this;
}
const ind_t & index(size_t i, size_t _I) const { return edges[i][_I].index; }
double & residual(size_t i, size_t _I) { return edges[i][_I].residual; }
const double & residual(size_t i, size_t _I) const { return edges[i][_I].residual; }
- void findMaxResidual( size_t &i, size_t &_I );
std::string identify() const;
void create();
void init();
- void calcNewMessage( size_t i, size_t _I );
double run();
+
+ void findMaxResidual( size_t &i, size_t &_I );
+ void calcNewMessage( size_t i, size_t _I );
Factor beliefV (size_t i) const;
Factor beliefF (size_t I) const;
Factor belief (const Var &n) const;
void init( const VarSet &ns );
void undoProbs( const VarSet &ns ) { FactorGraph::undoProbs(ns); init(ns); }
- bool checkProperties();
+
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
};
#include <vector>
#include <dai/factorgraph.h>
#include <dai/regiongraph.h>
-#include <dai/properties.h>
namespace dai {
/// A InfAlg object represents a discrete factorized probability distribution over multiple variables
/// together with an inference algorithm.
class InfAlg {
- private:
- /// Properties of the algorithm (replaces _tol, _maxiter, _verbose)
- Properties _properties;
-
- /// Maximum difference encountered so far
- double _maxdiff;
-
-
public:
- /// Default constructor
- InfAlg() : _properties(), _maxdiff(0.0) {}
-
- /// Constructor with options
- InfAlg( const Properties &opts ) : _properties(opts), _maxdiff(0.0) {}
-
- /// Copy constructor
- InfAlg( const InfAlg & x ) : _properties(x._properties), _maxdiff(x._maxdiff) {}
-
/// Clone (virtual copy constructor)
virtual InfAlg* clone() const = 0;
- /// Assignment operator
- InfAlg & operator=( const InfAlg & x ) {
- if( this != &x ) {
- _properties = x._properties;
- _maxdiff = x._maxdiff;
- }
- return *this;
- }
-
/// Virtual desctructor
// (this is needed because this class contains virtual functions)
virtual ~InfAlg() {}
- /// Returns true if a property with the given key is present
- bool HasProperty(const PropertyKey &key) const { return _properties.hasKey(key); }
-
- /// Gets a property
- const PropertyValue & GetProperty(const PropertyKey &key) const { return _properties.Get(key); }
-
- /// Gets a property, casted as ValueType
- template<typename ValueType>
- ValueType GetPropertyAs(const PropertyKey &key) const { return _properties.GetAs<ValueType>(key); }
-
- /// Sets a property
- void SetProperty(const PropertyKey &key, const PropertyValue &val) { _properties[key] = val; }
-
- /// Converts a property from string to ValueType, if necessary
- template<typename ValueType>
- void ConvertPropertyTo(const PropertyKey &key) { _properties.ConvertTo<ValueType>(key); }
-
- /// Gets all properties
- const Properties & GetProperties() const { return _properties; }
-
- /// Sets properties
- void SetProperties(const Properties &p) { _properties = p; }
-
- /// Sets tolerance
- void Tol( double tol ) { SetProperty("tol", tol); }
- /// Gets tolerance
- double Tol() const { return GetPropertyAs<double>("tol"); }
-
- /// Sets maximum number of iterations
- void MaxIter( size_t maxiter ) { SetProperty("maxiter", maxiter); }
- /// Gets maximum number of iterations
- size_t MaxIter() const { return GetPropertyAs<size_t>("maxiter"); }
-
- /// Sets verbosity
- void Verbose( size_t verbose ) { SetProperty("verbose", verbose); }
- /// Gets verbosity
- size_t Verbose() const { return GetPropertyAs<size_t>("verbose"); }
-
- /// Sets maximum difference encountered so far
- void MaxDiff( double maxdiff ) { _maxdiff = maxdiff; }
- /// Gets maximum difference encountered so far
- double MaxDiff() const { return _maxdiff; }
- /// Updates maximum difference encountered so far
- void updateMaxDiff( double maxdiff ) { if( maxdiff > _maxdiff ) _maxdiff = maxdiff; }
- /// Sets maximum difference encountered so far to zero
- void clearMaxDiff() { _maxdiff = 0.0; }
-
/// Identifies itself for logging purposes
virtual std::string identify() const = 0;
/// Factor I has been updated
virtual void updatedFactor( size_t I ) = 0;
- /// Checks whether all necessary properties have been set
- /// and casts string-valued properties to other values if necessary
- virtual bool checkProperties() = 0;
+ /// Return maximum difference between beliefs in the last pass
+ virtual double maxDiff() const = 0;
};
/// Default constructor
DAIAlg() : InfAlg(), T() {}
- /// Construct DAIAlg with empty T but using the specified properties
- DAIAlg( const Properties &opts ) : InfAlg( opts ), T() {}
+ /// Construct from T
+ DAIAlg( const T &t ) : InfAlg(), T(t) {}
- /// Construct DAIAlg using the specified properties
- DAIAlg( const T & t, const Properties &opts ) : InfAlg( opts ), T(t) {}
-
/// Copy constructor
DAIAlg( const DAIAlg & x ) : InfAlg(x), T(x) {}
#include <dai/daialg.h>
#include <dai/regiongraph.h>
#include <dai/enum.h>
+#include <dai/properties.h>
namespace dai {
std::vector<Factor> _Qb;
std::vector<std::vector<Factor> > _muab;
std::vector<std::vector<Factor> > _muba;
+
+ public:
+ struct Properties {
+ size_t verbose;
+ size_t maxiter;
+ double tol;
+ ENUM3(ClustersType,MIN,DELTA,LOOP)
+ ClustersType clusters;
+ bool doubleloop;
+ size_t loopdepth;
+ } props;
+ double maxdiff;
public:
/// Default constructor
- HAK() : DAIAlgRG() {};
+ HAK() : DAIAlgRG(), _Qa(), _Qb(), _muab(), _muba(), props(), maxdiff() {}
/// Copy constructor
- HAK(const HAK & x) : DAIAlgRG(x), _Qa(x._Qa), _Qb(x._Qb), _muab(x._muab), _muba(x._muba) {};
+ HAK(const HAK & x) : DAIAlgRG(x), _Qa(x._Qa), _Qb(x._Qb), _muab(x._muab), _muba(x._muba), props(x.props), maxdiff(x.maxdiff) {}
/// Clone function
HAK* clone() const { return new HAK(*this); }
/// Construct from RegionGraph
- HAK(const RegionGraph & rg, const Properties &opts);
+ HAK(const RegionGraph & rg, const PropertySet &opts);
/// Construct from RactorGraph using "clusters" option
- HAK(const FactorGraph & fg, const Properties &opts);
+ HAK(const FactorGraph & fg, const PropertySet &opts);
/// Assignment operator
HAK & operator=(const HAK & x) {
if( this != &x ) {
DAIAlgRG::operator=(x);
- _Qa = x._Qa;
- _Qb = x._Qb;
- _muab = x._muab;
- _muba = x._muba;
+ _Qa = x._Qa;
+ _Qb = x._Qb;
+ _muab = x._muab;
+ _muba = x._muba;
+ props = x.props;
+ maxdiff = x.maxdiff;
}
return *this;
}
static const char *Name;
- ENUM3(ClustersType,MIN,DELTA,LOOP)
- ClustersType Clusters() const { return GetPropertyAs<ClustersType>("clusters"); }
- bool DoubleLoop() { return GetPropertyAs<bool>("doubleloop"); }
- size_t LoopDepth() { return GetPropertyAs<size_t>("loopdepth"); }
-
Factor & muab( size_t alpha, size_t _beta ) { return _muab[alpha][_beta]; }
Factor & muba( size_t alpha, size_t _beta ) { return _muba[alpha][_beta]; }
const Factor& Qa( size_t alpha ) const { return _Qa[alpha]; };
void init( const VarSet &ns );
void undoProbs( const VarSet &ns ) { RegionGraph::undoProbs( ns ); init( ns ); }
- bool checkProperties();
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
private:
void constructMessages();
#include <dai/clustergraph.h>
#include <dai/weightedgraph.h>
#include <dai/enum.h>
+#include <dai/properties.h>
namespace dai {
std::vector<std::vector<Factor> > _mes;
double _logZ;
-
public:
- ENUM2(UpdateType,HUGIN,SHSH)
- UpdateType Updates() const { return GetPropertyAs<UpdateType>("updates"); }
+ struct Properties {
+ size_t verbose;
+ ENUM2(UpdateType,HUGIN,SHSH)
+ UpdateType updates;
+ } props;
- JTree() : DAIAlgRG(), _RTree(), _Qa(), _Qb(), _mes(), _logZ() {};
- JTree( const JTree& x ) : DAIAlgRG(x), _RTree(x._RTree), _Qa(x._Qa), _Qb(x._Qb), _mes(x._mes), _logZ(x._logZ) {};
+ public:
+ JTree() : DAIAlgRG(), _RTree(), _Qa(), _Qb(), _mes(), _logZ(), props() {}
+ JTree( const JTree& x ) : DAIAlgRG(x), _RTree(x._RTree), _Qa(x._Qa), _Qb(x._Qb), _mes(x._mes), _logZ(x._logZ), props(x.props) {}
JTree* clone() const { return new JTree(*this); }
JTree & operator=( const JTree& x ) {
if( this != &x ) {
_Qb = x._Qb;
_mes = x._mes;
_logZ = x._logZ;
+ props = x.props;
}
return *this;
}
- JTree( const FactorGraph &fg, const Properties &opts, bool automatic=true );
+ JTree( const FactorGraph &fg, const PropertySet &opts, bool automatic=true );
void GenerateJT( const std::vector<VarSet> &Cliques );
Factor & message( size_t alpha, size_t _beta ) { return _mes[alpha][_beta]; }
static const char *Name;
std::string identify() const;
- void init() { assert( checkProperties() ); }
+ void init() {}
void runHUGIN();
void runShaferShenoy();
double run();
size_t findEfficientTree( const VarSet& ns, DEdgeVec &Tree, size_t PreviousRoot=(size_t)-1 ) const;
Factor calcMarginal( const VarSet& ns );
- bool checkProperties();
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return 0.0; }
};
#include <dai/daialg.h>
#include <dai/enum.h>
#include <dai/factorgraph.h>
+#include <dai/properties.h>
namespace dai {
std::vector<Factor> _beliefs;
public:
- ENUM6(CavityType,FULL,PAIR,PAIR2,PAIRINT,PAIRCUM,UNIFORM)
- ENUM3(UpdateType,SEQFIX,SEQRND,NONE)
+ struct Properties {
+ size_t verbose;
+ size_t maxiter;
+ double tol;
+ ENUM6(CavityType,FULL,PAIR,PAIR2,PAIRINT,PAIRCUM,UNIFORM)
+ CavityType cavity;
+ ENUM3(UpdateType,SEQFIX,SEQRND,NONE)
+ UpdateType updates;
+ std::string cavainame;
+ PropertySet cavaiopts;
+ bool reinit;
+ } props;
+ double maxdiff;
- CavityType Cavity() const { return GetPropertyAs<CavityType>("cavity"); }
- UpdateType Updates() const { return GetPropertyAs<UpdateType>("updates"); }
- bool reInit() const { return GetPropertyAs<bool>("reinit"); }
-
+ public:
/// Default constructor
- LC() : DAIAlgFG() {};
+ LC() : DAIAlgFG(), _pancakes(), _cavitydists(), _phis(), _beliefs(), props(), maxdiff() {}
/// Copy constructor
- LC(const LC & x) : DAIAlgFG(x), _pancakes(x._pancakes), _cavitydists(x._cavitydists), _phis(x._phis), _beliefs(x._beliefs) {};
+ LC(const LC & x) : DAIAlgFG(x), _pancakes(x._pancakes), _cavitydists(x._cavitydists), _phis(x._phis), _beliefs(x._beliefs), props(x.props), maxdiff(x.maxdiff) {}
/// Clone function
LC* clone() const { return new LC(*this); }
/// Construct LC object from a FactorGraph and parameters
- LC(const FactorGraph & fg, const Properties &opts);
+ LC( const FactorGraph & fg, const PropertySet &opts );
/// Assignment operator
LC& operator=(const LC & x) {
if( this != &x ) {
_cavitydists = x._cavitydists;
_phis = x._phis;
_beliefs = x._beliefs;
+ props = x.props;
+ maxdiff = x.maxdiff;
}
return *this;
}
static const char *Name;
- double CalcCavityDist( size_t i, const std::string &name, const Properties &opts );
- double InitCavityDists( const std::string &name, const Properties &opts );
+ double CalcCavityDist( size_t i, const std::string &name, const PropertySet &opts );
+ double InitCavityDists( const std::string &name, const PropertySet &opts );
long SetCavityDists( std::vector<Factor> &Q );
void init();
std::vector<Factor> beliefs() const { return _beliefs; }
Complex logZ() const { return NAN; }
void CalcBelief (size_t i);
- const Factor & belief (size_t i) const { return _beliefs[i]; };
- const Factor & pancake (size_t i) const { return _pancakes[i]; };
- const Factor & cavitydist (size_t i) const { return _cavitydists[i]; };
+ const Factor &belief (size_t i) const { return _beliefs[i]; };
+ const Factor &pancake (size_t i) const { return _pancakes[i]; };
+ const Factor &cavitydist (size_t i) const { return _cavitydists[i]; };
void clamp( const Var &/*n*/, size_t /*i*/ ) { assert( 0 == 1 ); }
void undoProbs( const VarSet &/*ns*/ ) { assert( 0 == 1 ); }
void saveProbs( const VarSet &/*ns*/ ) { assert( 0 == 1 ); }
virtual void makeCavity(const Var & /*n*/) { assert( 0 == 1 ); }
- bool checkProperties();
+
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
};
#include <string>
#include <dai/daialg.h>
#include <dai/factorgraph.h>
+#include <dai/properties.h>
namespace dai {
class MF : public DAIAlgFG {
protected:
std::vector<Factor> _beliefs;
+
+ public:
+ struct Properties {
+ size_t verbose;
+ size_t maxiter;
+ double tol;
+ } props;
+ double maxdiff;
public:
// default constructor
- MF() : DAIAlgFG(), _beliefs() {};
+ MF() : DAIAlgFG(), _beliefs(), props(), maxdiff(0.0) {}
// copy constructor
- MF(const MF & x) : DAIAlgFG(x), _beliefs(x._beliefs) {};
+ MF( const MF& x ) : DAIAlgFG(x), _beliefs(x._beliefs), props(x.props), maxdiff(x.maxdiff) {}
MF* clone() const { return new MF(*this); }
// construct MF object from FactorGraph
- MF(const FactorGraph & fg, const Properties &opts) : DAIAlgFG(fg, opts) {
- assert( checkProperties() );
+ MF( const FactorGraph & fg, const PropertySet &opts ) : DAIAlgFG(fg), _beliefs(), props(), maxdiff(0.0) {
+ setProperties( opts );
create();
}
// assignment operator
- MF & operator=(const MF & x) {
- if(this!=&x) {
- DAIAlgFG::operator=(x);
+ MF& operator=( const MF &x ) {
+ if( this != &x ) {
+ DAIAlgFG::operator=( x );
_beliefs = x._beliefs;
+ props = x.props;
+ maxdiff = x.maxdiff;
}
return *this;
}
void init( const VarSet &ns );
void undoProbs( const VarSet &ns ) { FactorGraph::undoProbs(ns); init(ns); }
- bool checkProperties();
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
};
#include <dai/factorgraph.h>
#include <dai/daialg.h>
#include <dai/enum.h>
+#include <dai/properties.h>
namespace dai {
std::vector<double> Mag;
public:
- ENUM2(UpdateType,FULL,LINEAR)
- ENUM3(InitType,RESPPROP,CLAMPING,EXACT)
+ struct Properties {
+ size_t verbose;
+ double tol;
+ ENUM2(UpdateType,FULL,LINEAR)
+ ENUM3(InitType,RESPPROP,CLAMPING,EXACT)
+ UpdateType updates;
+ InitType inits;
+ } props;
+ double maxdiff;
- UpdateType Updates() const { return GetPropertyAs<UpdateType>("updates"); }
- InitType Inits() const { return GetPropertyAs<InitType>("inits"); }
-
- MR( const FactorGraph & fg, const Properties &opts );
+ public:
+ MR( const FactorGraph & fg, const PropertySet &opts );
void init(size_t Nin, double *_w, double *_th);
void makekindex();
void read_files();
Factor belief( const VarSet &/*ns*/ ) const { assert( 0 == 1 ); }
std::vector<Factor> beliefs() const;
Complex logZ() const { return NAN; }
- void init() { assert( checkProperties() ); }
+ void init() {}
static const char *Name;
std::string identify() const;
double _tJ(size_t i, sub_nb A);
double sign(double a) { return (a >= 0) ? 1.0 : -1.0; }
MR* clone() const { assert( 0 == 1 ); }
- bool checkProperties();
-
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
};
std::ostream& operator<< (std::ostream & os, const Property & p);
-/// The Properties class represents a set of properties
-class Properties : public std::map<PropertyKey, PropertyValue> {
+/// The PropertySet class represents a set of properties
+class PropertySet : public std::map<PropertyKey, PropertyValue> {
public:
/// Gets a property
const PropertyValue & Get(const PropertyKey &key) const {
- Properties::const_iterator x = find(key);
+ PropertySet::const_iterator x = find(key);
#ifdef DAI_DEBUG
if( x == this->end() )
std::cerr << "Get cannot find property " << key << std::endl;
}
/// Sets a property
- Properties & Set(const PropertyKey &key, const PropertyValue &val) { this->operator[](key) = val; return *this; }
+ PropertySet & Set(const PropertyKey &key, const PropertyValue &val) { this->operator[](key) = val; return *this; }
/// Gets a property, casted as ValueType
template<typename ValueType>
}
}
- /// Shorthand for (temporarily) adding properties, e.g. Properties p()("method","BP")("verbose",1)("tol",1e-9)
- Properties operator()(const PropertyKey &key, const PropertyValue &val) const { Properties copy = *this; return copy.Set(key,val); }
+ /// Converts a property from string to ValueType, if necessary
+ template<typename ValueType>
+ ValueType getStringAs(const PropertyKey &key) const {
+ PropertyValue val = Get(key);
+ if( val.type() == typeid(std::string) ) {
+ std::stringstream ss;
+ ss << GetAs<std::string>(key);
+ ValueType result;
+ ss >> result;
+ return result;
+ } else if( val.type() == typeid(ValueType) ) {
+ return boost::any_cast<ValueType>(val);
+ } else
+ assert( 0 == 1 );
+ }
+
+ /// Shorthand for (temporarily) adding properties, e.g. 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); }
/// Check if a property with given key exists
- bool hasKey(const PropertyKey &key) const { Properties::const_iterator x = find(key); return (x != this->end()); }
+ bool hasKey(const PropertyKey &key) const { PropertySet::const_iterator x = find(key); return (x != this->end()); }
- /// Sends a Properties object to an output stream
- friend std::ostream& operator<< (std::ostream & os, const Properties & ps);
+ /// Sends a PropertySet object to an output stream
+ friend std::ostream& operator<< (std::ostream & os, const PropertySet & ps);
- /// Reads a Properties object from an input stream
- friend std::istream& operator >> (std::istream& is, Properties & ps);
+ /// Reads a PropertySet object from an input stream
+ friend std::istream& operator >> (std::istream& is, PropertySet & ps);
};
#include <dai/clustergraph.h>
#include <dai/weightedgraph.h>
#include <dai/jtree.h>
+#include <dai/properties.h>
#include <dai/enum.h>
std::map<size_t, TreeEPSubTree> _Q;
public:
- ENUM2(TypeType,ORG,ALT)
- TypeType Type() const { return GetPropertyAs<TypeType>("type"); }
-
- TreeEP() : JTree(), _Q() {};
- TreeEP( const TreeEP& x ) : JTree(x), _Q(x._Q) {
+ struct Properties {
+ size_t verbose;
+ size_t maxiter;
+ double tol;
+ ENUM2(TypeType,ORG,ALT)
+ TypeType type;
+ } props;
+ double maxdiff;
+
+ public:
+ /// Default constructor
+ TreeEP() : JTree(), _Q(), props(), maxdiff() {};
+ /// Copy constructor
+ TreeEP( const TreeEP& x ) : JTree(x), _Q(x._Q), props(x.props), maxdiff(x.maxdiff) {
for( size_t I = 0; I < nrFactors(); I++ )
if( offtree( I ) )
_Q[I].I() = &factor(I);
for( size_t I = 0; I < nrFactors(); I++ )
if( offtree( I ) )
_Q[I].I() = &factor(I);
+ props = x.props;
+ maxdiff = x.maxdiff;
}
return *this;
}
- TreeEP( const FactorGraph &fg, const Properties &opts );
+ TreeEP( const FactorGraph &fg, const PropertySet &opts );
void ConstructRG( const DEdgeVec &tree );
static const char *Name;
void init( const VarSet &/*ns*/ ) { init(); }
void undoProbs( const VarSet &ns ) { RegionGraph::undoProbs( ns ); init( ns ); }
- bool checkProperties();
+
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ double maxDiff() const { return maxdiff; }
};
#include <string>
#include <dai/alldai.h>
+#include <dai/properties.h>
namespace dai {
using namespace std;
-InfAlg *newInfAlg( const string &name, const FactorGraph &fg, const Properties &opts ) {
+InfAlg *newInfAlg( const string &name, const FactorGraph &fg, const PropertySet &opts ) {
#ifdef WITH_BP
if( name == BP::Name )
return new BP (fg, opts);
#endif
#ifdef WITH_MF
- else if( name == MF::Name )
+ if( name == MF::Name )
return new MF (fg, opts);
#endif
#ifdef WITH_HAK
- else if( name == HAK::Name )
+ if( name == HAK::Name )
return new HAK (fg, opts);
#endif
#ifdef WITH_LC
- else if( name == LC::Name )
+ if( name == LC::Name )
return new LC (fg, opts);
#endif
#ifdef WITH_TREEEP
- else if( name == TreeEP::Name )
+ if( name == TreeEP::Name )
return new TreeEP (fg, opts);
#endif
#ifdef WITH_JTREE
- else if( name == JTree::Name )
+ if( name == JTree::Name )
return new JTree (fg, opts);
#endif
#ifdef WITH_MR
- else if( name == MR::Name )
+ if( name == MR::Name )
return new MR (fg, opts);
#endif
- else
- throw "Unknown inference algorithm";
+ throw "Unknown inference algorithm";
}
const char *BP::Name = "BP";
-bool BP::checkProperties() {
- if( !HasProperty("updates") )
- return false;
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
- if (!HasProperty("logdomain") )
- return false;
+void BP::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("logdomain") );
+ assert( opts.hasKey("updates") );
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
- ConvertPropertyTo<UpdateType>("updates");
- ConvertPropertyTo<bool>("logdomain");
- logDomain = GetPropertyAs<bool>("logdomain");
-
- return true;
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.logdomain = opts.getStringAs<bool>("logdomain");
+ props.updates = opts.getStringAs<Properties::UpdateType>("updates");
+}
+
+
+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 );
+ return opts;
}
void BP::init() {
- assert( checkProperties() );
for( size_t i = 0; i < nrVars(); ++i ) {
foreach( const Neighbor &I, nbV(i) ) {
- if( logDomain ) {
+ if( props.logdomain ) {
message( i, I.iter ).fill( 0.0 );
newMessage( i, I.iter ).fill( 0.0 );
} else {
*/
Prob prod( factor(I).p() );
- if( logDomain )
+ if( props.logdomain )
prod.takeLog();
// Calculate product of incoming messages and factor I
const ind_t & ind = index(j, _I);
// prod_j will be the product of messages coming into j
- Prob prod_j( var(j).states(), logDomain ? 0.0 : 1.0 );
+ Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 );
foreach( const Neighbor &J, nbV(j) )
if( J != I ) { // for all J in nb(j) \ I
- if( logDomain )
+ if( props.logdomain )
prod_j += message( j, J.iter );
else
prod_j *= message( j, J.iter );
// multiply prod with prod_j
for( size_t r = 0; r < prod.size(); ++r )
- if( logDomain )
+ if( props.logdomain )
prod[r] += prod_j[ind[r]];
else
prod[r] *= prod_j[ind[r]];
}
}
- if( logDomain ) {
+ if( props.logdomain ) {
prod -= prod.maxVal();
prod.takeExp();
}
marg.normalize( _normtype );
// Store result
- if( logDomain )
+ if( props.logdomain )
newMessage(i,_I) = marg.log();
else
newMessage(i,_I) = marg;
// BP::run does not check for NANs for performance reasons
// Somehow NaNs do not often occur in BP...
double BP::run() {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
- if( Verbose() >= 3)
+ if( props.verbose >= 3)
cout << endl;
double tic = toc();
size_t iter = 0;
size_t nredges = nrEdges();
- if( Updates() == UpdateType::SEQMAX ) {
+ if( props.updates == Properties::UpdateType::SEQMAX ) {
// do the first pass
for( size_t i = 0; i < nrVars(); ++i )
foreach( const Neighbor &I, nbV(i) ) {
// do several passes over the network until maximum number of iterations has
// been reached or until the maximum belief difference is smaller than tolerance
- for( iter=0; iter < MaxIter() && diffs.maxDiff() > Tol(); ++iter ) {
- if( Updates() == UpdateType::SEQMAX ) {
+ for( iter=0; iter < props.maxiter && diffs.maxDiff() > props.tol; ++iter ) {
+ if( props.updates == Properties::UpdateType::SEQMAX ) {
// Residuals-BP by Koller et al.
for( size_t t = 0; t < nredges; ++t ) {
// update the message with the largest residual
}
}
}
- } else if( Updates() == UpdateType::PARALL ) {
+ } else if( props.updates == Properties::UpdateType::PARALL ) {
// Parallel updates
for( size_t i = 0; i < nrVars(); ++i )
foreach( const Neighbor &I, nbV(i) )
message( i, I.iter ) = newMessage( i, I.iter );
} else {
// Sequential updates
- if( Updates() == UpdateType::SEQRND )
+ if( props.updates == Properties::UpdateType::SEQRND )
random_shuffle( update_seq.begin(), update_seq.end() );
foreach( const Edge &e, update_seq ) {
old_beliefs[i] = nb;
}
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "BP::run: maxdiff " << diffs.maxDiff() << " after " << iter+1 << " passes" << endl;
}
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "BP::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << "BP::run: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "BP::run: ";
cout << "converged in " << iter << " passes (" << toc() - tic << " clocks)." << endl;
}
Factor BP::beliefV( size_t i ) const {
- Prob prod( var(i).states(), logDomain ? 0.0 : 1.0 );
+ Prob prod( var(i).states(), props.logdomain ? 0.0 : 1.0 );
foreach( const Neighbor &I, nbV(i) )
- if( logDomain )
+ if( props.logdomain )
prod += newMessage( i, I.iter );
else
prod *= newMessage( i, I.iter );
- if( logDomain ) {
+ if( props.logdomain ) {
prod -= prod.maxVal();
prod.takeExp();
}
Factor BP::beliefF (size_t I) const {
Prob prod( factor(I).p() );
- if( logDomain )
+ if( props.logdomain )
prod.takeLog();
foreach( const Neighbor &j, nbF(I) ) {
const ind_t & ind = index(j, _I);
// prod_j will be the product of messages coming into j
- Prob prod_j( var(j).states(), logDomain ? 0.0 : 1.0 );
+ Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 );
foreach( const Neighbor &J, nbV(j) ) {
if( J != I ) { // for all J in nb(j) \ I
- if( logDomain )
+ if( props.logdomain )
prod_j += newMessage( j, J.iter );
else
prod_j *= newMessage( j, J.iter );
// multiply prod with prod_j
for( size_t r = 0; r < prod.size(); ++r ) {
- if( logDomain )
+ if( props.logdomain )
prod[r] += prod_j[ind[r]];
else
prod[r] *= prod_j[ind[r]];
}
}
- if( logDomain ) {
+ if( props.logdomain ) {
prod -= prod.maxVal();
prod.takeExp();
}
string BP::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
for( VarSet::const_iterator n = ns.begin(); n != ns.end(); ++n ) {
size_t ni = findVar( *n );
foreach( const Neighbor &I, nbV( ni ) )
- message( ni, I.iter ).fill( logDomain ? 0.0 : 1.0 );
+ message( ni, I.iter ).fill( props.logdomain ? 0.0 : 1.0 );
}
}
clamped->clamp( *n, s(*n) );
// run DAIAlg, calc logZ, store in Pns
- if( clamped->Verbose() >= 2 )
- cout << s << ": ";
if( reInit )
clamped->init();
clamped->run();
for( size_t j = 0; j < N; j++ ) {
// clamp Var j to its possible values
for( size_t j_val = 0; j_val < vns[j].states(); j_val++ ) {
- if( obj.Verbose() >= 2 )
- cout << j << "/" << N-1 << " (" << j_val << "/" << vns[j].states() << "): ";
-
// save unclamped factors connected to ns
clamped->saveProbs( ns );
const char *HAK::Name = "HAK";
-bool HAK::checkProperties() {
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
- if( !HasProperty("doubleloop") )
- return false;
- if( !HasProperty("clusters") )
- return false;
+void HAK::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("doubleloop") );
+ assert( opts.hasKey("clusters") );
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
- ConvertPropertyTo<bool>("doubleloop");
- ConvertPropertyTo<ClustersType>("clusters");
-
- if( HasProperty("loopdepth") )
- ConvertPropertyTo<size_t>("loopdepth");
- else if( Clusters() == ClustersType::LOOP )
- return false;
-
- return true;
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.doubleloop = opts.getStringAs<bool>("doubleloop");
+ props.clusters = opts.getStringAs<Properties::ClustersType>("clusters");
+
+ if( opts.hasKey("loopdepth") )
+ props.loopdepth = opts.getStringAs<size_t>("loopdepth");
+ else
+ assert( props.clusters != Properties::ClustersType::LOOP );
+}
+
+
+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( "loopdepth", props.loopdepth );
+ return opts;
}
}
-HAK::HAK(const RegionGraph & rg, const Properties &opts) : DAIAlgRG(rg, opts) {
- assert( checkProperties() );
+HAK::HAK(const RegionGraph & rg, const PropertySet &opts ) : DAIAlgRG(rg) {
+ setProperties( opts );
constructMessages();
}
}
-HAK::HAK(const FactorGraph & fg, const Properties &opts) : DAIAlgRG(opts) {
- assert( checkProperties() );
+HAK::HAK(const FactorGraph & fg, const PropertySet &opts) : DAIAlgRG(), props(), maxdiff(0.0) {
+ setProperties( opts );
vector<VarSet> cl;
- if( Clusters() == ClustersType::MIN ) {
+ if( props.clusters == Properties::ClustersType::MIN ) {
cl = fg.Cliques();
- } else if( Clusters() == ClustersType::DELTA ) {
+ } else if( props.clusters == Properties::ClustersType::DELTA ) {
for( size_t i = 0; i < fg.nrVars(); i++ )
cl.push_back(fg.Delta(i));
- } else if( Clusters() == ClustersType::LOOP ) {
+ } else if( props.clusters == Properties::ClustersType::LOOP ) {
cl = fg.Cliques();
set<VarSet> scl;
for( size_t i0 = 0; i0 < fg.nrVars(); i0++ ) {
VarSet i0d = fg.delta(i0);
- if( LoopDepth() > 1 )
- findLoopClusters( fg, scl, fg.var(i0), fg.var(i0), LoopDepth() - 1, fg.delta(i0) );
+ if( props.loopdepth > 1 )
+ findLoopClusters( fg, scl, fg.var(i0), fg.var(i0), props.loopdepth - 1, fg.delta(i0) );
}
for( set<VarSet>::const_iterator c = scl.begin(); c != scl.end(); c++ )
cl.push_back(*c);
- if( Verbose() >= 3 ) {
+ if( props.verbose >= 3 ) {
cout << "HAK uses the following clusters: " << endl;
for( vector<VarSet>::const_iterator cli = cl.begin(); cli != cl.end(); cli++ )
cout << *cli << endl;
RegionGraph::operator=(rg);
constructMessages();
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "HAK regiongraph: " << *this << endl;
}
string HAK::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
void HAK::init() {
- assert( checkProperties() );
-
for( vector<Factor>::iterator alpha = _Qa.begin(); alpha != _Qa.end(); alpha++ )
alpha->fill( 1.0 / alpha->states() );
double HAK::doGBP() {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
- if( Verbose() >= 3)
+ if( props.verbose >= 3)
cout << endl;
double tic = toc();
size_t iter = 0;
// do several passes over the network until maximum number of iterations has
// been reached or until the maximum belief difference is smaller than tolerance
- for( iter = 0; iter < MaxIter() && diffs.maxDiff() > Tol(); iter++ ) {
+ for( iter = 0; iter < props.maxiter && diffs.maxDiff() > props.tol; iter++ ) {
for( size_t beta = 0; beta < nrIRs(); beta++ ) {
foreach( const Neighbor &alpha, nbIR(beta) ) {
size_t _beta = alpha.dual;
old_beliefs[i] = new_belief;
}
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "HAK::doGBP: maxdiff " << diffs.maxDiff() << " after " << iter+1 << " passes" << endl;
}
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "HAK::doGBP: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << "HAK::doGBP: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << "HAK::doGBP: ";
cout << "converged in " << iter << " passes (" << toc() - tic << " clocks)." << endl;
}
double HAK::doDoubleLoop() {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
- if( Verbose() >= 3)
+ if( props.verbose >= 3)
cout << endl;
double tic = toc();
// Differences in single node beliefs
Diffs diffs(nrVars(), 1.0);
- size_t outer_maxiter = MaxIter();
- double outer_tol = Tol();
- size_t outer_verbose = Verbose();
- double org_maxdiff = MaxDiff();
+ size_t outer_maxiter = props.maxiter;
+ double outer_tol = props.tol;
+ size_t outer_verbose = props.verbose;
+ double org_maxdiff = maxdiff;
// Set parameters for inner loop
- MaxIter( 5 );
- Verbose( outer_verbose ? outer_verbose - 1 : 0 );
+ props.maxiter = 5;
+ props.verbose = outer_verbose ? outer_verbose - 1 : 0;
size_t outer_iter = 0;
for( outer_iter = 0; outer_iter < outer_maxiter && diffs.maxDiff() > outer_tol; outer_iter++ ) {
old_beliefs[i] = new_belief;
}
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "HAK::doDoubleLoop: maxdiff " << diffs.maxDiff() << " after " << outer_iter+1 << " passes" << endl;
}
// restore _maxiter, _verbose and _maxdiff
- MaxIter( outer_maxiter );
- Verbose( outer_verbose );
- MaxDiff( org_maxdiff );
+ props.maxiter = outer_maxiter;
+ props.verbose = outer_verbose;
+ maxdiff = org_maxdiff;
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
// Restore original outer regions
ORs = org_ORs;
for( size_t beta = 0; beta < nrIRs(); ++beta )
IR(beta).c() = org_IR_cs[beta];
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
cout << "HAK::doDoubleLoop: WARNING: not converged within " << outer_maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "HAK::doDoubleLoop: ";
cout << "converged in " << outer_iter << " passes (" << toc() - tic << " clocks)." << endl;
}
double HAK::run() {
- if( DoubleLoop() )
+ if( props.doubleloop )
return doDoubleLoop();
else
return doGBP();
const char *JTree::Name = "JTREE";
-bool JTree::checkProperties() {
- if (!HasProperty("verbose") )
- return false;
- if( !HasProperty("updates") )
- return false;
+void JTree::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("updates") );
- ConvertPropertyTo<size_t>("verbose");
- ConvertPropertyTo<UpdateType>("updates");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.updates = opts.getStringAs<Properties::UpdateType>("updates");
+}
+
- return true;
+PropertySet JTree::getProperties() const {
+ PropertySet opts;
+ opts.Set( "verbose", props.verbose );
+ opts.Set( "updates", props.updates );
+ return opts;
}
-JTree::JTree( const FactorGraph &fg, const Properties &opts, bool automatic ) : DAIAlgRG(fg, opts), _RTree(), _Qa(), _Qb(), _mes(), _logZ() {
- assert( checkProperties() );
+JTree::JTree( const FactorGraph &fg, const PropertySet &opts, bool automatic ) : DAIAlgRG(fg), _RTree(), _Qa(), _Qb(), _mes(), _logZ(), props() {
+ setProperties( opts );
if( automatic ) {
// Copy VarSets of factors
cl.push_back( factor(I).vars() );
ClusterGraph _cg( cl );
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "Initial clusters: " << _cg << endl;
// Retain only maximal clusters
_cg.eraseNonMaximal();
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "Maximal clusters: " << _cg << endl;
vector<VarSet> ElimVec = _cg.VarElim_MinFill().eraseNonMaximal().toVector();
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "VarElim_MinFill result: " << ElimVec << endl;
GenerateJT( ElimVec );
// Check counting numbers
Check_Counting_Numbers();
- if( Verbose() >= 3 ) {
+ if( props.verbose >= 3 ) {
cout << "Resulting regiongraph: " << *this << endl;
}
}
string JTree::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
double JTree::run() {
- if( Updates() == UpdateType::HUGIN )
+ if( props.updates == Properties::UpdateType::HUGIN )
runHUGIN();
- else if( Updates() == UpdateType::SHSH )
+ else if( props.updates == Properties::UpdateType::SHSH )
runShaferShenoy();
return 0.0;
}
const char *LC::Name = "LC";
-bool LC::checkProperties() {
- if( !HasProperty("cavity") )
- return false;
- if( !HasProperty("updates") )
- return false;
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
-
- ConvertPropertyTo<CavityType>("cavity");
- ConvertPropertyTo<UpdateType>("updates");
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
-
- if (HasProperty("cavainame") )
- ConvertPropertyTo<string>("cavainame");
- if (HasProperty("cavaiopts") )
- ConvertPropertyTo<Properties>("cavaiopts");
- if( HasProperty("reinit") )
- ConvertPropertyTo<bool>("reinit");
+void LC::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("cavity") );
+ assert( opts.hasKey("updates") );
- return true;
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.cavity = opts.getStringAs<Properties::CavityType>("cavity");
+ props.updates = opts.getStringAs<Properties::UpdateType>("updates");
+ if( opts.hasKey("cavainame") )
+ props.cavainame = opts.getStringAs<string>("cavainame");
+ if( opts.hasKey("cavaiopts") )
+ props.cavaiopts = opts.getStringAs<PropertySet>("cavaiopts");
+ if( opts.hasKey("reinit") )
+ props.reinit = opts.getStringAs<bool>("reinit");
}
-LC::LC(const FactorGraph & fg, const Properties &opts) : DAIAlgFG(fg, opts) {
- assert( checkProperties() );
+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 );
+ return opts;
+}
+
+
+LC::LC( const FactorGraph & fg, const PropertySet &opts ) : DAIAlgFG(fg), _pancakes(), _cavitydists(), _phis(), _beliefs(), props(), maxdiff(0.0) {
+ setProperties( opts );
// create pancakes
_pancakes.resize(nrVars());
string LC::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
}
-double LC::CalcCavityDist (size_t i, const std::string &name, const Properties &opts) {
+double LC::CalcCavityDist (size_t i, const std::string &name, const PropertySet &opts) {
Factor Bi;
double maxdiff = 0;
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << "Initing cavity " << var(i) << "(" << delta(i).size() << " vars, " << delta(i).states() << " states)" << endl;
- if( Cavity() == CavityType::UNIFORM )
+ if( props.cavity == Properties::CavityType::UNIFORM )
Bi = Factor(delta(i));
else {
InfAlg *cav = newInfAlg( name, *this, opts );
cav->makeCavity( i );
- if( Cavity() == CavityType::FULL )
- Bi = calcMarginal( *cav, cav->delta(i), reInit() );
- else if( Cavity() == CavityType::PAIR )
- Bi = calcMarginal2ndO( *cav, cav->delta(i), reInit() );
- else if( Cavity() == CavityType::PAIR2 ) {
- vector<Factor> pairbeliefs = calcPairBeliefsNew( *cav, cav->delta(i), reInit() );
+ if( props.cavity == Properties::CavityType::FULL )
+ Bi = calcMarginal( *cav, cav->delta(i), props.reinit );
+ else if( props.cavity == Properties::CavityType::PAIR )
+ Bi = calcMarginal2ndO( *cav, cav->delta(i), props.reinit );
+ else if( props.cavity == Properties::CavityType::PAIR2 ) {
+ vector<Factor> pairbeliefs = calcPairBeliefsNew( *cav, cav->delta(i), props.reinit );
for( size_t ij = 0; ij < pairbeliefs.size(); ij++ )
Bi *= pairbeliefs[ij];
- } else if( Cavity() == CavityType::PAIRINT ) {
- Bi = calcMarginal( *cav, cav->delta(i), reInit() );
+ } else if( props.cavity == Properties::CavityType::PAIRINT ) {
+ Bi = calcMarginal( *cav, cav->delta(i), props.reinit );
// Set interactions of order > 2 to zero
size_t N = delta(i).size();
x2x::w2logp (N, p);
// x2x::logpnorm (N, p);
x2x::logp2p (N, p);
- } else if( Cavity() == CavityType::PAIRCUM ) {
- Bi = calcMarginal( *cav, cav->delta(i), reInit() );
+ } else if( props.cavity == Properties::CavityType::PAIRCUM ) {
+ Bi = calcMarginal( *cav, cav->delta(i), props.reinit );
// Set cumulants of order > 2 to zero
size_t N = delta(i).size();
x2x::c2m (N, p, N);
x2x::m2p (N, p);
}
- maxdiff = cav->MaxDiff();
+ maxdiff = cav->maxDiff();
delete cav;
}
Bi.normalize( _normtype );
}
-double LC::InitCavityDists (const std::string &name, const Properties &opts) {
+double LC::InitCavityDists( const std::string &name, const PropertySet &opts ) {
double tic = toc();
- if( Verbose() >= 1 ) {
+ if( props.verbose >= 1 ) {
cout << "LC::InitCavityDists: ";
- if( Cavity() == CavityType::UNIFORM )
+ if( props.cavity == Properties::CavityType::UNIFORM )
cout << "Using uniform initial cavity distributions" << endl;
- else if( Cavity() == CavityType::FULL )
+ else if( props.cavity == Properties::CavityType::FULL )
cout << "Using full " << name << opts << "...";
- else if( Cavity() == CavityType::PAIR )
+ else if( props.cavity == Properties::CavityType::PAIR )
cout << "Using pairwise " << name << opts << "...";
- else if( Cavity() == CavityType::PAIR2 )
+ else if( props.cavity == Properties::CavityType::PAIR2 )
cout << "Using pairwise(new) " << name << opts << "...";
}
}
init();
- if( Verbose() >= 1 ) {
+ if( props.verbose >= 1 ) {
cout << "used " << toc() - tic << " clocks." << endl;
}
long LC::SetCavityDists( std::vector<Factor> &Q ) {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "LC::SetCavityDists: Setting initial cavity distributions" << endl;
if( Q.size() != nrVars() )
return -1;
void LC::init() {
for( size_t i = 0; i < nrVars(); ++i )
foreach( const Neighbor &I, nbV(i) )
- if( Updates() == UpdateType::SEQRND )
+ if( props.updates == Properties::UpdateType::SEQRND )
_phis[i][I.iter].randomize();
else
_phis[i][I.iter].fill(1.0);
foreach( const Neighbor &I, nbV(i) ) {
_pancakes[i] *= factor(I);
- if( Updates() == UpdateType::SEQRND )
+ if( props.updates == Properties::UpdateType::SEQRND )
_pancakes[i] *= _phis[i][I.iter];
}
double LC::run() {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << endl;
double tic = toc();
Diffs diffs(nrVars(), 1.0);
- updateMaxDiff( InitCavityDists(GetPropertyAs<string>("cavainame"), GetPropertyAs<Properties>("cavaiopts")) );
+ double md = InitCavityDists( props.cavainame, props.cavaiopts );
+ if( md > maxdiff )
+ maxdiff = md;
vector<Factor> old_beliefs;
for(size_t i=0; i < nrVars(); i++ )
// do several passes over the network until maximum number of iterations has
// been reached or until the maximum belief difference is smaller than tolerance
- for( iter=0; iter < MaxIter() && diffs.maxDiff() > Tol(); iter++ ) {
+ for( iter=0; iter < props.maxiter && diffs.maxDiff() > props.tol; iter++ ) {
// Sequential updates
- if( Updates() == UpdateType::SEQRND )
+ if( props.updates == Properties::UpdateType::SEQRND )
random_shuffle( update_seq.begin(), update_seq.end() );
for( size_t t=0; t < nredges; t++ ) {
old_beliefs[i] = belief(i);
}
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "LC::run: maxdiff " << diffs.maxDiff() << " after " << iter+1 << " passes" << endl;
}
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "LC::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << "LC::run: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << "LC::run: ";
cout << "converged in " << iter << " passes (" << toc() - tic << " clocks)." << endl;
}
const char *MF::Name = "MF";
-bool MF::checkProperties() {
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
-
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
+void MF::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+ assert( opts.hasKey("verbose") );
+
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+}
- return true;
+
+PropertySet MF::getProperties() const {
+ PropertySet opts;
+ opts.Set( "tol", props.tol );
+ opts.Set( "maxiter", props.maxiter );
+ opts.Set( "verbose", props.verbose );
+ return opts;
}
string MF::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
void MF::init() {
- assert( checkProperties() );
-
for( vector<Factor>::iterator qi = _beliefs.begin(); qi != _beliefs.end(); qi++ )
qi->fill(1.0);
}
double MF::run() {
double tic = toc();
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
size_t pass_size = _beliefs.size();
Diffs diffs(pass_size * 3, 1.0);
size_t t=0;
- for( t=0; t < (MaxIter()*pass_size) && diffs.maxDiff() > Tol(); t++ ) {
+ for( t=0; t < (props.maxiter*pass_size) && diffs.maxDiff() > props.tol; t++ ) {
// choose random Var i
size_t i = (size_t) (nrVars() * rnd_uniform());
_beliefs[i] = jan;
}
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "MF::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << "MF::run: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << "MF::run: ";
cout << "converged in " << t / pass_size << " passes (" << toc() - tic << " clocks)." << endl;
}
const char *MR::Name = "MR";
-bool MR::checkProperties() {
- if( !HasProperty("updates") )
- return false;
- if( !HasProperty("inits") )
- return false;
- if( !HasProperty("verbose") )
- return false;
- if( !HasProperty("tol") )
- return false;
+void MR::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("updates") );
+ assert( opts.hasKey("inits") );
- ConvertPropertyTo<UpdateType>("updates");
- ConvertPropertyTo<InitType>("inits");
- ConvertPropertyTo<size_t>("verbose");
- ConvertPropertyTo<double>("tol");
+ props.tol = opts.getStringAs<double>("tol");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.updates = opts.getStringAs<Properties::UpdateType>("updates");
+ props.inits = opts.getStringAs<Properties::InitType>("inits");
+}
+
- return true;
+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 );
+ return opts;
}
}
}
}
- } while((md > Tol())&&(runx<runs)); // Precision condition reached -> BP and RP finished
+ } while((md > props.tol)&&(runx<runs)); // Precision condition reached -> BP and RP finished
if(runx==runs)
- if( Verbose() >= 2 )
+ if( props.verbose >= 2 )
cout << "init_cor_resp: Convergence not reached (md=" << md << ")..." << endl;
if(md > maxdev)
maxdev = md;
assert( nb[j][_i] == i );
double newM = 0.0;
- if( Updates() == UpdateType::FULL ) {
+ if( props.updates == Properties::UpdateType::FULL ) {
// find indices in nb[j] that do not correspond with i
sub_nb _nbj_min_i(con[j]);
_nbj_min_i -= kindex[i][_j];
numer += tJ[i][_k] * cors[i][_j][_k] * (tanh(theta[i]) * sum_even + sum_odd);
}
newM -= numer / denom;
- } else if( Updates() == UpdateType::LINEAR ) {
+ } else if( props.updates == Properties::UpdateType::LINEAR ) {
newM = T(j,_i);
for(size_t _l=0; _l<con[i]; _l++) if( _l != _j )
newM -= Omega(i,_j,_l) * tJ[i][_l] * cors[i][_j][_l];
M[i][_j] = newM;
}
}
- } while((maxdev>Tol())&&(run<maxruns));
+ } while((maxdev>props.tol)&&(run<maxruns));
- updateMaxDiff( maxdev );
+ if( maxdev > maxdiff )
+ maxdiff = maxdev;
if(run==maxruns){
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "solve_mcav: Convergence not reached (maxdev=" << maxdev << ")..." << endl;
}
}
void MR::solveM() {
for(size_t i=0; i<N; i++) {
- if( Updates() == UpdateType::FULL ) {
+ if( props.updates == Properties::UpdateType::FULL ) {
// find indices in nb[i]
sub_nb _nbi(con[i]);
Mag[i] = (tanh(theta[i]) * sum_even + sum_odd) / (sum_even + tanh(theta[i]) * sum_odd);
- } else if( Updates() == UpdateType::LINEAR ) {
+ } else if( props.updates == Properties::UpdateType::LINEAR ) {
sub_nb empty(con[i]);
empty.clear();
Mag[i] = T(i,empty);
void MR::init_cor() {
for( size_t i = 0; i < nrVars(); i++ ) {
vector<Factor> pairq;
- if( Inits() == InitType::CLAMPING ) {
- BP bpcav(*this, Properties()("updates",string("SEQMAX"))("tol", string("1e-9"))("maxiter", string("1000UL"))("verbose", string("0UL"))("logdomain", string("0")));
+ if( props.inits == Properties::InitType::CLAMPING ) {
+ BP bpcav(*this, PropertySet()("updates",string("SEQMAX"))("tol", string("1e-9"))("maxiter", string("1000UL"))("verbose", string("0UL"))("logdomain", string("0")));
bpcav.makeCavity( i );
pairq = calcPairBeliefs( bpcav, delta(i), false );
- } else if( Inits() == InitType::EXACT ) {
- JTree jtcav(*this, Properties()("updates",string("HUGIN"))("verbose", string("0UL")) );
+ } else if( props.inits == Properties::InitType::EXACT ) {
+ JTree jtcav(*this, PropertySet()("updates",string("HUGIN"))("verbose", 0UL) );
jtcav.makeCavity( i );
pairq = calcPairBeliefs( jtcav, delta(i), false );
}
string MR::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
double MR::run() {
if( supported ) {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
double tic = toc();
for(size_t i=0; i<N; i++)
kindex[i].resize(kmax);
- if( Inits() == InitType::RESPPROP )
- updateMaxDiff( init_cor_resp() );
- else if( Inits() == InitType::EXACT )
+ if( props.inits == Properties::InitType::RESPPROP ) {
+ double md = init_cor_resp();
+ if( md > maxdiff )
+ maxdiff = md;
+ } else if( props.inits == Properties::InitType::EXACT )
init_cor(); // FIXME no MaxDiff() calculation
- else if( Inits() == InitType::CLAMPING )
+ else if( props.inits == Properties::InitType::CLAMPING )
init_cor(); // FIXME no MaxDiff() calculation
solvemcav();
Mag.resize(N);
solveM();
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "MR needed " << toc() - tic << " clocks." << endl;
return 0.0;
-MR::MR( const FactorGraph &fg, const Properties &opts ) : DAIAlgFG(fg, opts), supported(true) {
+MR::MR( const FactorGraph &fg, const PropertySet &opts ) : DAIAlgFG(fg), supported(true), maxdiff(0.0) {
+ setProperties( opts );
+
// check whether all vars in fg are binary
// check whether connectivity is <= kmax
for( size_t i = 0; i < fg.nrVars(); i++ )
os << boost::any_cast<double>(p.second);
else if( p.second.type() == typeid(bool) )
os << boost::any_cast<bool>(p.second);
- else if( p.second.type() == typeid(Properties) )
- os << boost::any_cast<Properties>(p.second);
+ else if( p.second.type() == typeid(PropertySet) )
+ os << boost::any_cast<PropertySet>(p.second);
#ifdef WITH_BP
- else if( p.second.type() == typeid(BP::UpdateType) )
- os << boost::any_cast<BP::UpdateType>(p.second);
+ else if( p.second.type() == typeid(BP::Properties::UpdateType) )
+ os << boost::any_cast<BP::Properties::UpdateType>(p.second);
#endif
#ifdef WITH_HAK
- else if( p.second.type() == typeid(HAK::ClustersType) )
- os << boost::any_cast<HAK::ClustersType>(p.second);
+ else if( p.second.type() == typeid(HAK::Properties::ClustersType) )
+ os << boost::any_cast<HAK::Properties::ClustersType>(p.second);
#endif
#ifdef WITH_JTREE
- else if( p.second.type() == typeid(JTree::UpdateType) )
- os << boost::any_cast<JTree::UpdateType>(p.second);
+ else if( p.second.type() == typeid(JTree::Properties::UpdateType) )
+ os << boost::any_cast<JTree::Properties::UpdateType>(p.second);
#endif
#ifdef WITH_MR
- else if( p.second.type() == typeid(MR::UpdateType) )
- os << boost::any_cast<MR::UpdateType>(p.second);
- else if( p.second.type() == typeid(MR::InitType) )
- os << boost::any_cast<MR::InitType>(p.second);
+ else if( p.second.type() == typeid(MR::Properties::UpdateType) )
+ os << boost::any_cast<MR::Properties::UpdateType>(p.second);
+ else if( p.second.type() == typeid(MR::Properties::InitType) )
+ os << boost::any_cast<MR::Properties::InitType>(p.second);
#endif
#ifdef WITH_TREEEP
- else if( p.second.type() == typeid(TreeEP::TypeType) )
- os << boost::any_cast<TreeEP::TypeType>(p.second);
+ else if( p.second.type() == typeid(TreeEP::Properties::TypeType) )
+ os << boost::any_cast<TreeEP::Properties::TypeType>(p.second);
#endif
#ifdef WITH_LC
- else if( p.second.type() == typeid(LC::CavityType) )
- os << boost::any_cast<LC::CavityType>(p.second);
- else if( p.second.type() == typeid(LC::UpdateType) )
- os << boost::any_cast<LC::UpdateType>(p.second);
+ else if( p.second.type() == typeid(LC::Properties::CavityType) )
+ os << boost::any_cast<LC::Properties::CavityType>(p.second);
+ else if( p.second.type() == typeid(LC::Properties::UpdateType) )
+ os << boost::any_cast<LC::Properties::UpdateType>(p.second);
#endif
else
throw "Unknown property type";
}
-/// Sends a Properties object to an output stream
-std::ostream& operator<< (std::ostream & os, const Properties & ps) {
+/// Sends a PropertySet object to an output stream
+std::ostream& operator<< (std::ostream & os, const PropertySet & ps) {
os << "[";
- for( Properties::const_iterator p = ps.begin(); p != ps.end(); p++ ) {
+ for( PropertySet::const_iterator p = ps.begin(); p != ps.end(); p++ ) {
if( p != ps.begin() )
os << ",";
os << (Property)*p;
}
-/// Reads a Properties object from an input stream, storing values as strings
-std::istream& operator >> (std::istream& is, Properties & ps) {
- ps = Properties();
+/// Reads a PropertySet object from an input stream, storing values as strings
+std::istream& operator >> (std::istream& is, PropertySet & ps) {
+ ps = PropertySet();
std::string s;
is >> s;
const char *TreeEP::Name = "TREEEP";
-bool TreeEP::checkProperties() {
- if( !HasProperty("type") )
- return false;
- if( !HasProperty("tol") )
- return false;
- if (!HasProperty("maxiter") )
- return false;
- if (!HasProperty("verbose") )
- return false;
+void TreeEP::setProperties( const PropertySet &opts ) {
+ assert( opts.hasKey("tol") );
+ assert( opts.hasKey("maxiter") );
+ assert( opts.hasKey("verbose") );
+ assert( opts.hasKey("type") );
- ConvertPropertyTo<TypeType>("type");
- ConvertPropertyTo<double>("tol");
- ConvertPropertyTo<size_t>("maxiter");
- ConvertPropertyTo<size_t>("verbose");
+ props.tol = opts.getStringAs<double>("tol");
+ props.maxiter = opts.getStringAs<size_t>("maxiter");
+ props.verbose = opts.getStringAs<size_t>("verbose");
+ props.type = opts.getStringAs<Properties::TypeType>("type");
+}
+
- return true;
+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 );
+ return opts;
}
}
-TreeEP::TreeEP( const FactorGraph &fg, const Properties &opts ) : JTree(fg, opts("updates",string("HUGIN")), false) {
- assert( checkProperties() );
+TreeEP::TreeEP( const FactorGraph &fg, const PropertySet &opts ) : JTree(fg, opts("updates",string("HUGIN")), false), props(), maxdiff(0.0) {
+ setProperties( opts );
assert( fg.G.isConnected() );
if( opts.hasKey("tree") ) {
ConstructRG( opts.GetAs<DEdgeVec>("tree") );
} else {
- if( Type() == TypeType::ORG ) {
+ if( props.type == Properties::TypeType::ORG ) {
// construct weighted graph with as weights a crude estimate of the
// mutual information between the nodes
WeightedGraph<double> wg;
// for( DEdgeVec::const_iterator e = MST.begin(); e != MST.end(); e++ )
// cout << *e << endl;
// ConstructRG( MST );
- } else if( Type() == TypeType::ALT ) {
+ } else if( props.type == Properties::TypeType::ALT ) {
// construct weighted graph with as weights an upper bound on the
// effective interaction strength between pairs of nodes
WeightedGraph<double> wg;
break;
}
- if( Verbose() >= 3 ) {
+ if( props.verbose >= 3 ) {
cout << "Resulting regiongraph: " << *this << endl;
}
}
string TreeEP::identify() const {
stringstream result (stringstream::out);
- result << Name << GetProperties();
+ result << Name << getProperties();
return result.str();
}
void TreeEP::init() {
- assert( checkProperties() );
-
runHUGIN();
// Init factor approximations
double TreeEP::run() {
- if( Verbose() >= 1 )
+ if( props.verbose >= 1 )
cout << "Starting " << identify() << "...";
- if( Verbose() >= 3)
+ if( props.verbose >= 3)
cout << endl;
double tic = toc();
// do several passes over the network until maximum number of iterations has
// been reached or until the maximum belief difference is smaller than tolerance
- for( iter=0; iter < MaxIter() && diffs.maxDiff() > Tol(); iter++ ) {
+ for( iter=0; iter < props.maxiter && diffs.maxDiff() > props.tol; iter++ ) {
for( size_t I = 0; I < nrFactors(); I++ )
if( offtree(I) ) {
_Q[I].InvertAndMultiply( _Qa, _Qb );
old_beliefs[i] = nb;
}
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "TreeEP::run: maxdiff " << diffs.maxDiff() << " after " << iter+1 << " passes" << endl;
}
- updateMaxDiff( diffs.maxDiff() );
+ if( diffs.maxDiff() > maxdiff )
+ maxdiff = diffs.maxDiff();
- if( Verbose() >= 1 ) {
- if( diffs.maxDiff() > Tol() ) {
- if( Verbose() == 1 )
+ if( props.verbose >= 1 ) {
+ if( diffs.maxDiff() > props.tol ) {
+ if( props.verbose == 1 )
cout << endl;
- cout << "TreeEP::run: WARNING: not converged within " << MaxIter() << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
+ cout << "TreeEP::run: WARNING: not converged within " << props.maxiter << " passes (" << toc() - tic << " clocks)...final maxdiff:" << diffs.maxDiff() << endl;
} else {
- if( Verbose() >= 3 )
+ if( props.verbose >= 3 )
cout << "TreeEP::run: ";
cout << "converged in " << iter << " passes (" << toc() - tic << " clocks)." << endl;
}
double maxdiff;
double time;
- TestAI( const FactorGraph &fg, const string &_name, const Properties &opts ) : obj(NULL), name(_name), err(), q(), logZ(0.0), maxdiff(0.0), time(0) {
+ TestAI( const FactorGraph &fg, const string &_name, const PropertySet &opts ) : obj(NULL), name(_name), err(), q(), logZ(0.0), maxdiff(0.0), time(0) {
double tic = toc();
obj = newInfAlg( name, fg, opts );
time += toc() - tic;
obj->run();
time += toc() - tic;
logZ = real(obj->logZ());
- maxdiff = obj->MaxDiff();
+ maxdiff = obj->maxDiff();
q = allBeliefs();
};
}
};
-pair<string, Properties> parseMethod( const string &_s, const map<string,string> & aliases ) {
+pair<string, PropertySet> parseMethod( const string &_s, const map<string,string> & aliases ) {
string s = _s;
if( aliases.find(_s) != aliases.end() )
s = aliases.find(_s)->second;
- pair<string, Properties> result;
+ pair<string, PropertySet> result;
string & name = result.first;
- Properties & opts = result.second;
+ PropertySet & opts = result.second;
string::size_type pos = s.find_first_of('[');
name = s.substr( 0, pos );
cout << "MAXDIFF" << endl;
for( size_t m = 0; m < methods.size(); m++ ) {
- pair<string, Properties> meth = parseMethod( methods[m], Aliases );
+ pair<string, PropertySet> meth = parseMethod( methods[m], Aliases );
if( vm.count("tol") )
meth.second.Set("tol",tol);