1 /* Copyright (C) 2006-2008 Joris Mooij [joris dot mooij at tuebingen dot mpg dot de]
2 Radboud University Nijmegen, The Netherlands /
3 Max Planck Institute for Biological Cybernetics, Germany
5 This file is part of libDAI.
7 libDAI is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 libDAI is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with libDAI; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 /// \brief Defines abstract base class InfAlg, its descendants DAIAlg<T>, the specializations DAIAlgFG and DAIAlgRG and some generic inference methods.
25 /// \todo Improve documentation
28 #ifndef __defined_libdai_daialg_h
29 #define __defined_libdai_daialg_h
35 #include <dai/factorgraph.h>
36 #include <dai/regiongraph.h>
42 /// InfAlg is an abstract base class, defining the common interface of all inference algorithms in libDAI.
43 /** \todo General marginalization functions like calcMarginal now copy a complete InfAlg object. Instead,
44 * it would make more sense that they construct a new object without copying the FactorGraph or RegionGraph.
45 * Or they can simply be made methods of the general InfAlg class.
46 * \idea Use a PropertySet as output of an InfAlg, instead of functions like maxDiff() and Iterations().
50 /// Virtual desctructor (needed because this class contains virtual functions)
54 /// Returns a pointer to a new, cloned copy of *this (i.e., virtual copy constructor)
55 virtual InfAlg
* clone() const = 0;
57 /// Identifies itself for logging purposes
58 virtual std::string
identify() const = 0;
60 /// Returns the "belief" (i.e., approximate marginal probability distribution) of a variable
61 virtual Factor
belief( const Var
&n
) const = 0;
63 /// Returns the "belief" (i.e., approximate marginal probability distribution) of a set of variables
64 virtual Factor
belief( const VarSet
&n
) const = 0;
66 /// Returns marginal for a variable.
67 /** Sometimes preferred to belief() for performance reasons.
68 * Faster implementations exist in e.g. BP.
70 virtual Factor
beliefV( size_t i
) const { return belief( fg().var(i
) ); }
72 /// Returns marginal for a factor.
73 /** Sometimes preferred to belief() for performance reasons.
74 * Faster implementations exist in e.g. BP.
76 virtual Factor
beliefF( size_t I
) const { return belief( fg().factor(I
).vars() ); }
78 /// Returns all "beliefs" (i.e., approximate marginal probability distribution) calculated by the algorithm
79 virtual std::vector
<Factor
> beliefs() const = 0;
81 /// Returns the logarithm of the (approximated) partition sum (normalizing constant of the factor graph)
82 virtual Real
logZ() const = 0;
84 /// Initializes all data structures of the approximate inference algorithm
85 /** This method should be called at least once before run() is called
87 virtual void init() = 0;
89 /// Initializes all data structures corresponding to some set of variables
90 /** This method can be used to do a partial initialization after a part of the factor graph has changed.
91 * Instead of initializing all data structures, it only initializes those involving the variables in ns.
93 virtual void init( const VarSet
&ns
) = 0;
95 /// Runs the approximate inference algorithm
96 /* Before run() is called the first time, init() should be called.
97 * If run() returns successfully, the results can be queried using the methods belief(), beliefs() and logZ().
99 virtual double run() = 0;
101 /// Clamp variable n to value i (i.e. multiply with a Kronecker delta \f$\delta_{x_n, i}\f$)
102 virtual void clamp( const Var
& n
, size_t i
, bool backup
= false ) = 0;
104 /// Set all factors interacting with var(i) to 1
105 virtual void makeCavity( size_t i
, bool backup
= false ) = 0;
107 /// Return maximum difference between single node beliefs in the last pass
108 /// \throw Exception if not implemented/supported
109 virtual double maxDiff() const = 0;
111 /// Return number of passes over the factorgraph
112 /// \throw Exception if not implemented/supported
113 virtual size_t Iterations() const = 0;
116 /// Get reference to underlying FactorGraph
117 virtual FactorGraph
&fg() = 0;
119 /// Get const reference to underlying FactorGraph
120 virtual const FactorGraph
&fg() const = 0;
123 virtual void backupFactor( size_t I
) = 0;
124 /// Save Factors involving ns
125 virtual void backupFactors( const VarSet
&ns
) = 0;
128 virtual void restoreFactor( size_t I
) = 0;
129 /// Restore Factors involving ns
130 virtual void restoreFactors( const VarSet
&ns
) = 0;
134 /// Combines an InfAlg and a graphical model, e.g., a FactorGraph or RegionGraph
135 /** \tparam GRM Should be castable to FactorGraph
136 * \todo A DAIAlg should not inherit from a FactorGraph or RegionGraph, but should
137 * store a reference to the graphical model object. This prevents needless copying
138 * of (possibly large) data structures. Disadvantage: the caller must not change
139 * the graphical model between calls to the inference algorithm (maybe a smart_ptr
140 * or some locking mechanism would help here?).
143 class DAIAlg
: public InfAlg
, public GRM
{
145 /// Default constructor
146 DAIAlg() : InfAlg(), GRM() {}
148 /// Construct from GRM
149 DAIAlg( const GRM
&grm
) : InfAlg(), GRM(grm
) {}
152 void backupFactor( size_t I
) { GRM::backupFactor( I
); }
153 /// Save Factors involving ns
154 void backupFactors( const VarSet
&ns
) { GRM::backupFactors( ns
); }
157 void restoreFactor( size_t I
) { GRM::restoreFactor( I
); }
158 /// Restore Factors involving ns
159 void restoreFactors( const VarSet
&ns
) { GRM::restoreFactors( ns
); }
161 /// Clamp variable n to value i (i.e. multiply with a Kronecker delta \f$\delta_{x_n, i}\f$)
162 void clamp( const Var
& n
, size_t i
, bool backup
= false ) { GRM::clamp( n
, i
, backup
); }
164 /// Set all factors interacting with var(i) to 1
165 void makeCavity( size_t i
, bool backup
= false ) { GRM::makeCavity( i
, backup
); }
167 /// Get reference to underlying FactorGraph
168 FactorGraph
&fg() { return (FactorGraph
&)(*this); }
170 /// Get const reference to underlying FactorGraph
171 const FactorGraph
&fg() const { return (const FactorGraph
&)(*this); }
175 /// Base class for inference algorithms that operate on a FactorGraph
176 typedef DAIAlg
<FactorGraph
> DAIAlgFG
;
178 /// Base class for inference algorithms that operate on a RegionGraph
179 typedef DAIAlg
<RegionGraph
> DAIAlgRG
;
182 Factor
calcMarginal( const InfAlg
& obj
, const VarSet
& ns
, bool reInit
);
183 std::vector
<Factor
> calcPairBeliefs( const InfAlg
& obj
, const VarSet
& ns
, bool reInit
);
184 std::vector
<Factor
> calcPairBeliefsNew( const InfAlg
& obj
, const VarSet
& ns
, bool reInit
);
185 Factor
calcMarginal2ndO( const InfAlg
& obj
, const VarSet
& ns
, bool reInit
);
188 } // end of namespace dai