-/* Copyright (C) 2006-2008 Joris Mooij [j dot mooij at science dot ru dot nl]
- Radboud University Nijmegen, The Netherlands
+/* 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) 2006-2009 Joris Mooij [joris dot mooij at libdai dot org]
+ * Copyright (C) 2006-2007 Radboud University Nijmegen, The Netherlands
+ */
- This file is part of libDAI.
- libDAI is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- libDAI is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with libDAI; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+/// \file
+/// \brief Defines class LC
+/// \todo Improve documentation
#ifndef __defined_libdai_lc_h
#include <dai/daialg.h>
#include <dai/enum.h>
#include <dai/factorgraph.h>
+#include <dai/properties.h>
+#include <dai/exceptions.h>
namespace dai {
+/// Approximate inference algorithm "Loop Corrected Belief Propagation" by Mooij and Kappen
class LC : public DAIAlgFG {
- protected:
+ private:
std::vector<Factor> _pancakes; // used by all LC types (psi_I is stored in the pancake)
std::vector<Factor> _cavitydists; // used by all LC types to store the approximate cavity distribution
/// _phis[i][_I] corresponds to \f$ \phi^{\setminus i}_I(x_{I \setminus i}) \f$
/// Single variable beliefs
std::vector<Factor> _beliefs;
+ /// Maximum difference encountered so far
+ Real _maxdiff;
+ /// Number of iterations needed
+ size_t _iters;
+
public:
- ENUM6(CavityType,FULL,PAIR,PAIR2,PAIRINT,PAIRCUM,UNIFORM)
- ENUM3(UpdateType,SEQFIX,SEQRND,NONE)
+ /// Parameters of this inference algorithm
+ struct Properties {
+ /// Enumeration of possible ways to initialize the cavities
+ DAI_ENUM(CavityType,FULL,PAIR,PAIR2,UNIFORM);
- CavityType Cavity() const { return GetPropertyAs<CavityType>("cavity"); }
- UpdateType Updates() const { return GetPropertyAs<UpdateType>("updates"); }
- bool reInit() const { return GetPropertyAs<bool>("reinit"); }
-
- /// Default constructor
- LC() : DAIAlgFG() {};
- /// Copy constructor
- LC(const LC & x) : DAIAlgFG(x), _pancakes(x._pancakes), _cavitydists(x._cavitydists), _phis(x._phis), _beliefs(x._beliefs) {};
- /// Clone function
- LC* clone() const { return new LC(*this); }
- /// Construct LC object from a FactorGraph and parameters
- LC(const FactorGraph & fg, const Properties &opts);
- /// Assignment operator
- LC& operator=(const LC & x) {
- if( this != &x ) {
- DAIAlgFG::operator=(x);
- _pancakes = x._pancakes;
- _cavitydists = x._cavitydists;
- _phis = x._phis;
- _beliefs = x._beliefs;
- }
- return *this;
- }
+ /// Enumeration of different update schedules
+ DAI_ENUM(UpdateType,SEQFIX,SEQRND,NONE);
+
+ /// Verbosity
+ size_t verbose;
+
+ /// Maximum number of iterations
+ size_t maxiter;
+
+ /// Tolerance
+ Real tol;
+
+ /// Complete or partial reinit of cavity graphs?
+ bool reinit;
+ /// Damping constant
+ Real damping;
+
+ /// How to initialize the cavities
+ CavityType cavity;
+
+ /// What update schedule to use
+ UpdateType updates;
+
+ /// Name of the algorithm used to initialize the cavity distributions
+ std::string cavainame; // FIXME: needs assignment operator?
+
+ /// Parameters for the algorithm used to initialize the cavity distributions
+ PropertySet cavaiopts; // FIXME: needs assignment operator?
+ } props;
+
+ /// Name of this inference algorithm
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 );
+
+ public:
+ /// Default constructor
+ LC() : DAIAlgFG(), _pancakes(), _cavitydists(), _phis(), _beliefs(), _maxdiff(), _iters(), props() {}
+
+ /// Construct from FactorGraph fg and PropertySet opts
+ LC( const FactorGraph &fg, const PropertySet &opts );
+
+
+ /// @name General InfAlg interface
+ //@{
+ virtual LC* clone() const { return new LC(*this); }
+ virtual std::string identify() const;
+ virtual Factor belief( const Var &n ) const { return( _beliefs[findVar(n)] ); }
+ virtual Factor belief( const VarSet &/*ns*/ ) const { DAI_THROW(NOT_IMPLEMENTED); return Factor(); }
+ virtual std::vector<Factor> beliefs() const { return _beliefs; }
+ virtual Real logZ() const { DAI_THROW(NOT_IMPLEMENTED); return 0.0; }
+ virtual void init();
+ virtual void init( const VarSet &/*ns*/ ) { init(); }
+ virtual Real run();
+ virtual Real maxDiff() const { return _maxdiff; }
+ virtual size_t Iterations() const { return _iters; }
+ //@}
+
+ Factor beliefV( size_t i ) const { return _beliefs[i]; }
+
+ /// @name Additional interface specific for LC
+ //@{
+ Real CalcCavityDist( size_t i, const std::string &name, const PropertySet &opts );
+ Real InitCavityDists( const std::string &name, const PropertySet &opts );
long SetCavityDists( std::vector<Factor> &Q );
- void init();
Factor NewPancake (size_t i, size_t _I, bool & hasNaNs);
- double run();
- std::string identify() const;
- Factor belief (const Var &n) const { return( _beliefs[findVar(n)] ); }
- Factor belief (const VarSet &/*ns*/) const { assert( 0 == 1 ); }
- 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]; };
-
- 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();
+ 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]; };
+ //@}
+
+ private:
+ void setProperties( const PropertySet &opts );
+ PropertySet getProperties() const;
+ std::string printProperties() const;
};