Significant improvement of documentation
[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
26
27 #ifndef __defined_libdai_util_h
28 #define __defined_libdai_util_h
29
30
31 #include <vector>
32 #include <set>
33 #include <map>
34 #include <iostream>
35 #include <cstdio>
36 #include <boost/foreach.hpp>
37 #include <algorithm>
38
39
40 #ifdef WINDOWS
41 #include <map>
42 #else
43 #include <tr1/unordered_map>
44 #endif
45
46
47 /// An alias to the BOOST_FOREACH macro from the boost::foreach library
48 #define foreach BOOST_FOREACH
49
50
51 #ifdef WINDOWS
52 /// Returns true if argument is NAN (Not A Number)
53 bool isnan( double x );
54
55 /// Returns inverse hyperbolic tangent of argument
56 double atanh( double x );
57
58 /// Returns log(1+x)
59 double log1p( double x );
60 #endif
61
62
63 namespace dai {
64
65
66 #ifdef WINDOWS
67 /// hash_map is an alias for std::map.
68 /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
69 */
70 template <typename T, typename U>
71 class hash_map : public std::map<T,U> {};
72 #else
73 /// hash_map is an alias for std::tr1::unordered_map.
74 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
75 */
76 template <typename T, typename U>
77 class hash_map : public std::tr1::unordered_map<T,U> {};
78 #endif
79
80
81 /// Returns the time in seconds
82 double toc();
83
84
85 /// Sets the random seed
86 void rnd_seed( size_t seed );
87
88 /// Returns a real number, distributed uniformly on [0,1)
89 double rnd_uniform();
90
91 /// Returns a real number from a standard-normal distribution
92 double rnd_stdnormal();
93
94 /// Returns a random integer in interval [min, max]
95 int rnd_int( int min, int max );
96
97
98 /// Writes a std::vector to a std::ostream
99 template<class T>
100 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
101 os << "(";
102 for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
103 os << (it != x.begin() ? ", " : "") << *it;
104 os << ")";
105 return os;
106 }
107
108 /// Writes a std::set to a std::ostream
109 template<class T>
110 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
111 os << "{";
112 for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
113 os << (it != x.begin() ? ", " : "") << *it;
114 os << "}";
115 return os;
116 }
117
118 /// Writes a std::map to a std::ostream
119 template<class T1, class T2>
120 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
121 os << "{";
122 for( typename std::map<T1,T2>::const_iterator it = x.begin(); it != x.end(); it++ )
123 os << (it != x.begin() ? ", " : "") << it->first << "->" << it->second;
124 os << "}";
125 return os;
126 }
127
128 /// Writes a std::pair to a std::ostream
129 template<class T1, class T2>
130 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
131 os << "(" << x.first << ", " << x.second << ")";
132 return os;
133 }
134
135
136 /// Used to keep track of the progress made by iterative algorithms
137 class Diffs : public std::vector<double> {
138 private:
139 size_t _maxsize;
140 double _def;
141 std::vector<double>::iterator _pos;
142 std::vector<double>::iterator _maxpos;
143 public:
144 /// Constructor
145 Diffs(long maxsize, double def) : std::vector<double>(), _maxsize(maxsize), _def(def) {
146 this->reserve(_maxsize);
147 _pos = begin();
148 _maxpos = begin();
149 }
150 /// Returns maximum difference encountered
151 double maxDiff() {
152 if( size() < _maxsize )
153 return _def;
154 else
155 return( *_maxpos );
156 }
157 /// Register new difference x
158 void push(double x) {
159 if( size() < _maxsize ) {
160 push_back(x);
161 _pos = end();
162 if( size() > 1 ) {
163 if( *_maxpos < back() ) {
164 _maxpos = end();
165 _maxpos--;
166 }
167 } else {
168 _maxpos = begin();
169 }
170 }
171 else {
172 if( _pos == end() )
173 _pos = begin();
174 if( _maxpos == _pos ) {
175 *_pos++ = x;
176 _maxpos = max_element(begin(),end());
177 } else {
178 if( x > *_maxpos )
179 _maxpos = _pos;
180 *_pos++ = x;
181 }
182 }
183 }
184 /// Return maximum number of differences stored
185 size_t maxSize() { return _maxsize; }
186 };
187
188
189 } // end of namespace dai
190
191
192 #endif