Improved documentation of include/dai/enum.h and include/dai/factor.h
[libdai.git] / include / dai / util.h
1 /* Copyright (C) 2006-2008 Joris Mooij [joris dot mooij at tuebingen dot mpg dot de]
2 Radboud University Nijmegen, The Netherlands /
3 Max Planck Institute for Biological Cybernetics, Germany
4
5 This file is part of libDAI.
6
7 libDAI is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 libDAI is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with libDAI; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22
23 /// \file
24 /// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality
25 /// \todo Improve documentation
26
27
28 #ifndef __defined_libdai_util_h
29 #define __defined_libdai_util_h
30
31
32 #include <vector>
33 #include <set>
34 #include <map>
35 #include <iostream>
36 #include <cstdio>
37 #include <boost/foreach.hpp>
38 #include <algorithm>
39
40
41 #ifdef WINDOWS
42 #include <map>
43 #else
44 #include <tr1/unordered_map>
45 #endif
46
47
48 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
49 #define foreach BOOST_FOREACH
50
51
52 /// Real number (alias for double, which could be changed to long double if necessary)
53 typedef double Real;
54
55
56 #ifdef WINDOWS
57 /// Returns true if argument is NAN (Not A Number)
58 bool isnan( double x );
59
60 /// Returns inverse hyperbolic tangent of argument
61 double atanh( double x );
62
63 /// Returns log(1+x)
64 double log1p( double x );
65 #endif
66
67
68 namespace dai {
69
70
71 #ifdef WINDOWS
72 /// hash_map is an alias for std::map.
73 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
74 */
75 template <typename T, typename U>
76 class hash_map : public std::map<T,U> {};
77 #else
78 /// hash_map is an alias for std::tr1::unordered_map.
79 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
80 */
81 template <typename T, typename U>
82 class hash_map : public std::tr1::unordered_map<T,U> {};
83 #endif
84
85
86 /// Returns the time in seconds
87 double toc();
88
89
90 /// Sets the random seed
91 void rnd_seed( size_t seed );
92
93 /// Returns a real number, distributed uniformly on [0,1)
94 double rnd_uniform();
95
96 /// Returns a real number from a standard-normal distribution
97 double rnd_stdnormal();
98
99 /// Returns a random integer in interval [min, max]
100 int rnd_int( int min, int max );
101
102
103 /// Writes a std::vector to a std::ostream
104 template<class T>
105 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
106 os << "(";
107 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
108 os << (it != x.begin() ? ", " : "") << *it;
109 os << ")";
110 return os;
111 }
112
113 /// Writes a std::set to a std::ostream
114 template<class T>
115 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
116 os << "{";
117 for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
118 os << (it != x.begin() ? ", " : "") << *it;
119 os << "}";
120 return os;
121 }
122
123 /// Writes a std::map to a std::ostream
124 template<class T1, class T2>
125 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
126 os << "{";
127 for( typename std::map<T1,T2>::const_iterator it = x.begin(); it != x.end(); it++ )
128 os << (it != x.begin() ? ", " : "") << it->first << "->" << it->second;
129 os << "}";
130 return os;
131 }
132
133 /// Writes a std::pair to a std::ostream
134 template<class T1, class T2>
135 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
136 os << "(" << x.first << ", " << x.second << ")";
137 return os;
138 }
139
140
141 /// Used to keep track of the progress made by iterative algorithms
142 class Diffs : public std::vector<double> {
143 private:
144 size_t _maxsize;
145 double _def;
146 std::vector<double>::iterator _pos;
147 std::vector<double>::iterator _maxpos;
148 public:
149 /// Constructor
150 Diffs(long maxsize, double def) : std::vector<double>(), _maxsize(maxsize), _def(def) {
151 this->reserve(_maxsize);
152 _pos = begin();
153 _maxpos = begin();
154 }
155 /// Returns maximum difference encountered
156 double maxDiff() {
157 if( size() < _maxsize )
158 return _def;
159 else
160 return( *_maxpos );
161 }
162 /// Register new difference x
163 void push(double x) {
164 if( size() < _maxsize ) {
165 push_back(x);
166 _pos = end();
167 if( size() > 1 ) {
168 if( *_maxpos < back() ) {
169 _maxpos = end();
170 _maxpos--;
171 }
172 } else {
173 _maxpos = begin();
174 }
175 }
176 else {
177 if( _pos == end() )
178 _pos = begin();
179 if( _maxpos == _pos ) {
180 *_pos++ = x;
181 _maxpos = max_element(begin(),end());
182 } else {
183 if( x > *_maxpos )
184 _maxpos = _pos;
185 *_pos++ = x;
186 }
187 }
188 }
189 /// Return maximum number of differences stored
190 size_t maxSize() { return _maxsize; }
191 };
192
193
194 } // end of namespace dai
195
196
197 #endif