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