Improved util.h/cpp and added unit tests
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 24 Mar 2010 17:12:50 +0000 (18:12 +0100)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Wed, 24 Mar 2010 17:12:50 +0000 (18:12 +0100)
  - Fixed a bug in rnd_seed()
  - Removed Real max( const std::vector<Real> &v )

ChangeLog
Makefile
include/dai/util.h
src/util.cpp
tests/unit/util.cpp [new file with mode: 0644]

index 9de45c2..100f69f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,13 +1,16 @@
 git HEAD
 --------
 
-* Improved WeightedGraph code:
+* Improved util.h/cpp:
+  - Fixed a bug in rnd_seed()
+  - Removed Real max( const std::vector<Real> &v )
+* Improved weightedgraph.h/cpp:
   - Renamed MaxSpanningTreePrims into MaxSpanningTree
   - Renamed MinSpanningTreePrims into MinSpanningTree
   - Added option to MaxSpanningTree and MinSpanningTree for
     choosing between Prim's algorithm and Kruskal's algorithm
   - More error checking in RootedTree constructor
-* Improved BipartiteGraph code:
+* Improved bipgraph.h/cpp:
   - Fixed bug in BipartiteGraph::eraseNode1()
   - Fixed bug in BipartiteGraph::eraseNode2()
   - Fixed bug in BipartiteGraph::isTree()
@@ -16,7 +19,7 @@ git HEAD
   - Added BipartiteGraph::findNb2()
   - BipartiteGraph::delta1() and BipartiteGraph::delta2() now 
     return a SmallSet<size_t> instead of a vector<size_t>
-* Improved GraphAL code:
+* Improved graph.h/cpp:
   - Fixed bug in GraphAL::nrEdges()
   - Fixed bug in GraphAL::addEdge()
   - Fixed bug in GraphAL::isTree()
@@ -25,7 +28,7 @@ git HEAD
   - Fixed bug in createGraphGrid3D()
   - Fixed bug in createGraphRegular()
   - Added GraphAL::hasEdge(size_t,size_t)
-* Improved SmallSet code:
+* Improved smallset.h/cpp:
   - The sizeHint argument of the iterator constructor
      SmallSet::SmallSet( TIterator begin, TIterator end, size_t sizeHint=0 )
     no longer has a default value in order to avoid confusion with the
@@ -33,8 +36,8 @@ git HEAD
     constructor.
 * Removed RandomDRegularGraph()
 * Compressed Makefile
-* Added unit tests for Var, SmallSet, VarSet, Graph, BipartiteGraph,
-  WeightedGraph, Enum
+* Added unit tests for var, smallset, varset, graph, bipgraph,
+  weightedgraph, enum, util
 * Added unit testing framework
 * Added initialization of TRWBP weights by sampling spanning trees
 * Cleaned up MR code:
index baf6247..840956b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -122,7 +122,7 @@ examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example
 
 matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
 
-unittests : tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE)
+unittests : tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/enum$(EE) tests/unit/util$(EE)
        echo Running unit tests...
        tests/unit/var
        tests/unit/smallset
@@ -131,6 +131,7 @@ unittests : tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE)
        tests/unit/bipgraph
        tests/unit/weightedgraph
        tests/unit/enum
+       tests/unit/util
 
 tests : tests/testdai$(EE) tests/testem/testem$(EE) tests/testbbp$(EE) $(unittests)
 
@@ -206,6 +207,8 @@ tests/unit/weightedgraph$(EE) : tests/unit/weightedgraph.cpp $(HEADERS) $(LIB)/l
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
 tests/unit/enum$(EE) : tests/unit/enum.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
+tests/unit/util$(EE) : tests/unit/util.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
 
 
 # TESTS
