From a4a03a5025a50919f07276f1dabbac8f68a4e635 Mon Sep 17 00:00:00 2001 From: Joris Mooij Date: Tue, 3 Nov 2009 11:04:16 +0100 Subject: [PATCH] Removed DAI_ACCMUT macro and improved documentation of include/dai/util.h --- ChangeLog | 1 + TODO | 4 ++- doxygen.conf | 3 +- include/dai/bbp.h | 60 +++++++++++++++++++++++++------------- include/dai/bp_dual.h | 24 ++++++++++----- include/dai/util.h | 68 +++++++++++++++++++++++-------------------- 6 files changed, 98 insertions(+), 62 deletions(-) diff --git a/ChangeLog b/ChangeLog index ccafce5..63168a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* Removed DAI_ACCMUT macro because it didn't yield satisfactory doxygen documentation * Replaced constructor TFactor::TFactor( const VarSet& vars, TIterator begin ) by two constructors diff --git a/TODO b/TODO index 783dcb5..50d6081 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,6 @@ To do for the next release (0.2.3): Improve documentation: - util.h daialg.h alldai.h exactinf.h @@ -27,3 +26,6 @@ multi-dimensional array, e.g., one corresponding to the Cartesian product of statespaces of variables) and "linear index". This should make it easier to document index.h and varset.h + +The Diffs object can probably be replaced by a simple +std::vector. diff --git a/doxygen.conf b/doxygen.conf index 45729f1..398cb83 100644 --- a/doxygen.conf +++ b/doxygen.conf @@ -1257,7 +1257,6 @@ PREDEFINED = DAI_WITH_BP \ DAI_WITH_JTREE \ DAI_WITH_MR \ DAI_WITH_CBP \ - DAI_ACCMUT \ DAI_DEBUG \ DAI_DEBASSERT @@ -1266,7 +1265,7 @@ PREDEFINED = DAI_WITH_BP \ # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. -EXPAND_AS_DEFINED = DAI_ACCMUT +EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone diff --git a/include/dai/bbp.h b/include/dai/bbp.h index ddad9c5..08e28d2 100644 --- a/include/dai/bbp.h +++ b/include/dai/bbp.h @@ -133,14 +133,22 @@ class BBP { void RegenerateSeqMessageAdjoints(); //@} - /// Returns T value; see eqn. (41) in [\ref EaG09] - DAI_ACCMUT(Prob & T(size_t i, size_t _I), { return _T[i][_I]; }); - /// Retunrs U value; see eqn. (42) in [\ref EaG09] - DAI_ACCMUT(Prob & U(size_t I, size_t _i), { return _U[I][_i]; }); - /// Returns S value; see eqn. (43) in [\ref EaG09] - DAI_ACCMUT(Prob & S(size_t i, size_t _I, size_t _j), { return _S[i][_I][_j]; }); - /// Returns R value; see eqn. (44) in [\ref EaG09] - DAI_ACCMUT(Prob & R(size_t I, size_t _i, size_t _J), { return _R[I][_i][_J]; }); + /// Returns reference to T value; see eqn. (41) in [\ref EaG09] + Prob & T(size_t i, size_t _I) { return _T[i][_I]; } + /// Returns constant reference to T value; see eqn. (41) in [\ref EaG09] + const Prob & T(size_t i, size_t _I) const { return _T[i][_I]; } + /// Returns reference to U value; see eqn. (42) in [\ref EaG09] + Prob & U(size_t I, size_t _i) { return _U[I][_i]; } + /// Returns constant reference to U value; see eqn. (42) in [\ref EaG09] + const Prob & U(size_t I, size_t _i) const { return _U[I][_i]; } + /// Returns reference to S value; see eqn. (43) in [\ref EaG09] + Prob & S(size_t i, size_t _I, size_t _j) { return _S[i][_I][_j]; } + /// Returns constant reference to S value; see eqn. (43) in [\ref EaG09] + const Prob & S(size_t i, size_t _I, size_t _j) const { return _S[i][_I][_j]; } + /// Returns reference to R value; see eqn. (44) in [\ref EaG09] + Prob & R(size_t I, size_t _i, size_t _J) { return _R[I][_i][_J]; } + /// Returns constant reference to R value; see eqn. (44) in [\ref EaG09] + const Prob & R(size_t I, size_t _i, size_t _J) const { return _R[I][_i][_J]; } /// @name Parallel algorithm //@{ @@ -243,20 +251,32 @@ class BBP { /// Return number of iterations done so far size_t doneIters() { return _iters; } - /// Returns variable factor adjoint - DAI_ACCMUT(Prob& adj_psi_V(size_t i), { return _adj_psi_V[i]; }); - /// Returns factor adjoint - DAI_ACCMUT(Prob& adj_psi_F(size_t I), { return _adj_psi_F[I]; }); - /// Returns variable belief adjoint - DAI_ACCMUT(Prob& adj_b_V(size_t i), { return _adj_b_V[i]; }); - /// Returns factor belief adjoint - DAI_ACCMUT(Prob& adj_b_F(size_t I), { return _adj_b_F[I]; }); + /// Returns reference to variable factor adjoint + Prob& adj_psi_V(size_t i) { return _adj_psi_V[i]; } + /// Returns constant reference to variable factor adjoint + const Prob& adj_psi_V(size_t i) const { return _adj_psi_V[i]; } + /// Returns reference to factor adjoint + Prob& adj_psi_F(size_t I) { return _adj_psi_F[I]; } + /// Returns constant reference to factor adjoint + const Prob& adj_psi_F(size_t I) const { return _adj_psi_F[I]; } + /// Returns reference to variable belief adjoint + Prob& adj_b_V(size_t i) { return _adj_b_V[i]; } + /// Returns constant reference to variable belief adjoint + const Prob& adj_b_V(size_t i) const { return _adj_b_V[i]; } + /// Returns reference to factor belief adjoint + Prob& adj_b_F(size_t I) { return _adj_b_F[I]; } + /// Returns constant reference to factor belief adjoint + const Prob& adj_b_F(size_t I) const { return _adj_b_F[I]; } protected: - /// Returns variable->factor message adjoint - DAI_ACCMUT(Prob& adj_n(size_t i, size_t _I), { return _adj_n[i][_I]; }); - /// Returns factor->variable message adjoint - DAI_ACCMUT(Prob& adj_m(size_t i, size_t _I), { return _adj_m[i][_I]; }); + /// Returns reference to variable->factor message adjoint + Prob& adj_n(size_t i, size_t _I) { return _adj_n[i][_I]; } + /// Returns constant reference to variable->factor message adjoint + const Prob& adj_n(size_t i, size_t _I) const { return _adj_n[i][_I]; } + /// Returns reference to factor->variable message adjoint + Prob& adj_m(size_t i, size_t _I) { return _adj_m[i][_I]; } + /// Returns constant reference to factor->variable message adjoint + const Prob& adj_m(size_t i, size_t _I) const { return _adj_m[i][_I]; } public: /// Parameters of this algorithm diff --git a/include/dai/bp_dual.h b/include/dai/bp_dual.h index 9baeebd..e205f98 100644 --- a/include/dai/bp_dual.h +++ b/include/dai/bp_dual.h @@ -101,14 +101,22 @@ class BP_dual { /// Returns the underlying FactorGraph const FactorGraph& fg() const { return _ia->fg(); } - /// Returns factor -> var message (I->i) - DAI_ACCMUT(Prob & msgM( size_t i, size_t _I ), { return _msgs.m[i][_I]; }); - /// Returns var -> factor message (i->I) - DAI_ACCMUT(Prob & msgN( size_t i, size_t _I ), { return _msgs.n[i][_I]; }); - /// Returns normalizer for msgM - DAI_ACCMUT(Real & zM( size_t i, size_t _I ), { return _msgs.Zm[i][_I]; }); - /// Returns normalizer for msgN - DAI_ACCMUT(Real & zN( size_t i, size_t _I ), { return _msgs.Zn[i][_I]; }); + /// Returns reference to factor -> var message (I->i) + Prob & msgM( size_t i, size_t _I ) { return _msgs.m[i][_I]; } + /// Returns constant reference to factor -> var message (I->i) + const Prob & msgM( size_t i, size_t _I ) const { return _msgs.m[i][_I]; } + /// Returns reference to var -> factor message (i->I) + Prob & msgN( size_t i, size_t _I ) { return _msgs.n[i][_I]; } + /// Returns constant reference to var -> factor message (i->I) + const Prob & msgN( size_t i, size_t _I ) const { return _msgs.n[i][_I]; } + /// Returns reference to normalizer for msgM + Real & zM( size_t i, size_t _I ) { return _msgs.Zm[i][_I]; } + /// Returns constant reference to normalizer for msgM + const Real & zM( size_t i, size_t _I ) const { return _msgs.Zm[i][_I]; } + /// Returns reference to normalizer for msgN + Real & zN( size_t i, size_t _I ) { return _msgs.Zn[i][_I]; } + /// Returns constant reference to normalizer for msgN + const Real & zN( size_t i, size_t _I ) const { return _msgs.Zn[i][_I]; } /// Returns variable belief Factor beliefV( size_t i ) const { return Factor( _ia->fg().var(i), _beliefs.b1[i] ); } diff --git a/include/dai/util.h b/include/dai/util.h index 458084d..67a25f6 100644 --- a/include/dai/util.h +++ b/include/dai/util.h @@ -11,7 +11,6 @@ /// \file /// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality -/// \todo Improve documentation #ifndef __defined_libdai_util_h @@ -29,11 +28,11 @@ #if defined(WINDOWS) - #include + #include // an alternative would be to use boost/tr1/unordered_map.hpp #elif defined(CYGWIN) - #include + #include // only present in boost 1.37 and higher #else - #include + #include // only present in modern GCC distributions #endif @@ -55,17 +54,8 @@ #define DAI_DMSG(str) do {} while(0) #endif -/// Produces accessor and mutator methods according to the common pattern. -/** Example: - * \code DAI_ACCMUT(size_t& maxIter(), { return props.maxiter; }); \endcode - * \todo At the moment, only the mutator appears in doxygen documentation. - */ -#define DAI_ACCMUT(x,y) \ - x y; \ - const x const y; - -/// Macro to give error message \a stmt if props.verbose>=\a n -#define DAI_IFVERB(n, stmt) if(props.verbose>=n) { cerr << stmt; } +/// Macro to give error message \a stmt if props.verbose >= \a n +#define DAI_IFVERB(n, stmt) if(props.verbose>=n) { std::cerr << stmt; } #ifdef WINDOWS @@ -86,7 +76,7 @@ namespace dai { -/// Real number (alias for double, which could be changed to long double if necessary) +/// Real number (alias for \c double, which could be changed to long double if necessary) typedef double Real; /// Returns logarithm of \a x @@ -106,14 +96,14 @@ inline Real exp( Real x ) { #ifdef WINDOWS - /// hash_map is an alias for std::map. + /// hash_map is an alias for \c std::map. /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map. */ template > class hash_map : public std::map {}; #else - /// hash_map is an alias for std::tr1::unordered_map. - /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions. + /// hash_map is an alias for \c std::tr1::unordered_map. + /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions or in boost versions 1.37 and higher. */ template > class hash_map : public std::tr1::unordered_map {}; @@ -140,16 +130,16 @@ Real rnd_uniform(); /// Returns a real number from a standard-normal distribution Real rnd_stdnormal(); -/// Returns a random integer in interval [min, max] +/// Returns a random integer in interval [\a min, \a max] int rnd_int( int min, int max ); -/// Returns a random integer in the half-open interval \f$[0,n)\f$ +/// Returns a random integer in the half-open interval [0, \a n) inline int rnd( int n) { return rnd_int( 0, n-1 ); } -/// Writes a std::vector to a std::ostream +/// Writes a \c std::vector<> to a \c std::ostream template std::ostream& operator << (std::ostream& os, const std::vector & x) { os << "("; @@ -159,7 +149,7 @@ std::ostream& operator << (std::ostream& os, const std::vector & x) { return os; } -/// Writes a std::set to a std::ostream +/// Writes a \c std::set<> to a \c std::ostream template std::ostream& operator << (std::ostream& os, const std::set & x) { os << "{"; @@ -169,7 +159,7 @@ std::ostream& operator << (std::ostream& os, const std::set & x) { return os; } -/// Writes a std::map to a std::ostream +/// Writes a \c std::map<> to a \c std::ostream template std::ostream& operator << (std::ostream& os, const std::map & x) { os << "{"; @@ -179,14 +169,14 @@ std::ostream& operator << (std::ostream& os, const std::map & x) { return os; } -/// Writes a std::pair to a std::ostream +/// Writes a \c std::pair<> to a \c std::ostream template std::ostream& operator << (std::ostream& os, const std::pair & x) { os << "(" << x.first << ", " << x.second << ")"; return os; } -/// Concatenate two vectors +/// Concatenates two vectors template std::vector concat( const std::vector& u, const std::vector& v ) { std::vector w; @@ -198,10 +188,23 @@ std::vector concat( const std::vector& u, const std::vector& v ) { return w; } -/// Split a string into tokens +/// Split a string into tokens delimited by characters in \a delim void tokenizeString( const std::string& s, std::vector& outTokens, const std::string& delim="\t\n" ); -/// Used to keep track of the progress made by iterative algorithms +/// Used to keep track of the progress made by iterative algorithms. +/** A Diffs object stores an array of fixed size, containing the + * history of certain values (for example, the \f$\ell_\infty\f$ + * differences between all the old beliefs and the new beliefs + * in one pass of belief propagation updates). A new value can be + * registered by calling Diffs::push(); the BP algorithm would use + * this to register the difference between the old and a newly + * calculated belief. The Diffs object keeps track of the maximum + * value encountered in the last Diffs::maxSize() values registered. + * The maximum value can then be queried by Diffs::maxDiff(). The + * BP algorithm would use this maximum value to compare it with a + * given tolerance, and if the tolerance exceeds the maximum value, + * the algorithm has converged. + */ class Diffs : public std::vector { private: size_t _maxsize; @@ -210,19 +213,22 @@ class Diffs : public std::vector { std::vector::iterator _maxpos; public: /// Constructor + /** \param maxsize Maximum number of differences to store + * \param def Default value + */ Diffs(long maxsize, Real def) : std::vector(), _maxsize(maxsize), _def(def) { this->reserve(_maxsize); _pos = begin(); _maxpos = begin(); } - /// Returns maximum difference encountered + /// Returns maximum difference encountered so far Real maxDiff() { if( size() < _maxsize ) return _def; else return( *_maxpos ); } - /// Register new difference x + /// Register new difference \a x void push(Real x) { if( size() < _maxsize ) { push_back(x); @@ -248,7 +254,7 @@ class Diffs : public std::vector { } } } - /// Return maximum number of differences stored + /// Return maximum number of differences that can be stored size_t maxSize() { return _maxsize; } }; -- 2.20.1