#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
+#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)
/// Returns log(1+x)
double log1p( double x );
+
+ /// Define INFINITY
+ #define INFINITY (std::numeric_limits<double>::infinity())
#endif
/// 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>
+ template <typename T, typename U, typename H = boost::hash<T> >
class hash_map : public std::map<T,U> {};
#else
/// 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>
- class hash_map : public std::tr1::unordered_map<T,U> {};
+ template <typename T, typename U, typename H = boost::hash<T> >
+ class hash_map : public std::tr1::unordered_map<T,U,H> {};
#endif
-/// Returns the time in seconds
+/// Returns wall clock time in seconds
double toc();
/// 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 );
+}
+
/// Writes a std::vector to a std::ostream
-template<class T>
+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++ )
}
/// Writes a std::set to a std::ostream
-template<class T>
+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++ )
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> {
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();
+ 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() {
+ double maxDiff() {
if( size() < _maxsize )
return _def;
else
- return( *_maxpos );
+ return( *_maxpos );
}
/// Register new difference x
void push(double x) {
} else {
_maxpos = begin();
}
- }
- else {
+ } else {
if( _pos == end() )
_pos = begin();
if( _maxpos == _pos ) {
- *_pos++ = x;
+ *_pos++ = x;
_maxpos = max_element(begin(),end());
} else {
if( x > *_maxpos )