Fixed division-by-zero issue in pow() which caused problems for GLC+ with sparse...
[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 #if defined(WINDOWS)
29 #include <cstdint> // only defined in C++11 and higher, but needed for Win64 builds in order to enable conditional code in MPIR library
30 #endif
31 #include <gmpxx.h>
32
33 #include <dai/exceptions.h>
34
35
36 #if defined(WINDOWS)
37 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
38 #elif defined(CYGWIN)
39 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
40 #elif defined(MACOSX)
41 #include <boost/tr1/unordered_map.hpp> // only present in boost 1.37 and higher
42 #else
43 #include <tr1/unordered_map> // only present in modern GCC distributions
44 #endif
45
46
47 /// An alias to the BOOST_FOREACH macro from the boost::bforeach library
48 #define bforeach BOOST_FOREACH
49
50 #ifdef DAI_DEBUG
51 /// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
52 /**
53 * Useful debugging macro to see what your code is doing.
54 * Example: \code DAI_PV(3+4) \endcode
55 * Output: \code 3+4= 7 \endcode
56 */
57 #define DAI_PV(x) do {std::cerr << #x "= " << (x) << std::endl;} while(0)
58 /// "Debugging message": Prints a message (only if DAI_DEBUG is defined)
59 #define DAI_DMSG(str) do {std::cerr << str << std::endl;} while(0)
60 #else
61 #define DAI_PV(x) do {} while(0)
62 #define DAI_DMSG(str) do {} while(0)
63 #endif
64
65 /// Macro to write message \a stmt to \c std::cerr if \a props.verbose >= \a n
66 #define DAI_IFVERB(n, stmt) if(props.verbose>=n) { std::cerr << stmt; }
67
68
69 #ifdef WINDOWS
70 /// Returns inverse hyperbolic tangent of argument
71 double atanh( double x );
72
73 /// Returns log(1+x)
74 double log1p( double x );
75
76 /// Define INFINITY
77 #define INFINITY (std::numeric_limits<Real>::infinity())
78
79 /// Define NAN
80 #define NAN (std::numeric_limits<Real>::quiet_NaN())
81
82 #if defined(_MSC_VER)
83 // Disable unsafe warning (use of the function 'strcpy' instead of
84 // 'strcpy_s' for portability reasons;
85 #pragma warning( disable : 4996 )
86 // Workaround for the char16_t type defined in Matlab and MSVC 2010
87 #if (_MSC_VER >= 1600)
88 #define __STDC_UTF_16__
89 #endif
90 #endif
91 #endif
92
93
94 namespace dai {
95
96
97 /// Real number (alias for \c double, which could be changed to <tt>long double</tt> if necessary)
98 typedef double Real;
99
100 /// Arbitrary precision integer number
101 typedef mpz_class BigInt;
102
103 /// Safe down-cast of big integer to size_t
104 inline size_t BigInt_size_t( const BigInt &N ) {
105 DAI_ASSERT( N <= (BigInt)std::numeric_limits<std::size_t>::max() );
106 return N.get_ui();
107 }
108
109 /// Returns true if argument is NAN (Not A Number)
110 bool isnan( Real x );
111
112 /// Returns logarithm of \a x
113 inline Real log( Real x ) {
114 return std::log(x);
115 }
116
117 /// Returns logarithm of \a x, or 0 if \a x == 0
118 inline Real log0( Real x ) {
119 return x ? std::log(x) : 0;
120 }
121
122 /// Returns exponent of \a x
123 inline Real exp( Real x ) {
124 return std::exp(x);
125 }
126
127 /// Returns \a x to the power \a y
128 /** We use the convention that division by zero yields zero;
129 * for powers, this means that if \a x == 0.0 and \a y < 0.0, we
130 * return 0.0 instead of generating an error.
131 */
132 inline Real pow( Real x, Real y ) {
133 errno = 0;
134 if( x == 0.0 && y < 0.0 )
135 return 0.0;
136 Real result = std::pow(x, y);
137 DAI_DEBASSERT( errno == 0 );
138 return result;
139 }
140
141
142 /// hash_map is an alias for \c std::tr1::unordered_map.
143 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions or in boost versions 1.37 and higher.
144 */
145 template <typename T, typename U, typename H = boost::hash<T> >
146 class hash_map : public std::tr1::unordered_map<T,U,H> {};
147
148
149 /// Returns wall clock time in seconds
150 double toc();
151
152
153 /// Returns absolute value of \a t
154 template<class T>
155 inline T abs( const T &t ) {
156 return (t < 0) ? (-t) : t;
157 }
158
159
160 /// Sets the random seed
161 void rnd_seed( size_t seed );
162
163 /// Returns a real number, distributed uniformly on [0,1)
164 Real rnd_uniform();
165
166 /// Returns a real number from a standard-normal distribution
167 Real rnd_stdnormal();
168
169 /// Returns a random integer in interval [\a min, \a max]
170 int rnd_int( int min, int max );
171
172 /// Returns a random integer in the half-open interval [0, \a n)
173 inline int rnd( int n ) {
174 return rnd_int( 0, n-1 );
175 }
176
177
178 /// Converts a variable of type \a T to a \c std::string by using a \c boost::lexical_cast
179 template<class T>
180 std::string toString( const T& x ) {
181 return boost::lexical_cast<std::string>(x);
182 }
183
184
185 /// Converts a variable of type std::string to \a T by using a \c boost::lexical_cast
186 template<class T>
187 T fromString( const std::string& x ) {
188 return boost::lexical_cast<T>(x);
189 }
190
191
192 /// Writes a \c std::vector<> to a \c std::ostream
193 template<class T>
194 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
195 os << "(";
196 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
197 os << (it != x.begin() ? ", " : "") << *it;
198 os << ")";
199 return os;
200 }
201
202 /// Writes a \c std::set<> to a \c std::ostream
203 template<class T>
204 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
205 os << "{";
206 for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
207 os << (it != x.begin() ? ", " : "") << *it;
208 os << "}";
209 return os;
210 }
211
212 /// Writes a \c std::map<> to a \c std::ostream
213 template<class T1, class T2>
214 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
215 os << "{";
216 for( typename std::map<T1,T2>::const_iterator it = x.begin(); it != x.end(); it++ )
217 os << (it != x.begin() ? ", " : "") << it->first << "->" << it->second;
218 os << "}";
219 return os;
220 }
221
222 /// Writes a \c std::pair<> to a \c std::ostream
223 template<class T1, class T2>
224 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
225 os << "(" << x.first << ", " << x.second << ")";
226 return os;
227 }
228
229 /// Concatenates two vectors
230 template<class T>
231 std::vector<T> concat( const std::vector<T>& u, const std::vector<T>& v ) {
232 std::vector<T> w;
233 w.reserve( u.size() + v.size() );
234 for( size_t i = 0; i < u.size(); i++ )
235 w.push_back( u[i] );
236 for( size_t i = 0; i < v.size(); i++ )
237 w.push_back( v[i] );
238 return w;
239 }
240
241 /// Split a string into tokens delimited by one of the characters in \a delim
242 /** \param s the string to be split into tokens
243 * \param singleDelim if \c true, any single delimiter forms a boundary between two tokens;
244 * if \c false, a maximal group of consecutive delimiters forms a boundary between two tokens
245 * \param delim delimiter characters
246 */
247 std::vector<std::string> tokenizeString( const std::string& s, bool singleDelim, const std::string& delim="\t\n" );
248
249
250 /// Enumerates different ways of normalizing a probability measure.
251 /**
252 * - NORMPROB means that the sum of all entries should be 1;
253 * - NORMLINF means that the maximum absolute value of all entries should be 1.
254 */
255 typedef enum { NORMPROB, NORMLINF } ProbNormType;
256
257 /// Enumerates different distance measures between probability measures.
258 /**
259 * - DISTL1 is the \f$\ell_1\f$ distance (sum of absolute values of pointwise difference);
260 * - DISTLINF is the \f$\ell_\infty\f$ distance (maximum absolute value of pointwise difference);
261 * - DISTTV is the total variation distance (half of the \f$\ell_1\f$ distance);
262 * - DISTKL is the Kullback-Leibler distance (\f$\sum_i p_i (\log p_i - \log q_i)\f$).
263 * - DISTHEL is the Hellinger distance (\f$\frac{1}{2}\sum_i (\sqrt{p_i}-\sqrt{q_i})^2\f$).
264 */
265 typedef enum { DISTL1, DISTLINF, DISTTV, DISTKL, DISTHEL } ProbDistType;
266
267
268 } // end of namespace dai
269
270
271 #endif