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
16 #ifndef __defined_libdai_util_h
17 #define __defined_libdai_util_h
25 #include <boost/foreach.hpp>
26 #include <boost/functional/hash.hpp>
31 #include <map> // an alternative would be to use boost/tr1/unordered_map.hpp
33 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
35 #include <tr1/unordered_map> // only present in modern GCC distributions
39 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
40 #define foreach BOOST_FOREACH
43 /// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
45 * Useful debugging macro to see what your code is doing.
46 * Example: \code DAI_PV(3+4) \endcode
47 * Output: \code 3+4= 7 \endcode
49 #define DAI_PV(x) do {std::cerr << #x "= " << (x) << std::endl;} while(0)
50 /// "Debugging message": Prints a message (only if DAI_DEBUG is defined)
51 #define DAI_DMSG(str) do {std::cerr << str << std::endl;} while(0)
53 #define DAI_PV(x) do {} while(0)
54 #define DAI_DMSG(str) do {} while(0)
57 /// Macro to write message \a stmt to \c std::cerr if \a props.verbose >= \a n
58 #define DAI_IFVERB(n, stmt) if(props.verbose>=n) { std::cerr << stmt; }
62 /// Returns true if argument is NAN (Not A Number)
63 bool isnan( double x
);
65 /// Returns inverse hyperbolic tangent of argument
66 double atanh( double x
);
69 double log1p( double x
);
72 #define INFINITY (std::numeric_limits<Real>::infinity())
79 /// Real number (alias for \c double, which could be changed to <tt>long double</tt> if necessary)
82 /// Returns logarithm of \a x
83 inline Real
log( Real x
) {
87 /// Returns logarithm of \a x, or 0 if \a x == 0
88 inline Real
log0( Real x
) {
89 return x
? std::log(x
) : 0;
92 /// Returns exponent of \a x
93 inline Real
exp( Real x
) {
97 /// Returns maximum value of a std::vector<Real>
98 Real
max( std::vector
<Real
> v
);
102 /// hash_map is an alias for \c std::map.
103 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
105 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
106 class hash_map
: public std::map
<T
,U
> {};
108 /// hash_map is an alias for \c std::tr1::unordered_map.
109 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions or in boost versions 1.37 and higher.
111 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
112 class hash_map
: public std::tr1::unordered_map
<T
,U
,H
> {};
116 /// Returns wall clock time in seconds
120 /// Returns absolute value of \a t
122 inline T
abs( const T
&t
) {
123 return (t
< 0) ? (-t
) : t
;
127 /// Sets the random seed
128 void rnd_seed( size_t seed
);
130 /// Returns a real number, distributed uniformly on [0,1)
133 /// Returns a real number from a standard-normal distribution
134 Real
rnd_stdnormal();
136 /// Returns a random integer in interval [\a min, \a max]
137 int rnd_int( int min
, int max
);
139 /// Returns a random integer in the half-open interval [0, \a n)
140 inline int rnd( int n
) {
141 return rnd_int( 0, n
-1 );
145 /// Writes a \c std::vector<> to a \c std::ostream
147 std::ostream
& operator << (std::ostream
& os
, const std::vector
<T
> & x
) {
149 for( typename
std::vector
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
150 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
155 /// Writes a \c std::set<> to a \c std::ostream
157 std::ostream
& operator << (std::ostream
& os
, const std::set
<T
> & x
) {
159 for( typename
std::set
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
160 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
165 /// Writes a \c std::map<> to a \c std::ostream
166 template<class T1
, class T2
>
167 std::ostream
& operator << (std::ostream
& os
, const std::map
<T1
,T2
> & x
) {
169 for( typename
std::map
<T1
,T2
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
170 os
<< (it
!= x
.begin() ? ", " : "") << it
->first
<< "->" << it
->second
;
175 /// Writes a \c std::pair<> to a \c std::ostream
176 template<class T1
, class T2
>
177 std::ostream
& operator << (std::ostream
& os
, const std::pair
<T1
,T2
> & x
) {
178 os
<< "(" << x
.first
<< ", " << x
.second
<< ")";
182 /// Concatenates two vectors
184 std::vector
<T
> concat( const std::vector
<T
>& u
, const std::vector
<T
>& v
) {
186 w
.reserve( u
.size() + v
.size() );
187 for( size_t i
= 0; i
< u
.size(); i
++ )
189 for( size_t i
= 0; i
< v
.size(); i
++ )
194 /// Split a string into tokens delimited by characters in \a delim
195 void tokenizeString( const std::string
& s
, std::vector
<std::string
>& outTokens
, const std::string
& delim
="\t\n" );
198 /// Used to keep track of the progress made by iterative algorithms.
199 /** \deprecated Superfluous, because a simple std::vector<Real> provides the same functionality
201 class Diffs
: public std::vector
<Real
> {
205 std::vector
<Real
>::iterator _pos
;
206 std::vector
<Real
>::iterator _maxpos
;
209 /** \param maxsize Maximum number of differences to store
210 * \param def Default value
212 Diffs(long maxsize
, Real def
) : std::vector
<Real
>(), _maxsize(maxsize
), _def(def
) {
213 this->reserve(_maxsize
);
217 /// Returns maximum difference encountered so far
219 if( size() < _maxsize
)
224 /// Register new difference \a x
226 if( size() < _maxsize
) {
230 if( *_maxpos
< back() ) {
240 if( _maxpos
== _pos
) {
242 _maxpos
= max_element(begin(),end());
250 /// Return maximum number of differences that can be stored
251 size_t maxSize() { return _maxsize
; }
255 } // end of namespace dai