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; }
72 /// Returns true if argument is NAN (Not A Number)
73 bool isnan( double x
);
75 /// Returns inverse hyperbolic tangent of argument
76 double atanh( double x
);
79 double log1p( double x
);
82 #define INFINITY (std::numeric_limits<double>::infinity())
89 /// Real number (alias for double, which could be changed to long double if necessary)
92 /// Returns logarithm of \a x
93 inline Real
log( Real x
) {
97 /// Returns exponent of \a x
98 inline Real
exp( Real x
) {
104 /// hash_map is an alias for std::map.
105 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
107 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
108 class hash_map
: public std::map
<T
,U
> {};
110 /// hash_map is an alias for std::tr1::unordered_map.
111 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
113 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
114 class hash_map
: public std::tr1::unordered_map
<T
,U
,H
> {};
118 /// Returns wall clock time in seconds
122 /// Returns absolute value of \a t
124 inline T
abs( const T
&t
) {
125 return (t
< 0) ? (-t
) : t
;
129 /// Sets the random seed
130 void rnd_seed( size_t seed
);
132 /// Returns a real number, distributed uniformly on [0,1)
135 /// Returns a real number from a standard-normal distribution
136 Real
rnd_stdnormal();
138 /// Returns a random integer in interval [min, max]
139 int rnd_int( int min
, int max
);
141 /// Returns a random integer in the half-open interval \f$[0,n)\f$
142 inline int rnd( int n
) {
143 return rnd_int( 0, n
-1 );
147 /// Writes a std::vector to a std::ostream
149 std::ostream
& operator << (std::ostream
& os
, const std::vector
<T
> & x
) {
151 for( typename
std::vector
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
152 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
157 /// Writes a std::set to a std::ostream
159 std::ostream
& operator << (std::ostream
& os
, const std::set
<T
> & x
) {
161 for( typename
std::set
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
162 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
167 /// Writes a std::map to a std::ostream
168 template<class T1
, class T2
>
169 std::ostream
& operator << (std::ostream
& os
, const std::map
<T1
,T2
> & x
) {
171 for( typename
std::map
<T1
,T2
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
172 os
<< (it
!= x
.begin() ? ", " : "") << it
->first
<< "->" << it
->second
;
177 /// Writes a std::pair to a std::ostream
178 template<class T1
, class T2
>
179 std::ostream
& operator << (std::ostream
& os
, const std::pair
<T1
,T2
> & x
) {
180 os
<< "(" << x
.first
<< ", " << x
.second
<< ")";
184 /// Concatenate two vectors
186 std::vector
<T
> concat( const std::vector
<T
>& u
, const std::vector
<T
>& v
) {
188 w
.reserve( u
.size() + v
.size() );
189 for( size_t i
= 0; i
< u
.size(); i
++ )
191 for( size_t i
= 0; i
< v
.size(); i
++ )
196 /// Split a string into tokens
197 void tokenizeString( const std::string
& s
, std::vector
<std::string
>& outTokens
, const std::string
& delim
="\t\n" );
199 /// Used to keep track of the progress made by iterative algorithms
200 class Diffs
: public std::vector
<double> {
204 std::vector
<double>::iterator _pos
;
205 std::vector
<double>::iterator _maxpos
;
208 Diffs(long maxsize
, double def
) : std::vector
<double>(), _maxsize(maxsize
), _def(def
) {
209 this->reserve(_maxsize
);
213 /// Returns maximum difference encountered
215 if( size() < _maxsize
)
220 /// Register new difference x
221 void push(double x
) {
222 if( size() < _maxsize
) {
226 if( *_maxpos
< back() ) {
236 if( _maxpos
== _pos
) {
238 _maxpos
= max_element(begin(),end());
246 /// Return maximum number of differences stored
247 size_t maxSize() { return _maxsize
; }
251 } // end of namespace dai