Miscellaneuos changes thanks to Dan Preston
authorJoris Mooij <joris@jorismooij.nl>
Thu, 5 Feb 2009 08:48:36 +0000 (09:48 +0100)
committerJoris Mooij <joris@jorismooij.nl>
Thu, 5 Feb 2009 08:48:36 +0000 (09:48 +0100)
* Improved Makefile (libDAI now also builds out-of-the-box on MacOSX,
  thanks to Dan Preston; merged Makefile.win and Makefile.shared into Makefile)
* Fixed bug in calcMarginal, calcPairBeliefs, calcPairBeliefsNew where
  states with zero probability mass were clamped, leading to NaNs or assertion
  errors (thanks to Dan Preston for reporting this)
* toc() now returns POSIX system time with maximum accuracy of microseconds
* Exception objects now remember their error code

12 files changed:
ChangeLog
Makefile
Makefile.shared [deleted file]
Makefile.win [deleted file]
README
include/dai/doc.h
include/dai/exceptions.h
include/dai/prob.h
include/dai/util.h
src/daialg.cpp
src/exceptions.cpp
src/util.cpp

index 3d0272f..6b9c3fb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,15 @@
-* [Peter Gober] Made libDAI compile out-of-the-box on Cygwin.
+* Improved Makefile (libDAI now also builds out-of-the-box on MacOSX, 
+  thanks to Dan Preston; merged Makefile.win and Makefile.shared into Makefile)
+* Fixed bug in calcMarginal, calcPairBeliefs, calcPairBeliefsNew where
+  states with zero probability mass were clamped, leading to NaNs or assertion
+  errors (thanks to Dan Preston for reporting this)
+* toc() now returns POSIX system time with maximum accuracy of microseconds
+* Exception objects now remember their error code
 
 
-git 39a4865f4eb0b32109ca50e7980028fed835adb9
+git 065eae35cbfcc36f1a945ae3053c80c23f366306
 --------------------------------------------
+* [Peter Gober] Made libDAI build out-of-the-box on Cygwin.
 * [Frederik Eaton] Added Gibbs sampler to algorithms
 * Improved documentation of include/dai/{bipgraph.h, prob.h, smallset.h,
   var.h, varset.h, factor.h, enum.h} and of examples/example.cpp
index 49f51cb..367dcfa 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,24 +1,31 @@
-#   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
+# Copyright (C) 2006-2009  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.
+# This file is part of libDAI.
 #
-#   libDAI is free software; you can redistribute it and/or modify
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2 of the License, or
-#   (at your option) any later version.
+# libDAI is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
 #
-#   libDAI is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
+# libDAI is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
 #
-#   You should have received a copy of the GNU General Public License
-#   along with libDAI; if not, write to the Free Software
-#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+# You should have received a copy of the GNU General Public License
+# along with libDAI; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 
+# Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX}
+# LINUX:   GNU/Linux and other UNIX variants
+# WINDOWS: Visual C++ with GNU Make
+# CYGWIN:  CygWin
+# MACOSX:  MacOSX
+OS=LINUX
+
 # Enable/disable various approximate inference methods
 WITH_BP=true
 WITH_MF=true
@@ -28,78 +35,340 @@ WITH_TREEEP=true
 WITH_JTREE=true
 WITH_MR=true
 WITH_GIBBS=true
+
 # Build with debug info?
 DEBUG=true
+
 # Build matlab interface?
 WITH_MATLAB=
 # New/old matlab version?
 NEW_MATLAB=true
 
-# Default OS = GNU/Linux
-# Windows Visual C++?
-WINDOWS=
-# Cygwin?
-CYGWIN=
-
 # Directories
+#   Location libDAI headers
 INC=include/dai
+#   Location of libDAI source files
 SRC=src
+#   Destination directory of libDAI library
 LIB=lib
+#   Additional iclude paths for C compiler
+CCINC=-Iinclude
 
 # Extensions (library, object, executable, matlab compiled MEX file)
-LE=.a
-OE=.o
-EE=
-ME=.mexglx
+ifneq ($(OS),WINDOWS)
+  LE=.a
+  OE=.o
+  EE=
+  ME=.mexglx
+else
+  LE=.lib
+  OE=.obj
+  EE=.exe
+  ME=.mexglx
+endif
 
 # Libraries
-LIBS=-ldai
+ifneq ($(OS),WINDOWS)
+  LIBS=-ldai
+  # Additional library paths for linker
+  CCLIB=-Llib
+else
+  # For some reason, we have to add the VC library path, although it is in the environment
+  LIBS=/link $(LIB)/libdai$(LE) /LIBPATH:"C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib"
+endif
 
-# We use the BOOST Program Options library
-ifdef CYGWIN
+# Tell the linker to link with the BOOST Program Options library
+ifeq ($(OS),CYGWIN)
   BOOSTLIBS=-lboost_program_options-gcc34-mt
-else
+endif
+ifeq ($(OS),MACOSX)
+  BOOSTLIBS=-lboost_program_options-mt
+endif
+ifeq ($(OS),LINUX)
   BOOSTLIBS=-lboost_program_options
 endif
