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