-* [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
-# 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
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)
-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
+++ /dev/null
-# 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)
+++ /dev/null
-# 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
- 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
- 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)
* - 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
/// 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];
};
#include <numeric>
#include <functional>
#include <dai/util.h>
+#include <dai/exceptions.h>
namespace dai {
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;
}
/// Returns log(1+x)
double log1p( double x );
+
+ /// Define INFINITY
+ #define INFINITY (std::numeric_limits<double>::infinity())
#endif
#endif
-/// Returns the time in seconds
+/// Returns wall clock time in seconds
double toc();
/// 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);
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 );
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 );
/// 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();
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++ ) {
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]);
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
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;
clamped->restoreFactors( ns );
}
- result.push_back( pairbelief );
+ result.push_back( pairbelief.normalized() );
}
}
"Multiple undo levels unsupported",
"FactorGraph is not connected",
"Impossible typecast",
- "Internal error"
+ "Internal error",
+ "Quantity not normalizable"
};
#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
// 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
}