7934e3be415c30a4d9b2ef8a314c4c5228b841ed
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)
53 /// Assertion if DAI_DEBUG is defined
54 #define DAI_DEBASSERT(x) do {assert(x);} while(0)
56 #define DAI_PV(x) do {} while(0)
57 #define DAI_DMSG(str) do {} while(0)
58 #define DAI_DEBASSERT(X) do {} while(0)
61 /// Produces accessor and mutator methods according to the common pattern.
63 * \code DAI_ACCMUT(size_t& maxIter(), { return props.maxiter; }); \endcode
64 * \todo At the moment, only the mutator appears in doxygen documentation.
66 #define DAI_ACCMUT(x,y) \
70 /// Macro to give error message \a stmt if props.verbose>=\a n
71 #define DAI_IFVERB(n, stmt) if(props.verbose>=n) { cerr << stmt; }
74 /// Real number (alias for double, which could be changed to long double if necessary)
79 /// Returns true if argument is NAN (Not A Number)
80 bool isnan( double x
);
82 /// Returns inverse hyperbolic tangent of argument
83 double atanh( double x
);
86 double log1p( double x
);
89 #define INFINITY (std::numeric_limits<double>::infinity())
97 /// hash_map is an alias for std::map.
98 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
100 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
101 class hash_map
: public std::map
<T
,U
> {};
103 /// hash_map is an alias for std::tr1::unordered_map.
104 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
106 template <typename T
, typename U
, typename H
= boost::hash
<T
> >
107 class hash_map
: public std::tr1::unordered_map
<T
,U
,H
> {};
111 /// Returns wall clock time in seconds
115 /// Sets the random seed
116 void rnd_seed( size_t seed
);
118 /// Returns a real number, distributed uniformly on [0,1)
119 double rnd_uniform();
121 /// Returns a real number from a standard-normal distribution
122 double rnd_stdnormal();
124 /// Returns a random integer in interval [min, max]
125 int rnd_int( int min
, int max
);
127 /// Returns a random integer in the half-open interval \f$[0,n)\f$
128 inline int rnd( int n
) {
129 return rnd_int( 0, n
-1 );
133 /// Writes a std::vector to a std::ostream
135 std::ostream
& operator << (std::ostream
& os
, const std::vector
<T
> & x
) {
137 for( typename
std::vector
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
138 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
143 /// Writes a std::set to a std::ostream
145 std::ostream
& operator << (std::ostream
& os
, const std::set
<T
> & x
) {
147 for( typename
std::set
<T
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
148 os
<< (it
!= x
.begin() ? ", " : "") << *it
;
153 /// Writes a std::map to a std::ostream
154 template<class T1
, class T2
>
155 std::ostream
& operator << (std::ostream
& os
, const std::map
<T1
,T2
> & x
) {
157 for( typename
std::map
<T1
,T2
>::const_iterator it
= x
.begin(); it
!= x
.end(); it
++ )
158 os
<< (it
!= x
.begin() ? ", " : "") << it
->first
<< "->" << it
->second
;
163 /// Writes a std::pair to a std::ostream
164 template<class T1
, class T2
>
165 std::ostream
& operator << (std::ostream
& os
, const std::pair
<T1
,T2
> & x
) {
166 os
<< "(" << x
.first
<< ", " << x
.second
<< ")";
170 /// Concatenate two vectors
172 std::vector
<T
> concat( const std::vector
<T
>& u
, const std::vector
<T
>& v
) {
174 w
.reserve( u
.size() + v
.size() );
175 for( size_t i
= 0; i
< u
.size(); i
++ )
177 for( size_t i
= 0; i
< v
.size(); i
++ )
182 /// Split a string into tokens
183 void tokenizeString( const std::string
& s
, std::vector
<std::string
>& outTokens
, const std::string
& delim
="\t\n" );
185 /// Used to keep track of the progress made by iterative algorithms
186 class Diffs
: public std::vector
<double> {
190 std::vector
<double>::iterator _pos
;
191 std::vector
<double>::iterator _maxpos
;
194 Diffs(long maxsize
, double def
) : std::vector
<double>(), _maxsize(maxsize
), _def(def
) {
195 this->reserve(_maxsize
);
199 /// Returns maximum difference encountered
201 if( size() < _maxsize
)
206 /// Register new difference x
207 void push(double x
) {
208 if( size() < _maxsize
) {
212 if( *_maxpos
< back() ) {
222 if( _maxpos
== _pos
) {
224 _maxpos
= max_element(begin(),end());
232 /// Return maximum number of differences stored
233 size_t maxSize() { return _maxsize
; }
237 } // end of namespace dai