Improved MatLab build process and some smaller misc changes
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Thu, 1 Apr 2010 17:16:02 +0000 (19:16 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Thu, 1 Apr 2010 17:16:02 +0000 (19:16 +0200)
- Added TFactor<T>::sumAbs() const
- Added TFactor<T>::operator=( const TFactor<T> &y )
- Added TProb<T>::resize(size_t, T)
- Improved Makefile (MatLab interface builds more reliably now)

ChangeLog
Makefile
Makefile.CYGWIN
Makefile.LINUX
Makefile.MACOSX
Makefile.WINDOWS
include/dai/factor.h
include/dai/prob.h
src/alldai.cpp
src/matlab/matlab.cpp
tests/unit/factor.cpp

index 06ff5d4..5d35e84 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,14 @@
 git HEAD
 --------
 
+TODO:
+* Write unit tests for newly added functions
+
 * Fixed some bugs in the MatLab interface build system
 * Fixed a bug in utils/fginfo.cpp
 * Improved factor.h/cpp:
+  - Added TFactor<T>::sumAbs() const
+  - Added TFactor<T>::operator=( const TFactor<T> &y )
   - Added get(size_t) and set(size_t,T) operators; get() is 
     equivalent to "operator[](size_t) const" and set() should
     be used instead of the non-const operator[], which has been deprecated
@@ -16,6 +21,7 @@ git HEAD
   - Added get(size_t) and set(size_t,T) operators; get() is 
     equivalent to "operator[](size_t) const" and set() should
     be used instead of the non-const operator[], which has been deprecated
+  - Added TProb<T>::resize(size_t, T)
 * Improved index.h/cpp:
   - Added multifor::reset()
 * Improved properties.h/cpp:
index 40e1c9b..6e8ad5b 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ include Makefile.conf
 
 # Set version and date
 DAI_VERSION="git HEAD"
-DAI_DATE="February 11, 2010 - or later"
+DAI_DATE="April 1, 2010 - or later"
 
 # Directories of libDAI sources
 # Location libDAI headers
@@ -34,78 +34,85 @@ else
 endif
 
 # Define build targets
-TARGETS=tests utils lib examples unittests testregression testem
+TARGETS:=tests utils lib examples
+ifneq ($(OS),WINDOWS)
+  TARGETS:=$(TARGETS) unittests
+endif
+TARGETS:=$(TARGETS) testregression testem
 ifdef WITH_DOC
   TARGETS:=$(TARGETS) doc
 endif
 ifdef WITH_MATLAB
   TARGETS:=$(TARGETS) matlabs
-  # Specify the same C++ compiler and flags to mex
-  ifdef NEW_MATLAB
-    MEXFLAGS:=$(MEXFLAGS) -largeArrayDims
-  else
-    MEXFLAGS:=$(MEXFLAGS) -DSMALLMEM
-  endif
 endif
 
 # Define conditional build targets
-OBJECTS:=exactinf$(OE) evidence$(OE) emalg$(OE)
+NAMES:=bipgraph graph varset daialg alldai clustergraph factor factorgraph properties regiongraph util weightedgraph exceptions exactinf evidence emalg
 ifdef WITH_BP
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_BP
-  OBJECTS:=$(OBJECTS) bp$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_BP
+  NAMES:=$(NAMES) bp
 endif
 ifdef WITH_FBP
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_FBP
-  OBJECTS:=$(OBJECTS) fbp$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_FBP
+  NAMES:=$(NAMES) fbp
 endif
 ifdef WITH_TRWBP
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_TRWBP
-  OBJECTS:=$(OBJECTS) trwbp$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_TRWBP
+  NAMES:=$(NAMES) trwbp
 endif
 ifdef WITH_MF
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MF
-  OBJECTS:=$(OBJECTS) mf$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_MF
+  NAMES:=$(NAMES) mf
 endif
 ifdef WITH_HAK
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_HAK
-  OBJECTS:=$(OBJECTS) hak$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_HAK
+  NAMES:=$(NAMES) hak
 endif
 ifdef WITH_LC
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_LC
-  OBJECTS:=$(OBJECTS) lc$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_LC
+  NAMES:=$(NAMES) lc
 endif
 ifdef WITH_TREEEP
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_TREEEP
-  OBJECTS:=$(OBJECTS) treeep$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_TREEEP
+  NAMES:=$(NAMES) treeep
 endif
 ifdef WITH_JTREE
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_JTREE
-  OBJECTS:=$(OBJECTS) jtree$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_JTREE
+  NAMES:=$(NAMES) jtree
 endif
 ifdef WITH_MR
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MR
-  OBJECTS:=$(OBJECTS) mr$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_MR
+  NAMES:=$(NAMES) mr
 endif
 ifdef WITH_GIBBS
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_GIBBS
-  OBJECTS:=$(OBJECTS) gibbs$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_GIBBS
+  NAMES:=$(NAMES) gibbs
 endif
 ifdef WITH_CBP
-  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_CBP
-  OBJECTS:=$(OBJECTS) bbp$(OE) cbp$(OE) bp_dual$(OE)
+  WITHFLAGS:=$(WITHFLAGS) -DDAI_WITH_CBP
+  NAMES:=$(NAMES) bbp cbp bp_dual
 endif
 
-# Define standard libDAI header dependencies
-HEADERS=$(INC)/bipgraph.h $(INC)/graph.h $(INC)/index.h $(INC)/var.h $(INC)/factor.h $(INC)/varset.h $(INC)/smallset.h $(INC)/prob.h $(INC)/daialg.h $(INC)/properties.h $(INC)/alldai.h $(INC)/enum.h $(INC)/exceptions.h $(INC)/util.h
+# Define standard libDAI header dependencies, source file names and object file names
+HEADERS=$(foreach name,bipgraph graph index var factor varset smallset prob daialg properties alldai enum exceptions util,$(INC)/$(name).h)
+SOURCES:=$(foreach name,$(NAMES),$(SRC)/$(name).cpp)
+OBJECTS:=$(foreach name,$(NAMES),$(name)$(OE))
 
-# Setup final command for C++ compiler and MEX
+# Setup final command for C++ compiler
 ifneq ($(OS),WINDOWS)
-  CC:=$(CC) $(CCINC) $(CCFLAGS) $(CCLIB)
+  CC:=$(CC) $(CCINC) $(CCFLAGS) $(WITHFLAGS) $(CCLIB)
 else
-  CC:=$(CC) $(CCINC) $(CCFLAGS)
+  CC:=$(CC) $(CCINC) $(CCFLAGS) $(WITHFLAGS)
   LIBS:=$(LIBS) $(CCLIB)
 endif
-MEX:=$(MEX) $(CCLIB) $(CCINC) $(MEXFLAGS)
+
+# Setup final command for MEX
+ifdef NEW_MATLAB
+  MEXFLAGS:=$(MEXFLAGS) -largeArrayDims
+else
+  MEXFLAGS:=$(MEXFLAGS) -DSMALLMEM
+endif
+MEX:=$(MEX) $(MEXINC) $(MEXFLAGS) $(WITHFLAGS) $(MEXLIB)
 
 
 # META TARGETS
@@ -143,7 +150,7 @@ lib: $(LIB)/libdai$(LE)
 ##########
 
 %$(OE) : $(SRC)/%.cpp $(INC)/%.h $(HEADERS)
-       $(CC) -c $< -o $@
+       $(CC) -c $<
 
 bbp$(OE) : $(SRC)/bbp.cpp $(INC)/bbp.h $(INC)/bp_dual.h $(HEADERS)
        $(CC) -c $<
@@ -167,54 +174,14 @@ emalg$(OE) : $(SRC)/emalg.cpp $(INC)/emalg.h $(INC)/evidence.h $(HEADERS)
 # EXAMPLES
 ###########
 
-examples/example$(EE) : examples/example.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_bipgraph$(EE) : examples/example_bipgraph.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_varset$(EE) : examples/example_varset.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_permute$(EE) : examples/example_permute.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_sprinkler$(EE) : examples/example_sprinkler.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_sprinkler_gibbs$(EE) : examples/example_sprinkler_gibbs.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS)
-
-examples/example_sprinkler_em$(EE) : examples/example_sprinkler_em.cpp $(HEADERS) $(LIB)/libdai$(LE)
+examples/%$(EE) : examples/%.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS)
 
 
 # UNIT TESTS
 #############
 