+ifeq ($(OS),WINDOWS)
+  BOOSTLIBS=/LIBPATH:C:\boost_1_36_0\stage\lib
+endif
 
-# Compile using GNU C++ Compiler
-CC=g++
-# Output filename option
-CCO=-o
+# Compiler specific options
+ifneq ($(OS),WINDOWS)
+  # Compile using GNU C++ Compiler
+  CC=g++
+  # Output filename option of the compiler
+  CCO=-o 
+else
+  # Compile using Visual C++ Compiler
+  CC=cl
+  # Output filename option
+  CCO=/Fe
+endif
 
 # Flags for the C++ compiler
-CCFLAGS=-O3 -Wno-deprecated -Wall -W -Wextra -fpic -Iinclude -Llib
-ifdef CYGWIN
-  CCFLAGS:=$(CCFLAGS) -I/usr/local/include/boost-1_37 -DCYGWIN -static
+ifneq ($(OS),WINDOWS)
+  CCFLAGS=-O3 -Wno-deprecated -Wall -W -Wextra -fpic
+  CCDEBUGFLAGS=-g -DDAI_DEBUG
+else
+  CCFLAGS=/Iinclude /IC:\boost_1_36_0 /EHsc /Ox
+  CCDEBUGFLAGS=/Zi -DDAI_DEBUG
+endif
+
+ifeq ($(OS),CYGWIN)
+  CCINC:=$(CCINC) -I/usr/local/include/boost-1_37
   # dynamic linking of Boost libraries seems not to work on Cygwin
+  CCFLAGS:=$(CCFLAGS) -DCYGWIN -static
+endif
+ifeq ($(OS),MACOSX)
+  # indicate where your boost headers and libraries are (likely where macports installs libraries)
+  CCINC:=$(CCINC) -I/opt/local/include
+  CCLIB:=$(CCLIB) -L/opt/local/lib
 endif
-CCDEBUGFLAGS=-g -DDAI_DEBUG
 
 # Build targets
-TARGETS=tests utils $(LIB)/libdai$(LE) examples testregression doc
+TARGETS=tests utils $(LIB)/libdai$(LE) examples testregression
+ifneq ($(OS),WINDOWS)
+  TARGETS:=$(TARGETS) doc 
+endif
 
 ifdef WITH_MATLAB
-       # Replace the following by the directory where Matlab has been installed
-       MATLABDIR=/agbs/share/sw/matlab
-       MEX=$(MATLABDIR)/bin/mex
-       MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#'-O3 -Wno-deprecated -Wall -W -Wextra -fpic'
+  ifneq ($(OS),WINDOWS)
+    # Replace the following by the directory where Matlab has been installed
+    MATLABDIR=/agbs/share/sw/matlab
+    MEX=$(MATLABDIR)/bin/mex
+    MEXFLAGS=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)'
+  else
+    # Replace the following by the directory where Matlab has been installed
+    MATLABDIR=c:\matlab
+    MEX=$(MATLABDIR)\bin\mex
+    MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#"/EHsc /Ox"
+  endif
+endif
+
+
+ifdef DEBUG
+  CCFLAGS:=$(CCFLAGS) $(CCDEBUGFLAGS)
+endif
+ifeq ($(OS),WINDOWS)
+  CCFLAGS:=$(CCFLAGS) -DWINDOWS
+endif
+ifdef WITH_MATLAB
+  TARGETS:=$(TARGETS) matlabs
+  ifdef NEW_MATLAB
+    MEXFLAGS:=$(MEXFLAGS) -largeArrayDims
+  else
+    MEXFLAGS:=$(MEXFLAGS) -DSMALLMEM
+  endif
+endif
+
+
+OBJECTS:=exactinf$(OE)
+ifdef WITH_BP
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_BP
+  OBJECTS:=$(OBJECTS) bp$(OE)
+endif
+ifdef WITH_MF
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MF
+  OBJECTS:=$(OBJECTS) mf$(OE)
+endif
+ifdef WITH_HAK
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_HAK
+  OBJECTS:=$(OBJECTS) hak$(OE)
+endif
+ifdef WITH_LC
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_LC
+  OBJECTS:=$(OBJECTS) lc$(OE)
+endif
+ifdef WITH_TREEEP
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_TREEEP
+  OBJECTS:=$(OBJECTS) treeep$(OE)
+endif
+ifdef WITH_JTREE
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_JTREE
+  OBJECTS:=$(OBJECTS) jtree$(OE)
 endif
+ifdef WITH_MR
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MR
+  OBJECTS:=$(OBJECTS) mr$(OE)
+endif
+ifdef WITH_GIBBS
+  CCFLAGS:=$(CCFLAGS) -DDAI_WITH_GIBBS
+  OBJECTS:=$(OBJECTS) gibbs$(OE)
+endif
+
+
+HEADERS=$(INC)/bipgraph.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
+
+
+CC:=$(CC) $(CCINC) $(CCLIB) $(CCFLAGS)
+MEX:=$(MEX) $(CCLIB) $(CCINC) $(MEXFLAGS)
+
+
+# META TARGETS
+###############
+
+all : $(TARGETS)
+
+examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE)
+
+matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
+
+tests : tests/testdai$(EE)
+
+utils : utils/createfg$(EE) utils/fg2dot$(EE) utils/fginfo$(EE)
+
+
+# OBJECTS
+##########
+
+bipgraph$(OE) : $(SRC)/bipgraph.cpp $(HEADERS)
+       $(CC) -c $(SRC)/bipgraph.cpp
+
+daialg$(OE) : $(SRC)/daialg.cpp $(HEADERS)
+       $(CC) -c $(SRC)/daialg.cpp
+
+exactinf$(OE) : $(SRC)/exactinf.cpp $(INC)/exactinf.h $(HEADERS)
+       $(CC) -c $(SRC)/exactinf.cpp
+
+bp$(OE) : $(SRC)/bp.cpp $(INC)/bp.h $(HEADERS)
+       $(CC) -c $(SRC)/bp.cpp
 
