Fixed tabs and trailing whitespaces
[libdai.git] / include / dai / util.h
index 4c093e0..accc90c 100644 (file)
@@ -1,6 +1,7 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [j dot mooij at science dot ru dot nl]
-    Radboud University Nijmegen, The Netherlands
-    
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
     This file is part of libDAI.
 
     libDAI is free software; you can redistribute it and/or modify
 */
 
 
+/// \file
+/// \brief Defines general utility functions and adds an abstraction layer for platform-dependent functionality
+/// \todo Improve documentation
+
+
 #ifndef __defined_libdai_util_h
 #define __defined_libdai_util_h
 
 
+#include <string>
 #include <vector>
 #include <set>
 #include <map>
 #include <iostream>
-#include <cstdio>
 #include <boost/foreach.hpp>
+#include <boost/functional/hash.hpp>
+#include <algorithm>
 
 
-#ifdef WINDOWS
-    #include <xmath.h> // for NAN
+#if defined(WINDOWS)
     #include <map>
+#elif defined(CYGWIN)
+    #include <boost/tr1/unordered_map.hpp>
 #else
     #include <tr1/unordered_map>
 #endif
 
 
+/// An alias to the BOOST_FOREACH macro from the boost::foreach library
 #define foreach BOOST_FOREACH
 
+#ifdef DAI_DEBUG
+/// \brief "Print variable". Prints the text of an expression, followed by its value (only if DAI_DEBUG is defined)
+/**
+ *  Useful debugging macro to see what your code is doing.
+ *  Example: \code DAI_PV(3+4) \endcode
+ *  Output: \code 3+4= 7 \endcode
+ */
+#define DAI_PV(x) do {std::cerr << #x "= " << (x) << std::endl;} while(0)
+/// "Debugging message": Prints a message (only if DAI_DEBUG is defined)
+#define DAI_DMSG(str) do {std::cerr << str << std::endl;} while(0)
+/// Assertion if DAI_DEBUG is defined
+#define DAI_DEBASSERT(x) do {assert(x);} while(0)
+#else
+#define DAI_PV(x) do {} while(0)
+#define DAI_DMSG(str) do {} while(0)
+#define DAI_DEBASSERT(X) do {} while(0)
+#endif
+
+/// Produces accessor and mutator methods according to the common pattern.
+/** Example:
+ *  \code DAI_ACCMUT(size_t& maxIter(), { return props.maxiter; }); \endcode
+ *  \todo At the moment, only the mutator appears in doxygen documentation.
+ */
+#define DAI_ACCMUT(x,y)                     \
+      x y;                                  \
+      const x const y;
+
+/// Macro to give error message \a stmt if props.verbose>=\a n
+#define DAI_IFVERB(n, stmt) if(props.verbose>=n) { cerr << stmt; }
+
+
+/// Real number (alias for double, which could be changed to long double if necessary)
+typedef double Real;
+
 
 #ifdef WINDOWS
+    /// Returns true if argument is NAN (Not A Number)
     bool isnan( double x );
+
+    /// Returns inverse hyperbolic tangent of argument
     double atanh( double x );
+
+    /// Returns log(1+x)
     double log1p( double x );
+
+    /// Define INFINITY
+    #define INFINITY (std::numeric_limits<double>::infinity())
 #endif
 
 