-tests/unit/var$(EE) : tests/unit/var.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/smallset$(EE) : tests/unit/smallset.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/varset$(EE) : tests/unit/varset.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/graph$(EE) : tests/unit/graph.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/bipgraph$(EE) : tests/unit/bipgraph.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/weightedgraph$(EE) : tests/unit/weightedgraph.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(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/unit/properties$(EE) : tests/unit/properties.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/index$(EE) : tests/unit/index.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/prob$(EE) : tests/unit/prob.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
-tests/unit/factor$(EE) : tests/unit/factor.cpp $(HEADERS) $(LIB)/libdai$(LE)
+tests/unit/%$(EE) : tests/unit/%.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_UTF)
 
 
@@ -225,28 +192,26 @@ tests/testdai$(EE) : tests/testdai.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_PO)
 tests/testem/testem$(EE) : tests/testem/testem.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS) $(BOOSTLIBS_PO)
-
+ifdef WITH_CBP
 tests/testbbp$(EE) : tests/testbbp.cpp $(HEADERS) $(LIB)/libdai$(LE)
        $(CC) $(CCO)$@ $< $(LIBS)
+endif
 
 
 # MATLAB INTERFACE
 ###################
 
-matlab/dai$(ME) : $(SRC)/matlab/dai.cpp $(HEADERS) matlab$(OE) $(LIB)/libdai$(LE)
-       $(MEX) -output $@ $< matlab$(OE) $(LIB)/libdai$(LE)
+matlab/dai$(ME) : $(SRC)/matlab/dai.cpp $(HEADERS) $(SOURCES) $(SRC)/matlab/matlab.cpp
+       $(MEX) -output $@ $< $(SRC)/matlab/matlab.cpp $(SOURCES)
 
