e8ecdfcbc3bd3aab7c091bebdd58276bd107235a
[libdai.git] / include / dai / util.h
1 /* This file is part of libDAI - http://www.libdai.org/
2 *
3 * Copyright (c) 2006-2011, The libDAI authors. All rights reserved.
4 *
5 * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
6 */
7
8
9 /// \file
10 /// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality
11
12
13 #ifndef __defined_libdai_util_h
14 #define __defined_libdai_util_h
15
16
17 #include <string>
18 #include <vector>
19 #include <set>
20 #include <map>
21 #include <iostream>
22 #include <boost/foreach.hpp>
23 #include <boost/functional/hash.hpp>
24 #include <boost/lexical_cast.hpp>
25 #include <algorithm>
26 #include <cerrno>
27
28 #include <dai/exceptions.h>
29
30
31 #if defined(WINDOWS)
32 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
33 #elif defined(CYGWIN)
34 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
35 #elif defined(MACOSX)
36 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
37 #else
38 #include <tr1/unordered_map> // only present in modern GCC distributions
39 #endif
40
41
42 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
43 #define foreach BOOST_FOREACH
44
45 #ifdef DAI_DEBUG
46 /// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
47 /**
48 * Useful debugging macro to see what your code is doing.
49 * Example: \code DAI_PV(3+4) \endcode
50 * Output: \code 3+4= 7 \endcode
51 */
52 #define DAI_PV(x) do {std::cerr << #x "= " << (x) << std::endl;} while(0)
53 /// "Debugging message": Prints a message (only if DAI_DEBUG is defined)
54 #define DAI_DMSG(str) do {std::cerr << str << std::endl;} while(0)
55 #else
56 #define DAI_PV(x) do {} while(0)
57 #define DAI_DMSG(str) do {} while(0)
58 #endif
59
60 /// Macro to write message \a stmt to \c std::cerr if \a props.verbose >= \a n
61 #define DAI_IFVERB(n, stmt) if(props.verbose>=n) { std::cerr << stmt; }
62
63
64 #ifdef WINDOWS
65 /// Returns inverse hyperbolic tangent of argument
66 double atanh( double x );
67
68 /// Returns log(1+x)
69 double log1p( double x );
70
71 /// Define INFINITY
72 #define INFINITY (std::numeric_limits<Real>::infinity())
73 #endif
74
75
76 namespace dai {
77
78
79 /// Real number (alias for \c double, which could be changed to <tt>long double</tt> if necessary)
80 typedef double Real;
81
82 /// Returns true if argument is NAN (Not A Number)
83 bool isnan( Real x );
84
85 /// Returns logarithm of \a x
86 inline Real log( Real x ) {
87 return std::log(x);
88 }
89
90 /// Returns logarithm of \a x, or 0 if \a x == 0
91 inline Real log0( Real x ) {
92 return x ? std::log(x) : 0;
93 }
94
95 /// Returns exponent of \a x
96 inline Real exp( Real x ) {
97 return std::exp(x);
98 }
99
100 /// Returns \a to the power \a y
101 inline Real pow( Real x, Real y ) {
102 errno = 0;
103 Real result = std::pow(x, y);
104 DAI_DEBASSERT( errno == 0 );
105 return result;
106 }
107
108
109 /// hash_map is an alias for \c std::tr1::unordered_map.
110 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions or in boost versions 1.37 and higher.
111 */
112 template <typename T, typename U, typename H = boost::hash<T> >
113 class hash_map : public std::tr1::unordered_map<T,U,H> {};
114
115
116 /// Returns wall clock time in seconds
117 double toc();
118
119
120 /// Returns absolute value of \a t
121 template<class T>
122 inline T abs( const T &t ) {
123 return (t < 0) ? (-t) : t;
124 }
125
126
127 /// Sets the random seed
128 void rnd_seed( size_t seed );
129
130 /// Returns a real number, distributed uniformly on [0,1)
131 Real rnd_uniform();
132
133 /// Returns a real number from a standard-normal distribution
134 Real rnd_stdnormal();
135
136 /// Returns a random integer in interval [\a min, \a max]
137 int rnd_int( int min, int max );
138
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 );
142 }
143
144
145 /// Converts a variable of type \a T to a \c std::string by using a \c boost::lexical_cast
146 template<class T>
147 std::string toString( const T& x ) {
148 return boost::lexical_cast<std::string>(x);
149 }
150
151
152 /// Converts a variable of type std::string to \a T by using a \c boost::lexical_cast
153 template<class T>
154 T fromString( const std::string& x ) {
155 return boost::lexical_cast<T>(x);
156 }
157
158
159 /// Writes a \c std::vector<> to a \c std::ostream
160 template<class T>
161 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
162 os << "(";
163 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
164 os << (it != x.begin() ? ", " : "") << *it;
165 os << ")";
166 return os;
167 }
168
169 /// Writes a \c std::set<> to a \c std::ostream
170 template<class T>
171 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
172 os << "{";
173 for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
174 os << (it != x.begin() ? ", " : "") << *it;
175 os << "}";
176 return os;
177 }
178
179 /// Writes a \c std::map<> to a \c std::ostream
180 template<class T1, class T2>
181 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
182 os << "{";
183 for( typename std::map<T1,T2>::const_iterator it = x.begin(); it != x.end(); it++ )
184 os << (it != x.begin() ? ", " : "") << it->first << "->" << it->second;
185 os << "}";
186 return os;
187 }
188
189 /// Writes a \c std::pair<> to a \c std::ostream
190 template<class T1, class T2>
191 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
192 os << "(" << x.first << ", " << x.second << ")";
193 return os;
194 }
195
196 /// Concatenates two vectors
197 template<class T>
198 std::vector<T> concat( const std::vector<T>& u, const std::vector<T>& v ) {
199 std::vector<T> w;
200 w.reserve( u.size() + v.size() );
201 for( size_t i = 0; i < u.size(); i++ )
202 w.push_back( u[i] );
203 for( size_t i = 0; i < v.size(); i++ )
204 w.push_back( v[i] );
205 return w;
206 }
207
208 /// Split a string into tokens delimited by one of the characters in \a delim
209 /** \param s the string to be split into tokens
210 * \param singleDelim if \c true, any single delimiter forms a boundary between two tokens;
211 * if \c false, a maximal group of consecutive delimiters forms a boundary between two tokens
212 * \param delim delimiter characters
213 */
214 std::vector<std::string> tokenizeString( const std::string& s, bool singleDelim, const std::string& delim="\t\n" );
215
216
217 /// Enumerates different ways of normalizing a probability measure.
218 /**
219 * - NORMPROB means that the sum of all entries should be 1;
220 * - NORMLINF means that the maximum absolute value of all entries should be 1.
221 */
222 typedef enum { NORMPROB, NORMLINF } ProbNormType;
223
224 /// Enumerates different distance measures between probability measures.
225 /**
226 * - DISTL1 is the \f$\ell_1\f$ distance (sum of absolute values of pointwise difference);
227 * - DISTLINF is the \f$\ell_\infty\f$ distance (maximum absolute value of pointwise difference);
228 * - DISTTV is the total variation distance (half of the \f$\ell_1\f$ distance);
229 * - DISTKL is the Kullback-Leibler distance (\f$\sum_i p_i (\log p_i - \log q_i)\f$).
230 * - DISTHEL is the Hellinger distance (\f$\frac{1}{2}\sum_i (\sqrt{p_i}-\sqrt{q_i})^2\f$).
231 */
232 typedef enum { DISTL1, DISTLINF, DISTTV, DISTKL, DISTHEL } ProbDistType;
233
234
235 } // end of namespace dai
236
237
238 #endif