+lc$(OE) : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)
+       $(CC) -c $(SRC)/lc.cpp
 
-include Makefile.shared
+mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
+       $(CC) -c $(SRC)/mf.cpp
 
+factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
+       $(CC) -c $(SRC)/factorgraph.cpp
 
+util$(OE) : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)
+       $(CC) -c $(SRC)/util.cpp
+
+regiongraph$(OE) : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)
+       $(CC) -c $(SRC)/regiongraph.cpp
+
+hak$(OE) : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h
+       $(CC) -c $(SRC)/hak.cpp
+
+clustergraph$(OE) : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)
+       $(CC) -c $(SRC)/clustergraph.cpp
+
+jtree$(OE) : $(SRC)/jtree.cpp $(INC)/jtree.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h
+       $(CC) -c $(SRC)/jtree.cpp
+
+treeep$(OE) : $(SRC)/treeep.cpp $(INC)/treeep.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h $(INC)/jtree.h
+       $(CC) -c $(SRC)/treeep.cpp
+
+weightedgraph$(OE) : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)
+       $(CC) -c $(SRC)/weightedgraph.cpp
+
+mr$(OE) : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)
+       $(CC) -c $(SRC)/mr.cpp
+
+gibbs$(OE) : $(SRC)/gibbs.cpp $(INC)/gibbs.h $(HEADERS)
+       $(CC) -c $(SRC)/gibbs.cpp
+
+properties$(OE) : $(SRC)/properties.cpp $(HEADERS)
+       $(CC) -c $(SRC)/properties.cpp
+
+exceptions$(OE) : $(SRC)/exceptions.cpp $(HEADERS)
+       $(CC) -c $(SRC)/exceptions.cpp
+
+alldai$(OE) : $(SRC)/alldai.cpp $(HEADERS)
+       $(CC) -c $(SRC)/alldai.cpp
+
+
+# EXAMPLES
+###########
+
+examples/example$(EE) : examples/example.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)examples/example$(EE) examples/example.cpp $(LIBS)
+
+examples/example_bipgraph$(EE) : examples/example_bipgraph.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)examples/example_bipgraph$(EE) examples/example_bipgraph.cpp $(LIBS)
+
+examples/example_varset$(EE) : examples/example_varset.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)examples/example_varset$(EE) examples/example_varset.cpp $(LIBS)
+
+
+# TESTS
+########
+
+tests/testdai$(EE) : tests/testdai.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)tests/testdai$(EE) tests/testdai.cpp $(LIBS) $(BOOSTLIBS)
+
+
+# MATLAB INTERFACE
+###################
+
+matlab/dai$(ME) : $(SRC)/matlab/dai.cpp $(HEADERS) matlab$(OE) $(LIB)/libdai$(LE)
+       $(MEX) -o matlab/dai $(SRC)/matlab/dai.cpp matlab$(OE) $(LIB)/libdai$(LE)
+
+matlab/dai_readfg$(ME) : $(SRC)/matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
+       $(MEX) -o matlab/dai_readfg $(SRC)/matlab/dai_readfg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
+
+matlab/dai_writefg$(ME) : $(SRC)/matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
+       $(MEX) -o matlab/dai_writefg $(SRC)/matlab/dai_writefg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
+
+matlab/dai_potstrength$(ME) : $(SRC)/matlab/dai_potstrength.cpp $(HEADERS) matlab$(OE) exceptions$(OE)
+       $(MEX) -o matlab/dai_potstrength $(SRC)/matlab/dai_potstrength.cpp matlab$(OE) exceptions$(OE)
+
+matlab$(OE) : $(SRC)/matlab/matlab.cpp $(INC)/matlab/matlab.h $(HEADERS)
+       $(MEX) -c $(SRC)/matlab/matlab.cpp
+
+
+# UTILS
+########
+
+utils/createfg$(EE) : utils/createfg.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)utils/createfg$(EE) utils/createfg.cpp $(LIBS) $(BOOSTLIBS)
+
+utils/fg2dot$(EE) : utils/fg2dot.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)utils/fg2dot$(EE) utils/fg2dot.cpp $(LIBS)
+
+utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCO)utils/fginfo$(EE) utils/fginfo.cpp $(LIBS)
+
+
+# LIBRARY
+##########
+
+ifneq ($(OS),WINDOWS)
 $(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
        -mkdir -p lib
        ar rcus $(LIB)/libdai$(LE) bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+else
+$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+       -mkdir lib
+       lib /out:$(LIB)/libdai$(LE) bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)
+endif
+
+
+# REGRESSION TESTS
+###################
 