-matlab/dai_readfg$(ME) : $(SRC)/matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE) bipgraph$(OE)
-       $(MEX) -output $@ $< factorgraph$(OE) matlab$(OE) exceptions$(OE) bipgraph$(OE)
+matlab/dai_readfg$(ME) : $(SRC)/matlab/dai_readfg.cpp $(HEADERS) $(SRC)/matlab/matlab.cpp $(SRC)/factorgraph.cpp $(SRC)/exceptions.cpp $(SRC)/bipgraph.cpp
+       $(MEX) -output $@ $< $(SRC)/matlab/matlab.cpp $(SRC)/factorgraph.cpp $(SRC)/exceptions.cpp $(SRC)/bipgraph.cpp
 
-matlab/dai_writefg$(ME) : $(SRC)/matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE) bipgraph$(OE)
-       $(MEX) -output $@ $< factorgraph$(OE) matlab$(OE) exceptions$(OE) bipgraph$(OE)
+matlab/dai_writefg$(ME) : $(SRC)/matlab/dai_writefg.cpp $(HEADERS) $(SRC)/matlab/matlab.cpp $(SRC)/factorgraph.cpp $(SRC)/exceptions.cpp $(SRC)/bipgraph.cpp
+       $(MEX) -output $@ $< $(SRC)/matlab/matlab.cpp $(SRC)/factorgraph.cpp $(SRC)/exceptions.cpp $(SRC)/bipgraph.cpp
 
-matlab/dai_potstrength$(ME) : $(SRC)/matlab/dai_potstrength.cpp $(HEADERS) matlab$(OE) exceptions$(OE)
-       $(MEX) -output $@ $< matlab$(OE) exceptions$(OE)
-
-matlab$(OE) : $(SRC)/matlab/matlab.cpp $(INC)/matlab/matlab.h $(HEADERS)
-       $(MEX) -c $<
+matlab/dai_potstrength$(ME) : $(SRC)/matlab/dai_potstrength.cpp $(HEADERS) $(SRC)/matlab/matlab.cpp $(SRC)/exceptions.cpp
+       $(MEX) -output $@ $< $(SRC)/matlab/matlab.cpp $(SRC)/exceptions.cpp
 
 
 # UTILS
@@ -265,8 +230,6 @@ utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
 # LIBRARY
 ##########
 
-OBJECTS:=bipgraph$(OE) graph$(OE) varset$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factor$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS) 
-
 ifneq ($(OS),WINDOWS)
 $(LIB)/libdai$(LE) : $(OBJECTS)
        -mkdir -p lib
@@ -318,7 +281,7 @@ TAGS :
 ifneq ($(OS),WINDOWS)
 .PHONY : clean
 clean :
-       -rm *$(OE)
+       -rm $(OBJECTS)
        -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)
@@ -329,26 +292,30 @@ clean :
 else
 .PHONY : clean
 clean :
-       -del *$(OE)
+       -del *.obj
        -del *.ilk
        -del *.pdb
-       -del *$(EE)
        -del matlab\*$(ME)
        -del examples\*$(EE)
+       -del examples\*$(EE).manifest
        -del examples\*.ilk
        -del examples\*.pdb
        -del tests\testdai$(EE)
        -del tests\testbbp$(EE)
+       -del tests\testdai$(EE).manifest
+       -del tests\testbbp$(EE).manifest
        -del tests\testem\testem$(EE)
+       -del tests\testem\testem$(EE).manifest
        -del tests\*.pdb
        -del tests\*.ilk
        -del tests\testem\*.pdb
        -del tests\testem\*.ilk
        -del utils\*$(EE)
+       -del utils\*$(EE).manifest
        -del utils\*.pdb
        -del utils\*.ilk
-       -del tests\unit\*.pdk
        -del tests\unit\*.ilk
+       -del tests\unit\*.pdb
        -del tests\unit\var$(EE)
        -del tests\unit\smallset$(EE)
        -del tests\unit\varset$(EE)
index 287283c..6ad12d4 100644 (file)
@@ -58,6 +58,10 @@ MATLABDIR=/agbs/share/sw/matlab
 MEX=$(MATLABDIR)/bin/mex
 # Specify the same C++ compiler and flags to mex
 MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)'
+# Standard include directories for MEX
+MEXINC:=$(CCINC)
+# Additional library search paths for MEX
+MEXLIB=
 
 # SWIG PYTHON INTERFACE
 # The following should resolve to the SWIG command
index 2631e21..c6ec441 100644 (file)
@@ -30,13 +30,7 @@ ME=.mexglx
 
 # COMPILER
 # Compile using GNU C++ Compiler