@@ -312,7 +315,7 @@ clean :
        -rm matlab/*$(ME)
        -rm examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE) examples/example_permute$(EE) examples/example_sprinkler$(EE) examples/example_sprinkler_gibbs$(EE) examples/example_sprinkler_em$(EE)
        -rm tests/testdai$(EE) tests/testem/testem$(EE) tests/testbbp$(EE)
-       -rm tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE)
+       -rm tests/unit/var$(EE) tests/unit/smallset$(EE) tests/unit/varset$(EE) tests/unit/graph$(EE) tests/unit/bipgraph$(EE) tests/unit/weightedgraph$(EE) tests/unit/enum$(EE) tests/unit/util$(EE)
        -rm utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE)
        -rm -R doc
        -rm -R lib
@@ -346,6 +349,7 @@ clean :
        -del tests\unit\bipgraph$(EE)
        -del tests\unit\weightedgraph$(EE)
        -del tests\unit\enum$(EE)
+       -del tests\unit\util$(EE)
        -del $(LIB)\libdai$(LE)
        -rmdir lib
 endif
index 7ce3362..8fe4f07 100644 (file)
@@ -96,9 +96,6 @@ inline Real exp( Real x ) {
     return std::exp(x);
 }
 
-/// Returns maximum value of a std::vector<Real>
-Real max( const std::vector<Real> &v );
-
 
 /// hash_map is an alias for \c std::tr1::unordered_map.
 /** We use the (experimental) TR1 unordered_map implementation included in modern GCC distributions or in boost versions 1.37 and higher.
index 54eae31..5b94118 100644 (file)
@@ -48,13 +48,6 @@ double log1p( double x ) {
 namespace dai {
 
 
-Real max( const std::vector<Real> &v ) {
-    if( v.size() == 0 )
-        return INFINITY;
-    else
-        return *std::max_element( v.begin(), v.end() );
-}
-
 // Returns user+system time in seconds
 double toc() {
 #ifdef WINDOWS
@@ -78,18 +71,19 @@ _rnd_gen_type _rnd_gen(42U);
 /// Uniform distribution with values between 0 and 1 (0 inclusive, 1 exclusive).
 boost::uniform_real<Real> _uni_dist(0,1);
 
-/// Global uniform random random number
-boost::variate_generator<_rnd_gen_type&, boost::uniform_real<Real> > _uni_rnd(_rnd_gen, _uni_dist);
-
 /// Normal distribution with mean 0 and standard deviation 1.
 boost::normal_distribution<Real> _normal_dist;
 
+/// Global uniform random random number
+boost::variate_generator<_rnd_gen_type&, boost::uniform_real<Real> > _uni_rnd(_rnd_gen, _uni_dist);
+
 /// Global random number generator with standard normal distribution
 boost::variate_generator<_rnd_gen_type&, boost::normal_distribution<Real> > _normal_rnd(_rnd_gen, _normal_dist);
 
 
 void rnd_seed( size_t seed ) {
     _rnd_gen.seed(seed);
+    _normal_rnd.distribution().reset(); // needed for clearing the cache used in boost::normal_distribution
 }
 
 Real rnd_uniform() {
diff --git a/tests/unit/util.cpp b/tests/unit/util.cpp
new file mode 100644 (file)
index 0000000..12c9c0b
--- /dev/null
@@ -0,0 +1,150 @@
+/*  This file is part of libDAI - http://www.libdai.org/
+ *
+ *  libDAI is licensed under the terms of the GNU General Public License version
+ *  2, or (at your option) any later version. libDAI is distributed without any
+ *  warranty. See the file COPYING for more details.
+ *
+ *  Copyright (C) 2010  Joris Mooij      [joris dot mooij at libdai dot org]
+ */
+
+
+#define BOOST_TEST_DYN_LINK
+
+
+#include <dai/util.h>
+#include <strstream>
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+
+using namespace dai;
+
+
+#define BOOST_TEST_MODULE UtilTest
+
+
+#include <boost/test/unit_test.hpp>
+
+
+BOOST_AUTO_TEST_CASE( IsNanTest ) {
+    double x = 0.0, y = 0.0;
+    BOOST_CHECK( isnan( x / y ) );
+    BOOST_CHECK( !isnan( x ) );
+}
+
+
+BOOST_AUTO_TEST_CASE( RndTest ) {
+    rnd_seed( 123 );
+    Real a1 = rnd_uniform();
+    Real b1 = rnd_stdnormal();
+    int c1 = rnd_int(0,1);
+    int d1 = rnd(2);
+
+    rnd_seed( 123 );
+    Real a2 = rnd_uniform();
+    Real b2 = rnd_stdnormal();
+    int c2 = rnd_int(0,1);
+    int d2 = rnd(2);
+
+    BOOST_CHECK_EQUAL( a1, a2 );
+    BOOST_CHECK_EQUAL( b1, b2 );
+    BOOST_CHECK_EQUAL( c1, c2 );
+    BOOST_CHECK_EQUAL( d1, d2 );
+
+    for( size_t i = 0; i < 10000; i++ ) {
+        Real x = rnd_uniform();
+        BOOST_CHECK( x >= 0.0 );
+        BOOST_CHECK( x < 1 );
+    }
+
+    for( int min = -5; min <= 5; min++ )
+        for( int max = min; max <= min + 10; max++ )
+            for( size_t i = 0; i < 1000; i++ ) {
+                int j = rnd_int( min, max );
+                BOOST_CHECK( j >= min );
+                BOOST_CHECK( j <= max );
+            }
+
+    for( int max = 1; max <= 100; max++ )
+        for( size_t i = 0; i < 100; i++ ) {
+            int j = rnd( max );
+            BOOST_CHECK( j >= 0 );
+            BOOST_CHECK( j < max );
+        }
+}
+
+
+BOOST_AUTO_TEST_CASE( StreamTest ) {
+    std::vector<int> v;
+    v.push_back( 1 );
+    v.push_back( 3 );
+    v.push_back( 2 );
+    std::stringstream ss;
+    ss << v;
+    std::string s;
+    std::getline( ss, s );
+    BOOST_CHECK_EQUAL( s, "(1, 3, 2)" );
+
+    std::set<int> x;
+    x.insert( 6 );
+    x.insert( 5 );
+    x.insert( 4 );
+    std::stringstream ss2;
+    ss2 << x;
+    std::getline( ss2, s );
+    BOOST_CHECK_EQUAL( s, "{4, 5, 6}" );
+
+    std::map<int,int> y;
+    y[1] = 6;
+    y[3] = 5;
+    y[2] = 4;
+    std::stringstream ss3;
+    ss3 << y;
+    std::getline( ss3, s );
+    BOOST_CHECK_EQUAL( s, "{1->6, 2->4, 3->5}" );
+
+    std::pair<int,double> z;
+    z.first = 5;
+    z.second = 1.2345;
+    std::stringstream ss4;
+    ss4 << z;
+    std::getline( ss4, s );
+    BOOST_CHECK_EQUAL( s, "(5, 1.2345)" );
+}
+
+
+BOOST_AUTO_TEST_CASE( concatTest ) {
+    std::vector<int> a;
+    a.push_back( 0 );
+    a.push_back( 1 );
+    std::vector<int> b;
+    b.push_back( 2 );
+    b.push_back( 3 );
+    b.push_back( 4 );
+    std::vector<int> c;
+    c.push_back( 0 );
+    c.push_back( 1 );
+    c.push_back( 2 );
+    c.push_back( 3 );
+    c.push_back( 4 );
+    BOOST_CHECK( concat( a, b ) == c );
+}
+
+
+BOOST_AUTO_TEST_CASE( tokenizeStringTest ) {
+    std::string s("Hello\tworld.\nThis is it.");
+    std::vector<std::string> words;
+    tokenizeString( s, words );
+    BOOST_CHECK_EQUAL( words.size(), 3 );
+    BOOST_CHECK_EQUAL( words[0], "Hello" );
+    BOOST_CHECK_EQUAL( words[1], "world." );
+    BOOST_CHECK_EQUAL( words[2], "This is it." );
+    words.clear();
+    tokenizeString( s, words, " " );
+    BOOST_CHECK_EQUAL( words.size(), 3 );
+    BOOST_CHECK_EQUAL( words[0], "Hello\tworld.\nThis" );
+    BOOST_CHECK_EQUAL( words[1], "is" );
+    BOOST_CHECK_EQUAL( words[2], "it." );
+}