+ifneq ($(OS),WINDOWS)
 testregression : tests/testdai$(EE)
        @echo Starting regression test...this can take a minute or so!
        cd tests && ./testregression && cd ..
+else
+testregression : tests/testdai$(EE)
+       @echo Starting regression test...this can take a minute or so!
+       cd tests && testregression.bat && cd ..
+endif
+
+
+# DOCUMENTATION
+################
 
 doc : $(INC)/*.h $(SRC)/*.cpp examples/*.cpp doxygen.conf
        doxygen doxygen.conf
 
+
+# CLEAN
+########
+
+ifneq ($(OS),WINDOWS)
 .PHONY : clean
 clean :
        -rm *$(OE)
@@ -109,3 +378,8 @@ clean :
        -rm utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE)
        -rm -R doc
        -rm -R lib
+else
+.PHONY : clean
+clean :
+       -del *$(OE) *.ilk *.pdb *$(EE) matlab\*$(ME) examples\*$(EE) examples\*.ilk examples\*.pdb tests\testdai$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE)
+endif
diff --git a/Makefile.shared b/Makefile.shared
deleted file mode 100644 (file)
index c137f74..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-#   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
-#   it under the terms of the GNU General Public License as published by
-#   the Free Software Foundation; either version 2 of the License, or
-#   (at your option) any later version.
-#
-#   libDAI is distributed in the hope that it will be useful,
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#   GNU General Public License for more details.
-#
-#   You should have received a copy of the GNU General Public License
-#   along with libDAI; if not, write to the Free Software
-#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-
-ifdef DEBUG
-       CCFLAGS:=$(CCFLAGS) $(CCDEBUGFLAGS)
-endif
-ifdef WINDOWS
-       CCFLAGS:=$(CCFLAGS) -DWINDOWS
-endif
-ifdef WITH_MATLAB
-       TARGETS:=$(TARGETS) matlabs
-       ifdef DEBUG
-               MEXFLAGS:=$(MEXFLAGS) $(CCDEBUGFLAGS)
-       endif
-       ifdef NEW_MATLAB
-               MEXFLAGS:=$(MEXFLAGS) -largeArrayDims
-       else
-               MEXFLAGS:=$(MEXFLAGS) -DSMALLMEM
-       endif
-endif
-
-
-OBJECTS:=exactinf$(OE)
-ifdef WITH_BP
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_BP
-       OBJECTS:=$(OBJECTS) bp$(OE)
-endif
-ifdef WITH_MF
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MF
-       OBJECTS:=$(OBJECTS) mf$(OE)
-endif
-ifdef WITH_HAK
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_HAK
-       OBJECTS:=$(OBJECTS) hak$(OE)
-endif
-ifdef WITH_LC
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_LC
-       OBJECTS:=$(OBJECTS) lc$(OE)
-endif
-ifdef WITH_TREEEP
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_TREEEP
-       OBJECTS:=$(OBJECTS) treeep$(OE)
-endif
-ifdef WITH_JTREE
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_JTREE
-       OBJECTS:=$(OBJECTS) jtree$(OE)
-endif
-ifdef WITH_MR
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_MR
-       OBJECTS:=$(OBJECTS) mr$(OE)
-endif
-ifdef WITH_GIBBS
-       CCFLAGS:=$(CCFLAGS) -DDAI_WITH_GIBBS
-       OBJECTS:=$(OBJECTS) gibbs$(OE)
-endif
-
-
-HEADERS=$(INC)/bipgraph.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
-
-
-all : $(TARGETS)
-
-examples : examples/example$(EE) examples/example_bipgraph$(EE) examples/example_varset$(EE)
-
-matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
-
-tests : tests/testdai$(EE)
-
-utils : utils/createfg$(EE) utils/fg2dot$(EE) utils/fginfo$(EE)
-
-
-bipgraph$(OE) : $(SRC)/bipgraph.cpp $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/bipgraph.cpp
-
-daialg$(OE) : $(SRC)/daialg.cpp $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/daialg.cpp
-
-exactinf$(OE) : $(SRC)/exactinf.cpp $(INC)/exactinf.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/exactinf.cpp
-
-bp$(OE) : $(SRC)/bp.cpp $(INC)/bp.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/bp.cpp
-
-lc$(OE) : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/lc.cpp
-
-mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/mf.cpp
-
-factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/factorgraph.cpp
-
-util$(OE) : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/util.cpp
-
-regiongraph$(OE) : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/regiongraph.cpp
-
-hak$(OE) : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h
-       $(CC) $(CCFLAGS) -c $(SRC)/hak.cpp
-
-clustergraph$(OE) : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/clustergraph.cpp
-
-jtree$(OE) : $(SRC)/jtree.cpp $(INC)/jtree.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h
-       $(CC) $(CCFLAGS) -c $(SRC)/jtree.cpp
-
-treeep$(OE) : $(SRC)/treeep.cpp $(INC)/treeep.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h $(INC)/jtree.h
-       $(CC) $(CCFLAGS) -c $(SRC)/treeep.cpp
-
-weightedgraph$(OE) : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/weightedgraph.cpp
-
-mr$(OE) : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/mr.cpp
-
-gibbs$(OE) : $(SRC)/gibbs.cpp $(INC)/gibbs.h $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/gibbs.cpp
-
-properties$(OE) : $(SRC)/properties.cpp $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/properties.cpp
-
-exceptions$(OE) : $(SRC)/exceptions.cpp $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/exceptions.cpp
-
-alldai$(OE) : $(SRC)/alldai.cpp $(HEADERS)
-       $(CC) $(CCFLAGS) -c $(SRC)/alldai.cpp
-
-
-# EXAMPLES
-###########
-
-examples/example$(EE) : examples/example.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)examples/example$(EE) examples/example.cpp $(LIBS)
-
-examples/example_bipgraph$(EE) : examples/example_bipgraph.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)examples/example_bipgraph$(EE) examples/example_bipgraph.cpp $(LIBS)
-
-examples/example_varset$(EE) : examples/example_varset.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)examples/example_varset$(EE) examples/example_varset.cpp $(LIBS)
-
-
-# TESTS
-########
-
-tests/testdai$(EE) : tests/testdai.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)tests/testdai$(EE) tests/testdai.cpp $(LIBS) $(BOOSTLIBS)
-
-
-# MATLAB INTERFACE
-###################
-
-matlab/dai$(ME) : $(SRC)/matlab/dai.cpp $(HEADERS) matlab$(OE) $(LIB)/libdai$(LE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai $(SRC)/matlab/dai.cpp matlab$(OE) $(LIB)/libdai$(LE)
-
-matlab/dai_readfg$(ME) : $(SRC)/matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg $(SRC)/matlab/dai_readfg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
-
-matlab/dai_writefg$(ME) : $(SRC)/matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg $(SRC)/matlab/dai_writefg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
-
-matlab/dai_potstrength$(ME) : $(SRC)/matlab/dai_potstrength.cpp $(HEADERS) matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength $(SRC)/matlab/dai_potstrength.cpp matlab$(OE) exceptions$(OE)
-
-matlab$(OE) : $(SRC)/matlab/matlab.cpp $(INC)/matlab/matlab.h $(HEADERS)
-       $(MEX) $(MEXFLAGS) -c $(SRC)/matlab/matlab.cpp
-
-
-# UTILS
-########
-
-utils/createfg$(EE) : utils/createfg.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)utils/createfg$(EE) utils/createfg.cpp $(LIBS) $(BOOSTLIBS)
-
-utils/fg2dot$(EE) : utils/fg2dot.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)utils/fg2dot$(EE) utils/fg2dot.cpp $(LIBS)
-
-utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
-       $(CC) $(CCFLAGS) $(CCO)utils/fginfo$(EE) utils/fginfo.cpp $(LIBS)
diff --git a/Makefile.win b/Makefile.win
deleted file mode 100755 (executable)
index 459e41a..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-#   Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]\r
-#   Radboud University Nijmegen, The Netherlands /\r
-#   Max Planck Institute for Biological Cybernetics, Germany\r
-#   \r
-#   This file is part of libDAI.\r
-#\r
-#   libDAI is free software; you can redistribute it and/or modify\r
-#   it under the terms of the GNU General Public License as published by\r
-#   the Free Software Foundation; either version 2 of the License, or\r
-#   (at your option) any later version.\r
-#\r
-#   libDAI is distributed in the hope that it will be useful,\r
-#   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-#   GNU General Public License for more details.\r
-#\r
-#   You should have received a copy of the GNU General Public License\r
-#   along with libDAI; if not, write to the Free Software\r
-#   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
-\r
-\r
-# Enable/disable various approximate inference methods\r
-WITH_BP=true\r
-WITH_MF=true\r
-WITH_HAK=true\r
-WITH_LC=true\r
-WITH_TREEEP=true\r
-WITH_JTREE=true\r
-WITH_MR=true\r
-WITH_GIBBS=true\r
-# Build with debug info?\r
-DEBUG=true\r
-# Build matlab interface?\r
-WITH_MATLAB=\r
-# New/old matlab version?\r
-NEW_MATLAB=true\r
-# Windows or linux (default)?\r
-WINDOWS=true\r
-\r
-# Directories\r
-INC=include/dai\r
-SRC=src\r
-LIB=lib\r
-\r
-# Extensions (library, object, executable, matlab compiled MEX file)\r
-LE=.lib\r
-OE=.obj\r
-EE=.exe\r
-ME=.mexglx\r
-\r
-# Libraries (for some reason, we have to add the VC library path, although it is in the environment)\r
-LIBS=/link $(LIB)/libdai$(LE) /LIBPATH:"C:\Program Files\Microsoft Visual Studio 9.0\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files\Microsoft Visual Studio 9.0\VC\LIB" /LIBPATH:"C:\Program Files\Microsoft SDKs\Windows\v6.0A\lib"\r
-\r
-# We use the BOOST Program Options library\r
-BOOSTLIBS=/LIBPATH:C:\boost_1_36_0\stage\lib\r
-\r
-# Compile using Visual C++ Compiler\r
-CC=cl\r
-# Output filename option\r
-CCO=/Fe\r
-\r
-# Flags for the C++ compiler\r
-CCFLAGS=/Iinclude /IC:\boost_1_36_0 /EHsc /Ox\r
-CCDEBUGFLAGS=/Zi -DDAI_DEBUG\r
-\r
-# Build targets\r
-TARGETS=tests utils $(LIB)/libdai$(LE) examples testregression # doc\r
-\r
-ifdef WITH_MATLAB\r
-       # Replace the following by the directory where Matlab has been installed\r
-       MATLABDIR=c:\matlab\r
-       MEX=$(MATLABDIR)\bin\mex\r
-       MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#"/EHsc /Ox"\r
-endif\r
-\r
-\r
-include Makefile.shared\r
-\r
-\r
-$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)\r
-       -mkdir lib\r
-       lib /out:$(LIB)/libdai$(LE) bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) exceptions$(OE) $(OBJECTS)\r
-\r
-testregression : tests/testdai$(EE)\r
-       @echo Starting regression test...this can take a minute or so!\r
-       cd tests && testregression.bat && cd ..\r
-\r
-doc : $(INC)/*.h $(SRC)/*.cpp examples/*.cpp doxygen.conf\r
-       doxygen doxygen.conf\r
-\r
-.PHONY : clean\r
-clean :\r
-       -del *$(OE) *.ilk *.pdb *$(EE) matlab\*$(ME) examples\*$(EE) examples\*.ilk examples\*.pdb tests\testdai$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE)\r
diff --git a/README b/README
index d711e7f..0eec502 100644 (file)
--- a/README
+++ b/README
@@ -141,15 +141,15 @@ You need:
 - GNU make
 - doxygen
 - graphviz
-- recent boost C++ libraries (at least version 1.34)
+- recent boost C++ libraries (at least version 1.34 or 1.37 for cygwin)
 
 On Debian/Ubuntu, you can easily install all these packages with a single command:
 "apt-get install g++ make doxygen libboost-dev libboost-graph-dev libboost-program-options-dev"
 (root permissions needed).
 
 On Cygwin, the prebuilt Cygwin package boost-1.33.1-x is known not to work.
-You can however obtain the latest boost version from http://www.boost.org/
-and compile/install it with:
+You can however obtain the latest boost version (you need at least 1.37.0)
+from http://www.boost.org/ and compile/install it with:
 
   ./configure
   make
@@ -175,7 +175,7 @@ You need:
 - recent boost C++ libraries (version 1.34 or higher)
 - GNU make (can be obtained from http://gnuwin32.sourceforge.net)
 For the regression test, you need:
-- GNU diff (can be obtained from http://gnuwin32.sourceforge.net)
+- GNU diff, GNU sed (can be obtained from http://gnuwin32.sourceforge.net)
 
 To build the source, edit the Makefile and adapt it to your local setup. Then, run (from the command line)
     
index 99223ae..d201fe5 100644 (file)
  *  - Generalized Belief Propagation [\ref YFW05];
  *  - Double-loop GBP [\ref HAK03];
  *  - Various variants of Loop Corrected Belief Propagation
- *    [\ref MoK07, \ref MoR05].
+ *    [\ref MoK07, \ref MoR05];
+ *  - Gibbs sampler.
  *
  *  \section language Why C++?
  *  Because libDAI is implemented in C++, it is very fast compared with
index 0ecb329..5f5681c 100644 (file)
@@ -57,26 +57,37 @@ namespace dai {
 /// Represents an exception (based on std::runtime_error)
 class Exception : public std::runtime_error {
     public:
+        /// Enumeration of exceptions used in libDAI
+        enum Code {NOT_IMPLEMENTED,
+                   UNKNOWN_DAI_ALGORITHM,
+                   UNKNOWN_PROPERTY_TYPE,
+                   MALFORMED_PROPERTY,
+                   UNKNOWN_ENUM_VALUE,
+                   CANNOT_READ_FILE,
+                   CANNOT_WRITE_FILE,
+                   INVALID_FACTORGRAPH_FILE,
+                   NOT_ALL_PROPERTIES_SPECIFIED,
+                   MULTIPLE_UNDO,
+                   FACTORGRAPH_NOT_CONNECTED,
+                   IMPOSSIBLE_TYPECAST,
+                   INTERNAL_ERROR,
+                   NOT_NORMALIZABLE,
+                   NUM_ERRORS};  // NUM_ERRORS should be the last entry
+
         /// Constructor
-            Exception(size_t code, const std::string& msg = "") : std::runtime_error(ErrorStrings[code] + " [" +  msg + "]") {}
+        Exception( Code _code, const std::string& msg="" ) : std::runtime_error(ErrorStrings[_code] + " [" +  msg + "]"), errorcode(_code) {}
+
+        /// Copy constructor
+        Exception( const Exception &e ) : std::runtime_error(e), errorcode(e.errorcode) {}
+
+        /// Returns error code of this exception
+        Code code() const { return errorcode; }
 
-        /// Enumeration of exceptions used in libDAI
-        enum codes {NOT_IMPLEMENTED,
-                    UNKNOWN_DAI_ALGORITHM,
-                    UNKNOWN_PROPERTY_TYPE,
-                    MALFORMED_PROPERTY,
-                    UNKNOWN_ENUM_VALUE,
-                    CANNOT_READ_FILE,
-                    CANNOT_WRITE_FILE,
-                    INVALID_FACTORGRAPH_FILE,
-                    NOT_ALL_PROPERTIES_SPECIFIED,
-                    MULTIPLE_UNDO,
-                    FACTORGRAPH_NOT_CONNECTED,
-                    IMPOSSIBLE_TYPECAST,
-                    INTERNAL_ERROR,
-                    NUM_ERRORS};  // NUM_ERRORS should be the last entry
 
     private:
+        /// Contains the error code of this exception
+        Code errorcode;
+
         /// Error messages corresponding to the exceptions enumerated above
         static std::string ErrorStrings[NUM_ERRORS];
 };
index 629f4d3..f251b05 100644 (file)
@@ -37,6 +37,7 @@
 #include <numeric>
 #include <functional>
 #include <dai/util.h>
+#include <dai/exceptions.h>
 
 
 namespace dai {
@@ -420,10 +421,10 @@ template <typename T> class TProb {
                 Z = totalSum();
             else if( norm == NORMLINF )
                 Z = maxAbs();
-#ifdef DAI_DEBUG
-            assert( Z != 0.0 );
-#endif
-            *this /= Z;
+            if( Z == 0.0 )
+                DAI_THROW(NOT_NORMALIZABLE);
+            else
+                *this /= Z;
             return Z;
         }
 
index 5061e4d..ca3e173 100644 (file)
@@ -64,6 +64,9 @@ typedef double Real;
 
     /// Returns log(1+x)
     double log1p( double x );
+
+    /// Define INFINITY
+    #define INFINITY (std::numeric_limits<double>::infinity())
 #endif
 
 
@@ -85,7 +88,7 @@ namespace dai {
 #endif
 
 
-/// Returns the time in seconds
+/// Returns wall clock time in seconds
 double toc();
 
 
index 79f9daa..ce18883 100644 (file)
@@ -31,6 +31,8 @@ using namespace std;
 
 
 /// Calculates the marginal of obj on ns by clamping all variables in ns and calculating logZ for each joined state.
+/*  reInit should be set to true if at least one of the possible clamped states would be invalid (leading to a factor graph with zero partition sum).
+ */
 Factor calcMarginal( const InfAlg & obj, const VarSet & ns, bool reInit ) {
     Factor Pns (ns);
     
@@ -38,7 +40,7 @@ Factor calcMarginal( const InfAlg & obj, const VarSet & ns, bool reInit ) {
     if( !reInit )
         clamped->init();
 
-    Real logZ0 = 0.0;
+    Real logZ0 = -INFINITY;
     for( State s(ns); s.valid(); s++ ) {
         // save unclamped factors connected to ns
         clamped->backupFactors( ns );
@@ -52,18 +54,26 @@ Factor calcMarginal( const InfAlg & obj, const VarSet & ns, bool reInit ) {
             clamped->init();
         else
             clamped->init(ns);
-        clamped->run();
-
-        Real Z;
-        if( s == 0 ) {
-            logZ0 = clamped->logZ();
-            Z = 1.0;
-        } else {
-            // subtract logZ0 to avoid very large numbers
-            Z = exp(clamped->logZ() - logZ0);
+
+        Real logZ;
+        try {
+            clamped->run();
+            logZ = clamped->logZ();
+        } catch( Exception &e ) {
+            if( e.code() == Exception::NOT_NORMALIZABLE )
+                logZ = -INFINITY;
+            else
+                throw;
         }
 
-        Pns[s] = Z;
+        if( logZ0 == -INFINITY )
+            if( logZ != -INFINITY )
+                logZ0 = logZ;
+
+        if( logZ == -INFINITY )
+            Pns[s] = 0;
+        else
+            Pns[s] = exp(logZ - logZ0); // subtract logZ0 to avoid very large numbers
         
         // restore clamped factors
         clamped->restoreFactors( ns );
@@ -76,6 +86,8 @@ Factor calcMarginal( const InfAlg & obj, const VarSet & ns, bool reInit ) {
 
 
 /// Calculates beliefs of all pairs in ns (by clamping nodes in ns and calculating logZ and the beliefs for each state).
+/*  reInit should be set to true if at least one of the possible clamped states would be invalid (leading to a factor graph with zero partition sum).
+ */
 vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& ns, bool reInit ) {
     // convert ns to vector<VarSet>
     size_t N = ns.size();
@@ -97,7 +109,7 @@ vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& ns, bool reIni
     if( !reInit )
         clamped->init();
 
-    Real logZ0 = 0.0;
+    Real logZ0 = -INFINITY;
     for( size_t j = 0; j < N; j++ ) {
         // clamp Var j to its possible values
         for( size_t j_val = 0; j_val < vns[j].states(); j_val++ ) {
@@ -106,18 +118,28 @@ vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& ns, bool reIni
                 clamped->init();
             else
                 clamped->init(ns);
-            clamped->run();
 
-            //if( j == 0 )
-            //  logZ0 = obj.logZ();
-            double Z_xj = 1.0;
-            if( j == 0 && j_val == 0 ) {
-                logZ0 = clamped->logZ();
-            } else {
-                // subtract logZ0 to avoid very large numbers
-                Z_xj = exp(clamped->logZ() - logZ0);
+            Real logZ;
+            try {
+                clamped->run();
+                logZ = clamped->logZ();
+            } catch( Exception &e ) {
+                if( e.code() == Exception::NOT_NORMALIZABLE )
+                    logZ = -INFINITY;
+                else
+                    throw;
             }
 
+            if( logZ0 == -INFINITY )
+                if( logZ != -INFINITY )
+                    logZ0 = logZ;
+
+            double Z_xj;
+            if( logZ == -INFINITY )
+                Z_xj = 0;
+            else
+                Z_xj = exp(logZ - logZ0); // subtract logZ0 to avoid very large numbers
+
             for( size_t k = 0; k < N; k++ ) 
                 if( k != j ) {
                     Factor b_k = clamped->belief(vns[k]);
@@ -140,13 +162,15 @@ vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& ns, bool reIni
     result.reserve( N * (N - 1) / 2 );
     for( size_t j = 0; j < N; j++ )
         for( size_t k = j+1; k < N; k++ )
-            result.push_back( (pairbeliefs[j * N + k] * pairbeliefs[k * N + j]) ^ 0.5 );
+            result.push_back( ((pairbeliefs[j * N + k] * pairbeliefs[k * N + j]) ^ 0.5).normalized() );
 
     return result;
 }
 
 
 /// Calculates beliefs of all pairs in ns (by clamping pairs in ns and calculating logZ for each joined state).
+/*  reInit should be set to true if at least one of the possible clamped states would be invalid (leading to a factor graph with zero partition sum).
+ */
 Factor calcMarginal2ndO( const InfAlg & obj, const VarSet& ns, bool reInit ) {
     // returns a a probability distribution whose 1st order interactions
     // are unspecified, whose 2nd order interactions approximate those of 
@@ -190,16 +214,28 @@ vector<Factor> calcPairBeliefsNew( const InfAlg & obj, const VarSet& ns, bool re
                         clamped->init();
                     else
                         clamped->init(ns);
-                    clamped->run();
-
-                    double Z_xj = 1.0;
-                    if( j_val == 0 && k_val == 0 ) {
-                        logZ0 = clamped->logZ();
-                    } else {
-                        // subtract logZ0 to avoid very large numbers
-                        Z_xj = exp(clamped->logZ() - logZ0);
+
+                    Real logZ;
+                    try {
+                        clamped->run();
+                        logZ = clamped->logZ();
+                    } catch( Exception &e ) {
+                        if( e.code() == Exception::NOT_NORMALIZABLE )
+                            logZ = -INFINITY;
+                        else
+                            throw;
                     }
 
+                    if( logZ0 == -INFINITY )
+                        if( logZ != -INFINITY )
+                            logZ0 = logZ;
+
+                    double Z_xj;
+                    if( logZ == -INFINITY )
+                        Z_xj = 0;
+                    else
+                        Z_xj = exp(logZ - logZ0); // subtract logZ0 to avoid very large numbers
+
                     // we assume that j.label() < k.label()
                     // i.e. we make an assumption here about the indexing
                     pairbelief[j_val + (k_val * nj->states())] = Z_xj;
@@ -208,7 +244,7 @@ vector<Factor> calcPairBeliefsNew( const InfAlg & obj, const VarSet& ns, bool re
                     clamped->restoreFactors( ns );
                 }
         
-            result.push_back( pairbelief );
+            result.push_back( pairbelief.normalized() );
         }
     }
     
index 12b74eb..738a4ad 100644 (file)
@@ -39,7 +39,8 @@ namespace dai {
         "Multiple undo levels unsupported",
         "FactorGraph is not connected",
         "Impossible typecast",
-        "Internal error"
+        "Internal error",
+        "Quantity not normalizable"
     }; 
 
 
index 8a367d8..f15db26 100644 (file)
@@ -32,9 +32,8 @@
     #include <boost/math/special_functions/log1p.hpp>  // for log1p
     #include <float.h>  // for _isnan
 #else
-    // Assume POSIX compliant system. We need the following for querying the CPU time for this process
-    #include <sys/times.h>
-    #include <sys/param.h>
+    // Assume POSIX compliant system. We need the following for querying the system time
+    #include <sys/time.h>
 #endif
 
 
@@ -63,13 +62,14 @@ namespace dai {
 // Returns user+system time in seconds
 double toc() {
 #ifdef WINDOWS
-    SYSTEMTIME  tbuf;
+    SYSTEMTIME tbuf;
     GetSystemTime(&tbuf);
     return( (double)(tbuf.wSecond + (double)tbuf.wMilliseconds / 1000.0) );
 #else
-    tms tbuf;
-    times(&tbuf);
-    return( (double)(tbuf.tms_utime + tbuf.tms_stime) / HZ );
+    struct timeval tv;
+    struct timezone tz;
+    gettimeofday( &tv, &tz );
+    return( (double)(tv.tv_sec + (double)tv.tv_usec / 1000000.0) );
 #endif
 }