-ifdef WITH_MATLAB
-# MatLab R2008b only works with older versions of g++
-  CC=g++-4.1
-else
-# If we don't build the MatLab interface, we prefer a newer version of g++
-  CC=g++
-endif
+CC=g++
 # Output filename option of the compiler
 CCO=-o
 # Flags for the C++ compiler
@@ -62,8 +56,13 @@ CCLIB=-Llib
 MATLABDIR=/agbs/share/sw/matlab
 # The following should resolve to the MatLab mex compile command
 MEX=$(MATLABDIR)/bin/mex
-# Specify the same C++ compiler and flags to mex
-MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)'
+# Specify the C++ compiler and flags for MEX
+# (MatLab R2008b only works with older versions of g++)
+MEXFLAGS:=CXX\#g++-4.1 CXXFLAGS\#'$(CCFLAGS)'
+# Standard include directories for MEX
+MEXINC:=$(CCINC)
+# Additional library search paths for MEX
+MEXLIB=
 
 # SWIG PYTHON INTERFACE
 # The following should resolve to the SWIG command
index e6cbb97..e009a7d 100644 (file)
@@ -57,6 +57,10 @@ MATLABDIR=/agbs/share/sw/matlab
 MEX=$(MATLABDIR)/bin/mex
 # Specify the same C++ compiler and flags to mex
 MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)'
+# Standard include directories for MEX
+MEXINC:=$(CCINC)
+# Additional library search paths for MEX
+MEXLIB=
 
 # SWIG PYTHON INTERFACE
 # The following should resolve to the SWIG command
index 90a371e..f3760bf 100644 (file)
@@ -26,7 +26,7 @@ OE=.obj
 # Binary executable
 EE=.exe
 # MatLab compiled MEX file
-ME=.mexglx
+ME=.mexw32
 
 # COMPILER
 # Compile using Visual C++ Compiler
@@ -34,13 +34,16 @@ CC=cl
 # Output filename option of the compiler
 CCO=/Fe
 # Flags for the C++ compiler
-CCFLAGS=/EHsc -DWINDOWS -DNOMINMAX
+CCFLAGS=/EHsc /GR /W3 /DWINDOWS /DNOMINMAX
+# For MatLab R2008b, the following flags seem to be necessary: /MD /D_SECURE_SCL=0
+# but the last one generates exceptions in executables... therefore, the MatLab 
+# interface is now built from source completely using mex
 # Flags to add in debugging mode (if DEBUG=true)
-CCDEBUGFLAGS=/Ox /Zi -DDAI_DEBUG
+CCDEBUGFLAGS=/Ox /Zi /DDAI_DEBUG
 # Flags to add in non-debugging mode (if DEBUG=false)
 CCNODEBUGFLAGS=/Ox
 # Standard include directories
-CCINC=/Iinclude /IE:\boost_1_42_0
+CCINC=-Iinclude -IE:\boost_1_42_0
 
 # LINKER
 # Standard libraries to include
@@ -54,11 +57,15 @@ CCLIB=/LIBPATH:"C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB" /LIB
 
 # MATLAB
 # Replace the following by the directory where MatLab has been installed
-MATLABDIR=c:\matlab
+MATLABDIR=c:\matlab\R2008b
 # The following should resolve to the MatLab mex compile command
 MEX=$(MATLABDIR)\bin\mex
-# Specify the same C++ compiler and flags to mex
-MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)'
+# Flags for MEX
+MEXFLAGS:=-DWINDOWS -DNOMINMAX
+# Standard include directories for MEX
+MEXINC:=$(CCINC)
+# Additional library search paths for MEX
+MEXLIB=
 
 # SWIG PYTHON INTERFACE
 # The following should resolve to the SWIG command
