New git HEAD version
[libdai.git] / src / util.cpp
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 #include <dai/util.h>
10 #include <boost/random.hpp>
11
12 #ifdef WINDOWS
13 #include <windows.h>
14 #include <boost/math/special_functions/atanh.hpp> // for atanh
15 #include <boost/math/special_functions/log1p.hpp> // for log1p
16 #include <float.h> // for _isnan
17 #else
18 // Assume POSIX compliant system. We need the following for querying the system time
19 #include <sys/time.h>
20 #endif
21
22
23 #ifdef WINDOWS
24 double atanh( double x ) {
25 return boost::math::atanh( x );
26 }
27 double log1p( double x ) {
28 return boost::math::log1p( x );
29 }
30 #endif
31
32
33 namespace dai {
34
35 #if defined CYGWIN
36 bool isnan( Real x ) {
37 return __isnand( x ); // isnan() is a macro in Cygwin (as required by C99)
38 }
39 #elif defined WINDOWS
40 bool isnan( Real x ) {
41 return _isnan( x );
42 }
43 #else
44 bool isnan( Real x ) {
45 return std::isnan( x );
46 }
47 #endif
48
49 // Returns user+system time in seconds
50 double toc() {
51 #ifdef WINDOWS
52 SYSTEMTIME tbuf;
53 GetSystemTime(&tbuf);
54 return( (double)(tbuf.wSecond + (double)tbuf.wMilliseconds / 1000.0) );
55 #else
56 struct timeval tv;
57 struct timezone tz;
58 gettimeofday( &tv, &tz );
59 return( (double)(tv.tv_sec + (double)tv.tv_usec / 1000000.0) );
60 #endif
61 }
62
63 /// Type of global random number generator
64 typedef boost::mt19937 _rnd_gen_type;
65
66 /// Global random number generator
67 _rnd_gen_type _rnd_gen(42U);
68
69 /// Uniform distribution with values between 0 and 1 (0 inclusive, 1 exclusive).
70 boost::uniform_real<Real> _uni_dist(0,1);
71
72 /// Normal distribution with mean 0 and standard deviation 1.
73 boost::normal_distribution<Real> _normal_dist;
74
75 /// Global uniform random random number
76 boost::variate_generator<_rnd_gen_type&, boost::uniform_real<Real> > _uni_rnd(_rnd_gen, _uni_dist);
77
78 /// Global random number generator with standard normal distribution
79 boost::variate_generator<_rnd_gen_type&, boost::normal_distribution<Real> > _normal_rnd(_rnd_gen, _normal_dist);
80
81
82 void rnd_seed( size_t seed ) {
83 _rnd_gen.seed( static_cast<unsigned int>(seed) );
84 _normal_rnd.distribution().reset(); // needed for clearing the cache used in boost::normal_distribution
85 }
86
87 Real rnd_uniform() {
88 return _uni_rnd();
89 }
90
91 Real rnd_stdnormal() {
92 return _normal_rnd();
93 }
94
95 int rnd_int( int min, int max ) {
96 return (int)floor(_uni_rnd() * (max + 1 - min) + min);
97 }
98
99 std::vector<std::string> tokenizeString( const std::string& s, bool singleDelim, const std::string& delim ) {
100 using namespace std;
101 vector<string> tokens;
102
103 string::size_type start = 0;
104 while( start <= s.size() ) {
105 string::size_type end = s.find_first_of( delim, start );
106 if( end == string::npos )
107 end = s.size();
108
109 if( end == start && !singleDelim ) {
110 // skip to next non-delimiter
111 start = s.find_first_not_of( delim, start );
112 if( start == string::npos )
113 break;
114 } else { // we found a token
115 tokens.push_back( s.substr(start, end - start) );
116 start = end + 1;
117 }
118 }
119
120 return tokens;
121 }
122
123
124 } // end of namespace dai