Improved tokenizeString
[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 WINDOWS
30 double atanh( double x ) {
31 return boost::math::atanh( x );
32 }
33 double log1p( double x ) {
34 return boost::math::log1p( x );
35 }
36 #endif
37
38
39 namespace dai {
40
41 #if defined CYGWIN
42 bool isnan( Real x ) {
43 return __isnand( x ); // isnan() is a macro in Cygwin (as required by C99)
44 }
45 #elif defined WINDOWS
46 bool isnan( Real x ) {
47 return _isnan( x );
48 }
49 #else
50 bool isnan( Real x ) {
51 return std::isnan( x );
52 }
53 #endif
54
55 // Returns user+system time in seconds
56 double toc() {
57 #ifdef WINDOWS
58 SYSTEMTIME tbuf;
59 GetSystemTime(&tbuf);
60 return( (double)(tbuf.wSecond + (double)tbuf.wMilliseconds / 1000.0) );
61 #else
62 struct timeval tv;
63 struct timezone tz;
64 gettimeofday( &tv, &tz );
65 return( (double)(tv.tv_sec + (double)tv.tv_usec / 1000000.0) );
66 #endif
67 }
68
69 /// Type of global random number generator
70 typedef boost::minstd_rand _rnd_gen_type; // Try boost::mt19937 or boost::ecuyer1988 instead of boost::minstd_rand
71
72 /// Global random number generator
73 _rnd_gen_type _rnd_gen(42U);
74
75 /// Uniform distribution with values between 0 and 1 (0 inclusive, 1 exclusive).
76 boost::uniform_real<Real> _uni_dist(0,1);
77
78 /// Normal distribution with mean 0 and standard deviation 1.
79 boost::normal_distribution<Real> _normal_dist;
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 /// Global random number generator with standard normal distribution
85 boost::variate_generator<_rnd_gen_type&, boost::normal_distribution<Real> > _normal_rnd(_rnd_gen, _normal_dist);
86
87
88 void rnd_seed( size_t seed ) {
89 _rnd_gen.seed(seed);
90 _normal_rnd.distribution().reset(); // needed for clearing the cache used in boost::normal_distribution
91 }
92
93 Real rnd_uniform() {
94 return _uni_rnd();
95 }
96
97 Real rnd_stdnormal() {
98 return _normal_rnd();
99 }
100
101 int rnd_int( int min, int max ) {
102 return (int)floor(_uni_rnd() * (max + 1 - min) + min);
103 }
104
105 std::vector<std::string> tokenizeString( const std::string& s, bool singleDelim, const std::string& delim ) {
106 using namespace std;
107 vector<string> tokens;
108
109 string::size_type start = 0;
110 while( start < s.size() ) {
111 string::size_type end = s.find_first_of( delim, start );
112 if( end == string::npos )
113 end = s.size();
114
115 if( end == start && !singleDelim ) {
116 // skip to next non-delimiter
117 start = s.find_first_not_of( delim, start );
118 if( start == string::npos )
119 start = s.size();
120 } else { // we found a token
121 tokens.push_back( s.substr(start, end - start) );
122 start = end + 1;
123 }
124 }
125
126 return tokens;
127 }
128
129
130 void tokenizeString(const std::string& s, std::vector<std::string>& outTokens, const std::string& delim) {
131 size_t start = 0;
132 while (start < s.size()) {
133 size_t end = s.find_first_of(delim, start);
134 if (end > s.size())
135 end = s.size();
136 outTokens.push_back(s.substr(start, end - start));
137 start = end + 1;
138 }
139 }
140
141
142 } // end of namespace dai