index cfb616c..48e135c 100644 (file)
@@ -149,6 +149,9 @@ template <typename T> class TFactor {
 
         /// Returns sum of all values
         T sum() const { return _p.sum(); }
+        
+        /// Returns sum of absolute values
+        T sumAbs() const { return _p.sumAbs(); }
 
         /// Returns maximum absolute value of all values
         T maxAbs() const { return _p.maxAbs(); }
@@ -161,6 +164,11 @@ template <typename T> class TFactor {
 
         /// Returns strength of this factor (between variables \a i and \a j), as defined in eq. (52) of [\ref MoK07b]
         T strength( const Var &i, const Var &j ) const;
+
+        /// Comparison
+        bool operator==( const TFactor<T>& y ) const {
+            return (_vs == y._vs) && (_p == y._p);
+        }
     //@}
 
     /// \name Unary transformations
index 81ca241..d7d6846 100644 (file)
@@ -286,6 +286,13 @@ class TProb {
         const_reverse_iterator rend() const { return _p.rend(); }
     //@}
 
+    /// \name Miscellaneous operations
+    //@{
+        void resize( size_t sz, T c = T() ) {
+            _p.resize( sz, c );
+        }
+    //@}
+
     /// \name Queries
     //@{
         /// Gets \a i 'th entry
index 04ea599..46a5a39 100644 (file)
@@ -10,6 +10,7 @@
 
 
 #include <string>
+#include <fstream>
 #include <dai/alldai.h>
 #include <dai/properties.h>
 #include <dai/exceptions.h>
index 1e1c313..256987f 100644 (file)
@@ -119,7 +119,7 @@ vector<Factor> mx2Factors(const mxArray *psi, long verbose) {
         }
         Permute permindex( di, perm );
         for( size_t li = 0; li < prod; li++ )
-            factors.back()[permindex.convertLinearIndex(li)] = factordata[li];
+            factors.back().set( permindex.convertLinearIndex(li), factordata[li] );
     }
 
     if( verbose >= 3 ) {
@@ -166,7 +166,7 @@ Factor mx2Factor(const mxArray *psi) {
     }
     Permute permindex( di, perm );
     for( size_t li = 0; li < prod; li++ )
-        factor[permindex.convertLinearIndex(li)] = factordata[li];
+        factor.set( permindex.convertLinearIndex(li), factordata[li] );
 
     return( factor );
 }
index 79c61a0..cb0441a 100644 (file)
@@ -31,146 +31,140 @@ const double tol = 1e-8;
 BOOST_AUTO_TEST_CASE( ConstructorsTest ) {
     // check constructors
     Factor x1;
-/*    BOOST_CHECK_EQUAL( x1.states(), 0 );
-    BOOST_CHECK( x1.p() == std::vector<Real>() );
-
-    Factor x2( 3 );
-    BOOST_CHECK_EQUAL( x2.states(), 3 );
-    BOOST_CHECK( x2.p() == std::vector<Real>( 3, 1.0 / 3.0 ) );
-    BOOST_CHECK_EQUAL( x2[0], 1.0 / 3.0 );
-    BOOST_CHECK_EQUAL( x2[1], 1.0 / 3.0 );
-    BOOST_CHECK_EQUAL( x2[2], 1.0 / 3.0 );
-
-    Factor x3( 4, 1.0 );
-    BOOST_CHECK_EQUAL( x3.states(), 4 );
-    BOOST_CHECK( x3.p() == std::vector<Real>( 4, 1.0 ) );
-    BOOST_CHECK_EQUAL( x3[0], 1.0 );
-    BOOST_CHECK_EQUAL( x3[1], 1.0 );
-    BOOST_CHECK_EQUAL( x3[2], 1.0 );
-    BOOST_CHECK_EQUAL( x3[3], 1.0 );
-    x3.set( 0, 0.5 );
-    x3.set( 1, 1.0 );
-    x3.set( 2, 2.0 );
-    x3.set( 3, 4.0 );
-
-    Factor x4( x3.begin(), x3.end() );
-    BOOST_CHECK_EQUAL( x4.states(), 4 );
-    BOOST_CHECK( x4.p() == x3.p() );
-    BOOST_CHECK_EQUAL( x4[0], 0.5 );
-    BOOST_CHECK_EQUAL( x4[1], 1.0 );
-    BOOST_CHECK_EQUAL( x4[2], 2.0 );
-    BOOST_CHECK_EQUAL( x4[3], 4.0 );
-
-    x3.p() = std::vector<Real>( 4, 2.5 );
-    Factor x5( x3.begin(), x3.end(), x3.states() );
-    BOOST_CHECK_EQUAL( x5.states(), 4 );
-    BOOST_CHECK( x5.p() == x3.p() );
-    BOOST_CHECK_EQUAL( x5[0], 2.5 );
-    BOOST_CHECK_EQUAL( x5[1], 2.5 );
-    BOOST_CHECK_EQUAL( x5[2], 2.5 );
-    BOOST_CHECK_EQUAL( x5[3], 2.5 );
-
-    std::vector<int> y( 3, 2 );
-    Factor x6( y );
-    BOOST_CHECK_EQUAL( x6.states(), 3 );
-    BOOST_CHECK( x6.p() == std::vector<Real>( 3, 2.0 ) );
-    BOOST_CHECK_EQUAL( x6[0], 2.0 );
-    BOOST_CHECK_EQUAL( x6[1], 2.0 );
-    BOOST_CHECK_EQUAL( x6[2], 2.0 );
-
-    Factor x7( x6 );
-    BOOST_CHECK( x7 == x6 );
+    BOOST_CHECK_EQUAL( x1.states(), 1 );
+    BOOST_CHECK( x1.p() == Prob( 1, 1.0 ) );
+    BOOST_CHECK( x1.vars() == VarSet() );
+
+    Factor x2( 5.0 );
+    BOOST_CHECK_EQUAL( x2.states(), 1 );
+    BOOST_CHECK( x2.p() == Prob( 1, 5.0 ) );
+    BOOST_CHECK( x2.vars() == VarSet() );
+
+    Var v1( 0, 3 );
+    Factor x3( v1 );
+    BOOST_CHECK_EQUAL( x3.states(), 3 );
+    BOOST_CHECK( x3.p() == Prob( 3, 1.0 / 3.0 ) );
+    BOOST_CHECK( x3.vars() == VarSet( v1 ) );
+    BOOST_CHECK_EQUAL( x3[0], 1.0 / 3.0 );
+    BOOST_CHECK_EQUAL( x3[1], 1.0 / 3.0 );
+    BOOST_CHECK_EQUAL( x3[2], 1.0 / 3.0 );
+
+    Var v2( 1, 2 );
+    Factor x4( VarSet( v1, v2 ) );
+    BOOST_CHECK_EQUAL( x4.states(), 6 );
+    BOOST_CHECK( x4.p() == Prob( 6, 1.0 / 6.0 ) );
+    BOOST_CHECK( x4.vars() == VarSet( v1, v2 ) );
+    for( size_t i = 0; i < 6; i++ )
+        BOOST_CHECK_EQUAL( x4[i], 1.0 / 6.0 );
+
+    Factor x5( VarSet( v1, v2 ), 1.0 );
+    BOOST_CHECK_EQUAL( x5.states(), 6 );
+    BOOST_CHECK( x5.p() == Prob( 6, 1.0 ) );
+    BOOST_CHECK( x5.vars() == VarSet( v1, v2 ) );
+    for( size_t i = 0; i < 6; i++ )
+        BOOST_CHECK_EQUAL( x5[i], 1.0 );
+
+    std::vector<Real> x( 6, 1.0 );
+    for( size_t i = 0; i < 6; i++ )
+        x[i] = 10.0 - i;
+    Factor x6( VarSet( v1, v2 ), x );
+    BOOST_CHECK_EQUAL( x6.states(), 6 );
+    BOOST_CHECK( x6.vars() == VarSet( v1, v2 ) );
+    for( size_t i = 0; i < 6; i++ )
+        BOOST_CHECK_EQUAL( x6[i], x[i] );
+
+    x.resize( 4 );
+    BOOST_CHECK_THROW( Factor x7( VarSet( v1, v2 ), x ), Exception );
+
+    x.resize( 6 );
+    x[4] = 10.0 - 4; x[5] = 10.0 - 5;
+    Factor x8( VarSet( v2, v1 ), &(x[0]) );
+    BOOST_CHECK_EQUAL( x8.states(), 6 );
+    BOOST_CHECK( x8.vars() == VarSet( v1, v2 ) );
+    for( size_t i = 0; i < 6; i++ )
+        BOOST_CHECK_EQUAL( x8[i], x[i] );
+
+    Prob xx( x );
+    Factor x9( VarSet( v2, v1 ), xx );
+    BOOST_CHECK_EQUAL( x9.states(), 6 );
+    BOOST_CHECK( x9.vars() == VarSet( v1, v2 ) );
+    for( size_t i = 0; i < 6; i++ )
+        BOOST_CHECK_EQUAL( x9[i], x[i] );
+
+    xx.resize( 4 );
+    BOOST_CHECK_THROW( Factor x10( VarSet( v2, v1 ), xx ), Exception );
+
+    std::vector<Real> w;
+    w.push_back( 0.1 );
+    w.push_back( 3.5 );
+    w.push_back( 2.8 );
+    w.push_back( 6.3 );
+    w.push_back( 8.4 );
+    w.push_back( 0.0 );
+    w.push_back( 7.4 );
+    w.push_back( 2.4 );
+    w.push_back( 8.9 );
+    w.push_back( 1.3 );
+    w.push_back( 1.6 );
+    w.push_back( 2.6 );
+    Var v4( 4, 3 );
+    Var v8( 8, 2 );
+    Var v7( 7, 2 );
+    std::vector<Var> vars;
+    vars.push_back( v4 );
+    vars.push_back( v8 );
+    vars.push_back( v7 );
+    Factor x11( vars, w );
+    BOOST_CHECK_EQUAL( x11.states(), 12 );
+    BOOST_CHECK( x11.vars() == VarSet( vars.begin(), vars.end() ) );
+    BOOST_CHECK_EQUAL( x11[0], 0.1 );
+    BOOST_CHECK_EQUAL( x11[1], 3.5 );
+    BOOST_CHECK_EQUAL( x11[2], 2.8 );
+    BOOST_CHECK_EQUAL( x11[3], 7.4 );
+    BOOST_CHECK_EQUAL( x11[4], 2.4 );
+    BOOST_CHECK_EQUAL( x11[5], 8.9 );
+    BOOST_CHECK_EQUAL( x11[6], 6.3 );
+    BOOST_CHECK_EQUAL( x11[7], 8.4 );
+    BOOST_CHECK_EQUAL( x11[8], 0.0 );
+    BOOST_CHECK_EQUAL( x11[9], 1.3 );
+    BOOST_CHECK_EQUAL( x11[10], 1.6 );
+    BOOST_CHECK_EQUAL( x11[11], 2.6 );
+
+    Factor x12( x11 );
+    BOOST_CHECK( x12 == x11 );
     
-    Factor x8 = x6;
-    BOOST_CHECK( x8 == x6 );*/
-}
-
-/*
-
-BOOST_AUTO_TEST_CASE( IteratorTest ) {
-    Prob x( 5, 0.0 );
-    size_t i;
-    for( i = 0; i < x.size(); i++ )
-        x.set( i, i );
-
-    i = 0;
-    for( Prob::const_iterator cit = x.begin(); cit != x.end(); cit++, i++ )
-        BOOST_CHECK_EQUAL( *cit, i );
-    
-    i = 0;
-    for( Prob::iterator it = x.begin(); it != x.end(); it++, i++ )
-        *it = 4 - i;
-    
-    i = 0;
-    for( Prob::const_iterator it = x.begin(); it != x.end(); it++, i++ )
-        BOOST_CHECK_EQUAL( *it, 4 - i );
-
-    i = 0;
-    for( Prob::const_reverse_iterator crit = x.rbegin(); crit != x.rend(); crit++, i++ )
-        BOOST_CHECK_EQUAL( *crit, i );
-
-    i = 0;
-    for( Prob::reverse_iterator rit = x.rbegin(); rit != x.rend(); rit++, i++ )
-        *rit = 2 * i;
-    
-    i = 0;
-    for( Prob::const_reverse_iterator crit = x.rbegin(); crit != x.rend(); crit++, i++ )
-        BOOST_CHECK_EQUAL( *crit, 2 * i );
+    Factor x13 = x12;
+    BOOST_CHECK( x13 == x11 );
 }
 
 
 BOOST_AUTO_TEST_CASE( QueriesTest ) {
-    Prob x( 5, 0.0 );
-    for( size_t i = 0; i < x.size(); i++ )
+    Factor x( Var( 5, 5 ), 0.0 );
+    for( size_t i = 0; i < x.states(); i++ )
         x.set( i, 2.0 - i );
 
-    // test accumulate, min, max, sum, sumAbs, maxAbs
+    // test min, max, sum, sumAbs, maxAbs
     BOOST_CHECK_EQUAL( x.sum(), 0.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 0.0, std::plus<Real>(), fo_id<Real>() ), 0.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 1.0, std::plus<Real>(), fo_id<Real>() ), 1.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -1.0, std::plus<Real>(), fo_id<Real>() ), -1.0 );
     BOOST_CHECK_EQUAL( x.max(), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -INFINITY, fo_max<Real>(), fo_id<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 3.0, fo_max<Real>(), fo_id<Real>() ), 3.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -5.0, fo_max<Real>(), fo_id<Real>() ), 2.0 );
     BOOST_CHECK_EQUAL( x.min(), -2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( INFINITY, fo_min<Real>(), fo_id<Real>() ), -2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -3.0, fo_min<Real>(), fo_id<Real>() ), -3.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 5.0, fo_min<Real>(), fo_id<Real>() ), -2.0 );
     BOOST_CHECK_EQUAL( x.sumAbs(), 6.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 0.0, std::plus<Real>(), fo_abs<Real>() ), 6.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 1.0, std::plus<Real>(), fo_abs<Real>() ), 7.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -1.0, std::plus<Real>(), fo_abs<Real>() ), 7.0 );
     BOOST_CHECK_EQUAL( x.maxAbs(), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 0.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 1.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -1.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 3.0, fo_max<Real>(), fo_abs<Real>() ), 3.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -3.0, fo_max<Real>(), fo_abs<Real>() ), 3.0 );
     x.set( 1, 1.0 );
     BOOST_CHECK_EQUAL( x.maxAbs(), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 0.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 1.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -1.0, fo_max<Real>(), fo_abs<Real>() ), 2.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 3.0, fo_max<Real>(), fo_abs<Real>() ), 3.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( -3.0, fo_max<Real>(), fo_abs<Real>() ), 3.0 );
-    for( size_t i = 0; i < x.size(); i++ )
-        x.set( i, i ? (1.0 / i) : 0.0 );
-    BOOST_CHECK_EQUAL( x.accumulate( 0.0, std::plus<Real>(), fo_inv0<Real>() ), 10.0 );
     x /= x.sum();
 
     // test entropy
     BOOST_CHECK( x.entropy() < Prob(5).entropy() );
     for( size_t i = 1; i < 100; i++ )
-        BOOST_CHECK_CLOSE( Prob(i).entropy(), std::log(i), tol );
+        BOOST_CHECK_CLOSE( Factor( Var(0,i) ).entropy(), std::log(i), tol );
 
     // test hasNaNs and hasNegatives
-    BOOST_CHECK( !Prob( 3, 0.0 ).hasNaNs() );
+    BOOST_CHECK( !Factor( 0.0 ).hasNaNs() );
     Real c = 0.0;
-    BOOST_CHECK( Prob( 3, c / c ).hasNaNs() );
-    BOOST_CHECK( !Prob( 3, 0.0 ).hasNegatives() );
-    BOOST_CHECK( !Prob( 3, 1.0 ).hasNegatives() );
-    BOOST_CHECK( Prob( 3, -1.0 ).hasNegatives() );
+    BOOST_CHECK( Factor( c / c ).hasNaNs() );
+    BOOST_CHECK( !Factor( 0.0 ).hasNegatives() );
+    BOOST_CHECK( !Factor( 1.0 ).hasNegatives() );
+    BOOST_CHECK( Factor( -1.0 ).hasNegatives() );
     x.set( 0, 0.0 ); x.set( 1, 0.0 ); x.set( 2, -1.0 ); x.set( 3, 1.0 ); x.set( 4, 100.0 );
     BOOST_CHECK( x.hasNegatives() );
     x.set( 2, -INFINITY );
@@ -179,77 +173,34 @@ BOOST_AUTO_TEST_CASE( QueriesTest ) {
     BOOST_CHECK( !x.hasNegatives() );
     x.set( 2, -1.0 );
 
-    // test argmax
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)100.0 ) );
-    x.set( 4, 0.5 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)3, (Real)1.0 ) );
-    x.set( 3, -2.0 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)0.5 ) );
-    x.set( 4, -1.0 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)0, (Real)0.0 ) );
-    x.set( 0, -2.0 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)1, (Real)0.0 ) );
-    x.set( 1, -3.0 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)2, (Real)-1.0 ) );
-    x.set( 2, -2.0 );
-    BOOST_CHECK( x.argmax() == std::make_pair( (size_t)4, (Real)-1.0 ) );
-
-    // test draw
-    for( size_t i = 0; i < x.size(); i++ )
-        x.set( i, i ? (1.0 / i) : 0.0 );
-    for( size_t repeat = 0; repeat < 10000; repeat++ ) {
-        BOOST_CHECK( x.draw() < x.size() );
-        BOOST_CHECK( x.draw() != 0 );
-    }
-    x.set( 2, 0.0 );
-    for( size_t repeat = 0; repeat < 10000; repeat++ ) {
-        BOOST_CHECK( x.draw() < x.size() );
-        BOOST_CHECK( x.draw() != 0 );
-        BOOST_CHECK( x.draw() != 2 );
-    }
-    x.set( 4, 0.0 );
-    for( size_t repeat = 0; repeat < 10000; repeat++ ) {
-        BOOST_CHECK( x.draw() < x.size() );
-        BOOST_CHECK( x.draw() != 0 );
-        BOOST_CHECK( x.draw() != 2 );
-        BOOST_CHECK( x.draw() != 4 );
-    }
-    x.set( 1, 0.0 );
-    for( size_t repeat = 0; repeat < 10000; repeat++ )
-        BOOST_CHECK( x.draw() == 3 );
-
-    // test <, ==
-    Prob a(3, 1.0), b(3, 1.0);
-    BOOST_CHECK( !(a < b) );
-    BOOST_CHECK( !(b < a) );
+    // test strength
+    Var x0(0,2);
+    Var x1(1,2);
+    BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, 1.0 ).strength( x0, x1 ), std::tanh( 1.0 ), tol );
+    BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, -1.0 ).strength( x0, x1 ), std::tanh( 1.0 ), tol );
+    BOOST_CHECK_CLOSE( createFactorIsing( x0, x1, 0.5 ).strength( x0, x1 ), std::tanh( 0.5 ), tol );
+
+    // test ==
+    Factor a(Var(0,3)), b(Var(0,3));
+    Factor d(Var(1,3));
+    BOOST_CHECK( !(a == d) );
+    BOOST_CHECK( !(b == d) );
     BOOST_CHECK( a == b );
     a.set( 0, 0.0 );
-    BOOST_CHECK( a < b );
-    BOOST_CHECK( !(b < a) );
     BOOST_CHECK( !(a == b) );
     b.set( 2, 0.0 );
-    BOOST_CHECK( a < b );
-    BOOST_CHECK( !(b < a) );
     BOOST_CHECK( !(a == b) );
     b.set( 0, 0.0 );
-    BOOST_CHECK( !(a < b) );
-    BOOST_CHECK( b < a );
     BOOST_CHECK( !(a == b) );
     a.set( 1, 0.0 );
-    BOOST_CHECK( a < b );
-    BOOST_CHECK( !(b < a) );
     BOOST_CHECK( !(a == b) );
     b.set( 1, 0.0 );
-    BOOST_CHECK( !(a < b) );
-    BOOST_CHECK( b < a );
     BOOST_CHECK( !(a == b) );
     a.set( 2, 0.0 );
-    BOOST_CHECK( !(a < b) );
-    BOOST_CHECK( !(b < a) );
     BOOST_CHECK( a == b );
 }
 
-
+/*
 BOOST_AUTO_TEST_CASE( UnaryTransformationsTest ) {
     Prob x( 3 );
     x.set( 0, -2.0 );