Cleaned up TProb<T> and some misc other stuff, improved State class, and
[libdai.git] / include / dai / util.h
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
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.
6 *
7 * Copyright (C) 2006-2009 Joris Mooij [joris dot mooij at libdai dot org]
8 * Copyright (C) 2006-2007 Radboud University Nijmegen, The Netherlands
9 */
10
11
12 /// \file
13 /// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality
14 /// \todo Improve documentation
15
16
17 #ifndef __defined_libdai_util_h
18 #define __defined_libdai_util_h
19
20
21 #include <string>
22 #include <vector>
23 #include <set>
24 #include <map>
25 #include <iostream>
26 #include <boost/foreach.hpp>
27 #include <boost/functional/hash.hpp>
28 #include <algorithm>
29
30
31 #if defined(WINDOWS)
32 #include <map>
33 #elif defined(CYGWIN)
34 #include <boost/tr1/unordered_map.hpp>
35 #else
36 #include <tr1/unordered_map>
37 #endif
38
39
40 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
41 #define foreach BOOST_FOREACH
42
43 #ifdef DAI_DEBUG
44 /// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
45 /**
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
49 */
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 #else
54 #define DAI_PV(x) do {} while(0)
55 #define DAI_DMSG(str) do {} while(0)
56 #endif
57
58 /// Produces accessor and mutator methods according to the common pattern.
59 /** Example:
60 * \code DAI_ACCMUT(size_t& maxIter(), { return props.maxiter; }); \endcode
61 * \todo At the moment, only the mutator appears in doxygen documentation.
62 */
63 #define DAI_ACCMUT(x,y) \
64 x y; \
65 const x const y;
66
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; }
69
70
71 #ifdef WINDOWS
72 /// Returns true if argument is NAN (Not A Number)
73 bool isnan( double x );
74
75 /// Returns inverse hyperbolic tangent of argument
76 double atanh( double x );
77
78 /// Returns log(1+x)
79 double log1p( double x );
80
81 /// Define INFINITY
82 #define INFINITY (std::numeric_limits<Real>::infinity())
83 #endif
84
85
86 namespace dai {
87
88
89 /// Real number (alias for double, which could be changed to long double if necessary)
90 typedef double Real;
91
92 /// Returns logarithm of \a x
93 inline Real log( Real x ) {
94 return std::log(x);
95 }
96
97 /// Returns logarithm of \a x, or 0 if \a x == 0
98 inline Real log0( Real x ) {
99 return x ? std::log(x) : 0;
100 }
101
102 /// Returns exponent of \a x
103 inline Real exp( Real x ) {
104 return std::exp(x);
105 }
106
107
108 #ifdef WINDOWS
109 /// hash_map is an alias for std::map.
110 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
111 */
112 template <typename T, typename U, typename H = boost::hash<T> >
113 class hash_map : public std::map<T,U> {};
114 #else
115 /// hash_map is an alias for std::tr1::unordered_map.
116 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
117 */
118 template <typename T, typename U, typename H = boost::hash<T> >
119 class hash_map : public std::tr1::unordered_map<T,U,H> {};
120 #endif
121
122
123 /// Returns wall clock time in seconds
124 double toc();
125
126
127 /// Returns absolute value of \a t
128 template<class T>
129 inline T abs( const T &t ) {
130 return (t < 0) ? (-t) : t;
131 }
132
133
134 /// Sets the random seed
135 void rnd_seed( size_t seed );
136
137 /// Returns a real number, distributed uniformly on [0,1)
138 Real rnd_uniform();
139
140 /// Returns a real number from a standard-normal distribution
141 Real rnd_stdnormal();
142
143 /// Returns a random integer in interval [min, max]
144 int rnd_int( int min, int max );
145
146 /// Returns a random integer in the half-open interval \f$[0,n)\f$
147 inline int rnd( int n) {
148 return rnd_int( 0, n-1 );
149 }
150
151
152 /// Writes a std::vector to a std::ostream
153 template<class T>
154 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
155 os << "(";
156 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
157 os << (it != x.begin() ? ", " : "") << *it;
158 os << ")";
159 return os;
160 }
161
162 /// Writes a std::set to a std::ostream
163 template<class T>
164 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
165 os << "{";
166 for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
167 os << (it != x.begin() ? ", " : "") << *it;
168 os << "}";
169 return os;
170 }
171
172 /// Writes a std::map to a std::ostream
173 template<class T1, class T2>
174 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
175 os << "{";
176 for( typename std::map<T1,T2>::const_iterator it = x.begin(); it != x.end(); it++ )
177 os << (it != x.begin() ? ", " : "") << it->first << "->" << it->second;
178 os << "}";
179 return os;
180 }
181
182 /// Writes a std::pair to a std::ostream
183 template<class T1, class T2>
184 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
185 os << "(" << x.first << ", " << x.second << ")";
186 return os;
187 }
188
189 /// Concatenate two vectors
190 template<class T>
191 std::vector<T> concat( const std::vector<T>& u, const std::vector<T>& v ) {
192 std::vector<T> w;
193 w.reserve( u.size() + v.size() );
194 for( size_t i = 0; i < u.size(); i++ )
195 w.push_back( u[i] );
196 for( size_t i = 0; i < v.size(); i++ )
197 w.push_back( v[i] );
198 return w;
199 }
200
201 /// Split a string into tokens
202 void tokenizeString( const std::string& s, std::vector<std::string>& outTokens, const std::string& delim="\t\n" );
203
204 /// Used to keep track of the progress made by iterative algorithms
205 class Diffs : public std::vector<Real> {
206 private:
207 size_t _maxsize;
208 Real _def;
209 std::vector<Real>::iterator _pos;
210 std::vector<Real>::iterator _maxpos;
211 public:
212 /// Constructor
213 Diffs(long maxsize, Real def) : std::vector<Real>(), _maxsize(maxsize), _def(def) {
214 this->reserve(_maxsize);
215 _pos = begin();
216 _maxpos = begin();
217 }
218 /// Returns maximum difference encountered
219 Real maxDiff() {
220 if( size() < _maxsize )
221 return _def;
222 else
223 return( *_maxpos );
224 }
225 /// Register new difference x
226 void push(Real x) {
227 if( size() < _maxsize ) {
228 push_back(x);
229 _pos = end();
230 if( size() > 1 ) {
231 if( *_maxpos < back() ) {
232 _maxpos = end();
233 _maxpos--;
234 }
235 } else {
236 _maxpos = begin();
237 }
238 } else {
239 if( _pos == end() )
240 _pos = begin();
241 if( _maxpos == _pos ) {
242 *_pos++ = x;
243 _maxpos = max_element(begin(),end());
244 } else {
245 if( x > *_maxpos )
246 _maxpos = _pos;
247 *_pos++ = x;
248 }
249 }
250 }
251 /// Return maximum number of differences stored
252 size_t maxSize() { return _maxsize; }
253 };
254
255
256 } // end of namespace dai
257
258
259 #endif