1 /* This file is part of libDAI - http://www.libdai.org/
3 * libDAI is licensed under the terms of the GNU General Public License version
4 * 2, or (at your option) any later version. libDAI is distributed without any
5 * warranty. See the file COPYING for more details.
7 * Copyright (C) 2006-2009 Joris Mooij [joris dot mooij at libdai dot org]
8 * Copyright (C) 2006-2007 Radboud University Nijmegen, The Netherlands
13 /// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality
14 /// \todo Improve documentation
17 #ifndef __defined_libdai_util_h
18 #define __defined_libdai_util_h
26 #include <boost/foreach.hpp>
27 #include <boost/functional/hash.hpp>
34 #include <boost/tr1/unordered_map.hpp>
36 #include <tr1/unordered_map>
40 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
41 #define foreach BOOST_FOREACH
44 /// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
46 * Useful debugging macro to see what your code is doing.
47 * Example: \code DAI_PV(3+4) \endcode
48 * Output: \code 3+4= 7 \endcode
50 #define DAI_PV(x) do {std::cerr << #x "= " << (x) << std::endl;} while(0)
51 /// "Debugging message": Prints a message (only if DAI_DEBUG is defined)
52 #define DAI_DMSG(str) do {std::cerr << str << std::endl;} while(0)
54 #define DAI_PV(x) do {} while(0)
55 #define DAI_DMSG(str) do {} while(0)
58 /// Produces accessor and mutator methods according to the common pattern.
60 * \code DAI_ACCMUT(size_t& maxIter(), { return props.maxiter; }); \endcode
61 * \todo At the moment, only the mutator appears in doxygen documentation.
63 #define DAI_ACCMUT(x,y) \
67 /// Macro to give error message \a stmt if props.verbose>=\a n
68 #define DAI_IFVERB(n, stmt) if(props.verbose>=n) { cerr << stmt; }
71 /// Real number (alias for double, which could be changed to long double if necessary)
76 /// Returns true if argument is NAN (Not A Number)
77 bool isnan( double x
);
79 /// Returns inverse hyperbolic tangent of argument
80 double atanh( double x
);
83 double log1p( double x
);
86 #define INFINITY (std::numeric_limits<double>::infinity())
94 /// hash_map is an alias for std::map.
95 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
97 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
98 class hash_map
: public std::map
<T
,U
> {};
100 /// hash_map is an alias for std::tr1::unordered_map.
101 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
103 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
104 class hash_map
: public std::tr1::unordered_map
<T
,U
,H
> {};
108 /// Returns wall clock time in seconds
112 /// Sets the random seed
113 void rnd_seed( size_t seed
);
115 /// Returns a real number, distributed uniformly on [0,1)
116 double rnd_uniform();
118 /// Returns a real number from a standard-normal distribution
119 double rnd_stdnormal();
121 /// Returns a random integer in interval [min, max]
122 int rnd_int( int min
, int max
);
124 /// Returns a random integer in the half-open interval \f$[0,n)\f$
125 inline int rnd( int n
) {
126 return rnd_int( 0, n
-1 );
130 /// Writes a std::vector to a std::ostream
132 std::ostream
& operator << (std::ostream
& os
, const std::vector
<T
> & x
) {
134 for( typename
std::vector
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
135 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
140 /// Writes a std::set to a std::ostream
142 std::ostream
& operator << (std::ostream
& os
, const std::set
<T
> & x
) {
144 for( typename
std::set
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
145 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
150 /// Writes a std::map to a std::ostream
151 template<class T1
, class T2
>
152 std::ostream
& operator << (std::ostream
& os
, const std::map
<T1
,T2
> & x
) {
154 for( typename
std::map
<T1
,T2
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
155 os
<< (it
!= x
.begin() ? ", " : "") << it
->first
<< "->" << it
->second
;
160 /// Writes a std::pair to a std::ostream
161 template<class T1
, class T2
>
162 std::ostream
& operator << (std::ostream
& os
, const std::pair
<T1
,T2
> & x
) {
163 os
<< "(" << x
.first
<< ", " << x
.second
<< ")";
167 /// Concatenate two vectors
169 std::vector
<T
> concat( const std::vector
<T
>& u
, const std::vector
<T
>& v
) {
171 w
.reserve( u
.size() + v
.size() );
172 for( size_t i
= 0; i
< u
.size(); i
++ )
174 for( size_t i
= 0; i
< v
.size(); i
++ )
179 /// Split a string into tokens
180 void tokenizeString( const std::string
& s
, std::vector
<std::string
>& outTokens
, const std::string
& delim
="\t\n" );
182 /// Used to keep track of the progress made by iterative algorithms
183 class Diffs
: public std::vector
<double> {
187 std::vector
<double>::iterator _pos
;
188 std::vector
<double>::iterator _maxpos
;
191 Diffs(long maxsize
, double def
) : std::vector
<double>(), _maxsize(maxsize
), _def(def
) {
192 this->reserve(_maxsize
);
196 /// Returns maximum difference encountered
198 if( size() < _maxsize
)
203 /// Register new difference x
204 void push(double x
) {
205 if( size() < _maxsize
) {
209 if( *_maxpos
< back() ) {
219 if( _maxpos
== _pos
) {
221 _maxpos
= max_element(begin(),end());
229 /// Return maximum number of differences stored
230 size_t maxSize() { return _maxsize
; }
234 } // end of namespace dai