@@ -53,23 +105,44 @@ namespace dai {
 
 
 #ifdef WINDOWS
-    template <typename T, typename U>
+    /// hash_map is an alias for std::map.
+    /** Since there is no TR1 unordered_map implementation available yet, we fall back on std::map.
+     */
+    template <typename T, typename U, typename H = boost::hash<T> >
         class hash_map : public std::map<T,U> {};
 #else
-    template <typename T, typename U>
-        class hash_map : public std::tr1::unordered_map<T,U> {};
+    /// hash_map is an alias for std::tr1::unordered_map.
+    /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions.
+     */
+    template <typename T, typename U, typename H = boost::hash<T> >
+        class hash_map : public std::tr1::unordered_map<T,U,H> {};
 #endif
 
 
+/// Returns wall clock time in seconds
 double toc();
+
+
+/// Sets the random seed
 void rnd_seed( size_t seed );
+
+/// Returns a real number, distributed uniformly on [0,1)
 double rnd_uniform();
+
+/// Returns a real number from a standard-normal distribution
 double rnd_stdnormal();
+
+/// Returns a random integer in interval [min, max]
 int rnd_int( int min, int max );
 
+/// Returns a random integer in the half-open interval \f$[0,n)\f$
+inline int rnd( int n) {
+    return rnd_int( 0, n-1 );
+}
+
 
-// Output a std::vector
-template<class T> 
+/// Writes a std::vector to a std::ostream
+template<class T>
 std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
     os << "(";
     for( typename std::vector<T>::const_iterator it = x.begin(); it != x.end(); it++ )
@@ -78,9 +151,8 @@ std::ostream& operator << (std::ostream& os, const std::vector<T> & x) {
     return os;
 }
 
-
-// Output a std::set
-template<class T> 
+/// Writes a std::set to a std::ostream
+template<class T>
 std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
     os << "{";
    for( typename std::set<T>::const_iterator it = x.begin(); it != x.end(); it++ )
@@ -89,8 +161,7 @@ std::ostream& operator << (std::ostream& os, const std::set<T> & x) {
     return os;
 }
 
-
-/// Output a std::map
+/// Writes a std::map to a std::ostream
 template<class T1, class T2>
 std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
     os << "{";
@@ -100,14 +171,79 @@ std::ostream& operator << (std::ostream& os, const std::map<T1,T2> & x) {
     return os;
 }
 
-
-/// Output a std::pair
+/// Writes a std::pair to a std::ostream
 template<class T1, class T2>
 std::ostream& operator << (std::ostream& os, const std::pair<T1,T2> & x) {
     os << "(" << x.first << ", " << x.second << ")";
     return os;
 }
 
+/// Concatenate two vectors
+template<class T>
+std::vector<T> concat( const std::vector<T>& u, const std::vector<T>& v ) {
+    std::vector<T> w;
+    w.reserve( u.size() + v.size() );
+    for( size_t i = 0; i < u.size(); i++ )
+        w.push_back( u[i] );
+    for( size_t i = 0; i < v.size(); i++ )
+        w.push_back( v[i] );
+    return w;
+}
+
+/// Split a string into tokens
+void tokenizeString( const std::string& s, std::vector<std::string>& outTokens, const std::string& delim="\t\n" );
+
+/// Used to keep track of the progress made by iterative algorithms
+class Diffs : public std::vector<double> {
+    private:
+        size_t _maxsize;
+        double _def;
+        std::vector<double>::iterator _pos;
+        std::vector<double>::iterator _maxpos;
+    public:
+        /// Constructor
+        Diffs(long maxsize, double def) : std::vector<double>(), _maxsize(maxsize), _def(def) {
+            this->reserve(_maxsize);
+            _pos = begin();
+            _maxpos = begin();
+        }
+        /// Returns maximum difference encountered
+        double maxDiff() {
+            if( size() < _maxsize )
+                return _def;
+            else
+                return( *_maxpos );
+        }
+        /// Register new difference x
+        void push(double x) {
+            if( size() < _maxsize ) {
+                push_back(x);
+                _pos = end();
+                if( size() > 1 ) {
+                    if( *_maxpos < back() ) {
+                        _maxpos = end();
+                        _maxpos--;
+                    }
+                } else {
+                    _maxpos = begin();
+                }
+            } else {
+                if( _pos == end() )
+                    _pos = begin();
+                if( _maxpos == _pos ) {
+                    *_pos++ = x;
+                    _maxpos = max_element(begin(),end());
+                } else {
+                    if( x > *_maxpos )
+                        _maxpos = _pos;
+                    *_pos++ = x;
+                }
+            }
+        }
+        /// Return maximum number of differences stored
+        size_t maxSize() { return _maxsize; }
+};
+
 
 } // end of namespace dai