Added ExactInf class for doing brute force exact inference...
authorJoris Mooij <jorism@osun.tuebingen.mpg.de>
Tue, 23 Sep 2008 10:41:06 +0000 (12:41 +0200)
committerJoris Mooij <jorism@osun.tuebingen.mpg.de>
Tue, 23 Sep 2008 10:41:06 +0000 (12:41 +0200)
... and:
- Cleaned up and synched Makefiles
- Improved example
- Added --marginals option to tests/test

13 files changed:
Makefile
Makefile.win
STATUS
example.cpp
include/dai/alldai.h
include/dai/exactinf.h [new file with mode: 0644]
src/alldai.cpp
src/exactinf.cpp [new file with mode: 0644]
tests/aliases.conf
tests/test.cpp
tests/testall
tests/testall.bat
tests/testfast.out

index bde5a6f..64a6ab9 100644 (file)
--- a/Makefile
+++ b/Makefile
 
 
 # Enable/disable various approximate inference methods
-WITH_BP = true
-WITH_MF = true
-WITH_HAK = true
-WITH_LC = true
-WITH_TREEEP = true
-WITH_JTREE = true
-WITH_MR = true
+WITH_BP=true
+WITH_MF=true
+WITH_HAK=true
+WITH_LC=true
+WITH_TREEEP=true
+WITH_JTREE=true
+WITH_MR=true
 # Build with debug info?
-DEBUG = true
+DEBUG=true
 # Build matlab interface?
-WITH_MATLAB =
+WITH_MATLAB=
 # New/old matlab version?
-NEW_MATLAB = true
+NEW_MATLAB=true
 # Windows or linux (default)?
-WINDOWS =
+WINDOWS=
 
 # Directories
-INC = include/dai
-SRC = src
-LIB = lib
+INC=include/dai
+SRC=src
+LIB=lib
+
+# Extensions (library, object, executable extensions)
+LE=.a
+OE=.o
+EE=
+
+# Libraries
+LIBS=-ldai
 
 # We use the BOOST Program Options library
-BOOSTFLAGS = -lboost_program_options
+BOOSTLIBS=-lboost_program_options
 
 # Compile using GNU C++ Compiler
-CC = g++
+CC=g++
 
 # Flags for the C++ compiler
-CCFLAGS = -Wall -W -Wextra -fpic -I./include -Llib -O3 #-pg #-static #-DVERBOSE
+CCFLAGS=-Wall -W -Wextra -fpic -I./include -Llib -O3 #-pg #-static #-DVERBOSE
 ifdef DEBUG
-CCFLAGS := $(CCFLAGS) -g -DDAI_DEBUG
-else
-CCFLAGS := $(CCFLAGS)
+CCFLAGS:=$(CCFLAGS) -g -DDAI_DEBUG
 endif
 
+ifdef WINDOWS
+CCFLAGS=$(CCFLAGS) -DWINDOWS
+endif
+
+OBJECTS:=exactinf$(OE)
 ifdef WITH_BP
-CCFLAGS := $(CCFLAGS) -DWITH_BP
-OBJECTS := $(OBJECTS) bp.o
+CCFLAGS:=$(CCFLAGS) -DWITH_BP
+OBJECTS:=$(OBJECTS) bp$(OE)
 endif
 ifdef WITH_MF
-CCFLAGS := $(CCFLAGS) -DWITH_MF
-OBJECTS := $(OBJECTS) mf.o
+CCFLAGS:=$(CCFLAGS) -DWITH_MF
+OBJECTS:=$(OBJECTS) mf$(OE)
 endif
 ifdef WITH_HAK
-CCFLAGS := $(CCFLAGS) -DWITH_HAK
-OBJECTS := $(OBJECTS) hak.o
+CCFLAGS:=$(CCFLAGS) -DWITH_HAK
+OBJECTS:=$(OBJECTS) hak$(OE)
 endif
 ifdef WITH_LC
-CCFLAGS := $(CCFLAGS) -DWITH_LC
-OBJECTS := $(OBJECTS) lc.o
+CCFLAGS:=$(CCFLAGS) -DWITH_LC
+OBJECTS:=$(OBJECTS) lc$(OE)
 endif
 ifdef WITH_TREEEP
-CCFLAGS := $(CCFLAGS) -DWITH_TREEEP
-OBJECTS := $(OBJECTS) treeep.o
+CCFLAGS:=$(CCFLAGS) -DWITH_TREEEP
+OBJECTS:=$(OBJECTS) treeep$(OE)
 endif
 ifdef WITH_JTREE
-CCFLAGS := $(CCFLAGS) -DWITH_JTREE
-OBJECTS := $(OBJECTS) jtree.o
+CCFLAGS:=$(CCFLAGS) -DWITH_JTREE
+OBJECTS:=$(OBJECTS) jtree$(OE)
 endif
 ifdef WITH_MR
-CCFLAGS := $(CCFLAGS) -DWITH_MR
-OBJECTS := $(OBJECTS) mr.o
+CCFLAGS:=$(CCFLAGS) -DWITH_MR
+OBJECTS:=$(OBJECTS) mr$(OE)
 endif
 
 ifdef WITH_MATLAB
 # Replace the following by the directory where Matlab has been installed
-MATLABDIR = /opt/matlab/bin
+MATLABDIR=/opt/matlab/bin
 # Replace the following with the extension of compiled MEX files on this platform, e.g. .mexglx for x86
-MEXEXT = .mexglx
-MEX = $(MATLABDIR)/mex
-MEXFLAGS = -I.
+ME=.mexglx
+MEX=$(MATLABDIR)/mex
+MEXFLAGS=-I.
 ifdef DEBUG
-MEXFLAGS := $(MEXFLAGS) -g -DDAI_DEBUG
+MEXFLAGS:=$(MEXFLAGS) -g -DDAI_DEBUG
 endif
 ifdef NEW_MATLAB
-MEXFLAGS := $(MEXFLAGS) -largeArrayDims
+MEXFLAGS:=$(MEXFLAGS) -largeArrayDims
 else
-MEXFLAGS := $(MEXFLAGS) -DSMALLMEM
+MEXFLAGS:=$(MEXFLAGS) -DSMALLMEM
 endif
 endif
 
-HEADERS = $(INC)/bipgraph.h $(INC)/diffs.h $(INC)/index.h $(INC)/var.h $(INC)/factor.h $(INC)/varset.h $(INC)/prob.h $(INC)/daialg.h $(INC)/properties.h $(INC)/alldai.h $(INC)/enum.h $(INC)/x2x.h $(INC)/exceptions.h
+HEADERS=$(INC)/bipgraph.h $(INC)/diffs.h $(INC)/index.h $(INC)/var.h $(INC)/factor.h $(INC)/varset.h $(INC)/prob.h $(INC)/daialg.h $(INC)/properties.h $(INC)/alldai.h $(INC)/enum.h $(INC)/x2x.h $(INC)/exceptions.h
 
-TARGETS = tests utils $(LIB)/libdai.a example testregression doc
+TARGETS=tests utils $(LIB)/libdai$(LE) example$(EE) testregression doc
 ifdef WITH_MATLAB
-TARGETS := $(TARGETS) matlabs
+TARGETS:=$(TARGETS) matlabs
 endif
 all : $(TARGETS)
        echo -e "\a"
 
-matlabs : matlab/dai.$(MEXEXT) matlab/dai_readfg.$(MEXEXT) matlab/dai_writefg.$(MEXEXT) matlab/dai_potstrength.$(MEXEXT)
+matlabs : matlab/dai.$(ME) matlab/dai_readfg.$(ME) matlab/dai_writefg.$(ME) matlab/dai_potstrength.$(ME)
 
-$(LIB)/libdai.a : bipgraph.o daialg.o alldai.o clustergraph.o factorgraph.o properties.o regiongraph.o util.o weightedgraph.o x2x.o exceptions.o $(OBJECTS)
-       ar rcs $(LIB)/libdai.a bipgraph.o daialg.o alldai.o clustergraph.o factorgraph.o properties.o regiongraph.o util.o weightedgraph.o x2x.o exceptions.o $(OBJECTS)
+$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) x2x$(OE) exceptions$(OE) $(OBJECTS)
+       ar rcus $(LIB)/libdai$(LE) bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) x2x$(OE) exceptions$(OE) $(OBJECTS)
 
-tests : tests/test
+tests : tests/test$(EE)
 
-utils : utils/createfg utils/fg2dot utils/fginfo
+utils : utils/createfg$(EE) utils/fg2dot$(EE) utils/fginfo$(EE)
 
 testregression : tests/test
        echo Testing...this can take a while...
@@ -126,103 +137,107 @@ doc : $(INC)/*.h $(SRC)/*.cpp doxygen.conf
        doxygen doxygen.conf
 
 clean :
-       rm *.o example matlab/*.$(MEXEXT) matlab/*.o tests/test utils/fg2dot utils/createfg utils/fginfo $(LIB)/libdai.a; echo
+       rm *$(OE) example$(EE) matlab/*.$(ME) matlab/*$(OE) tests/test$(EE) utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE) $(LIB)/libdai$(LE); echo
        rm -R doc; echo
 
-bipgraph.o : $(SRC)/bipgraph.cpp $(HEADERS)
+bipgraph$(OE) : $(SRC)/bipgraph.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/bipgraph.cpp
 
-daialg.o : $(SRC)/daialg.cpp $(HEADERS)
+daialg$(OE) : $(SRC)/daialg.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/daialg.cpp
 
-bp.o : $(SRC)/bp.cpp $(INC)/bp.h $(HEADERS)
+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.o : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)
+lc$(OE) : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/lc.cpp
 
-mf.o : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
+mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/mf.cpp
 
-factorgraph.o : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
+factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/factorgraph.cpp
 
-util.o : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)
+util$(OE) : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/util.cpp
 
-regiongraph.o : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)
+regiongraph$(OE) : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/regiongraph.cpp
 
-hak.o : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h
+hak$(OE) : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h
        $(CC) $(CCFLAGS) -c $(SRC)/hak.cpp
 
-clustergraph.o : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)
+clustergraph$(OE) : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/clustergraph.cpp
 
-jtree.o : $(SRC)/jtree.cpp $(INC)/jtree.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h
+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.o : $(SRC)/treeep.cpp $(INC)/treeep.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h $(INC)/jtree.h
+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.o : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)
+weightedgraph$(OE) : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/weightedgraph.cpp
 
-mr.o : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)
+mr$(OE) : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/mr.cpp
 
-properties.o : $(SRC)/properties.cpp $(HEADERS)
+properties$(OE) : $(SRC)/properties.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/properties.cpp
 
-exceptions.o: $(SRC)/exceptions.cpp $(HEADERS)
+exceptions$(OE) : $(SRC)/exceptions.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/exceptions.cpp
 
-alldai.o : $(SRC)/alldai.cpp $(HEADERS)
+alldai$(OE) : $(SRC)/alldai.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/alldai.cpp
 
-x2x.o : $(SRC)/x2x.cpp $(HEADERS)
+x2x$(OE) : $(SRC)/x2x.cpp $(HEADERS)
        $(CC) $(CCFLAGS) -c $(SRC)/x2x.cpp
 
+
 # EXAMPLE
 ##########
 
-example : example.cpp $(HEADERS) $(LIB)/libdai.a
-       $(CC) $(CCFLAGS) -o example example.cpp -ldai
+example$(EE) : example.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCFLAGS) -o example$(EE) example.cpp $(LIBS)
 
 # TESTS
 ########
 
-tests/test : tests/test.cpp $(HEADERS) $(LIB)/libdai.a
-       $(CC) $(CCFLAGS) -o tests/test tests/test.cpp -ldai $(BOOSTFLAGS)
+tests/test$(EE) : tests/test.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCFLAGS) -o tests/test$(EE) tests/test.cpp $(LIBS) $(BOOSTLIBS)
 
 
 # MATLAB INTERFACE
 ###################
 
-matlab/dai.$(MEXEXT) : matlab/dai.cpp $(HEADERS) matlab/matlab.o $(LIB)/libdai.a
-       $(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab.o $(LIB)/libdai.a
+matlab/dai.$(ME) : matlab/dai.cpp $(HEADERS) matlab/matlab$(OE) $(LIB)/libdai$(LE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab$(OE) $(LIB)/libdai$(LE)
 
-matlab/dai_readfg.$(MEXEXT) : matlab/dai_readfg.cpp $(HEADERS) factorgraph.o matlab/matlab.o
-       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph.o matlab/matlab.o
+matlab/dai_readfg.$(ME) : matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
 
-matlab/dai_writefg.$(MEXEXT) : matlab/dai_writefg.cpp $(HEADERS) factorgraph.o matlab/matlab.o
-       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph.o matlab/matlab.o
+matlab/dai_writefg.$(ME) : matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
 
-matlab/dai_potstrength.$(MEXEXT) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab.o
-       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab.o
+matlab/dai_potstrength.$(ME) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab$(OE) exceptions$(OE)
 
-matlab/matlab.o : matlab/matlab.cpp matlab/matlab.h $(HEADERS)
+matlab/matlab$(OE) : matlab/matlab.cpp matlab/matlab.h $(HEADERS)
        $(MEX) $(MEXFLAGS) -outdir matlab -c matlab/matlab.cpp
 
 
 # UTILS
 ########
 
-utils/createfg : utils/createfg.cpp $(HEADERS) factorgraph.o weightedgraph.o util.o bipgraph.o exceptions.o
-       $(CC) $(CCFLAGS) -o utils/createfg utils/createfg.cpp factorgraph.o weightedgraph.o util.o bipgraph.o exceptions.o $(BOOSTFLAGS)
+utils/createfg$(EE) : utils/createfg.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCFLAGS) -o utils/createfg utils/createfg.cpp $(LIBS) $(BOOSTLIBS)
 
-utils/fg2dot : utils/fg2dot.cpp $(HEADERS) factorgraph.o exceptions.o
-       $(CC) $(CCFLAGS) -o utils/fg2dot utils/fg2dot.cpp factorgraph.o exceptions.o
+utils/fg2dot$(EE) : utils/fg2dot.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCFLAGS) -o utils/fg2dot utils/fg2dot.cpp $(LIBS)
 
-utils/fginfo : utils/fginfo.cpp $(HEADERS) factorgraph.o bipgraph.o exceptions.o
-       $(CC) $(CCFLAGS) -o utils/fginfo utils/fginfo.cpp factorgraph.o bipgraph.o exceptions.o
+utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)
+       $(CC) $(CCFLAGS) -o utils/fginfo utils/fginfo.cpp $(LIBS)
index 8edf18d..948b4e3 100755 (executable)
@@ -40,92 +40,95 @@ INC=include/dai
 SRC=src\r
 LIB=lib\r
 \r
-# For some reason, we have to set the library path, although it is in the environment\r
-LIBS=/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
+# Extensions (library, object, executable extensions)\r
+LE=.lib\r
+OE=.obj\r
+EE=.exe\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 GNU C++ Compiler\r
 CC=cl\r
-OBJEXT=obj\r
-LIBEXT=lib\r
 \r
 # Flags for the C++ compiler\r
 CCFLAGS=/I./include /IC:\boost_1_36_0 /EHsc /Ox\r
 !IFDEF DEBUG\r
 CCFLAGS=$(CCFLAGS) /Zi /DDAI_DEBUG\r
-!ELSE\r
-CCFLAGS=$(CCFLAGS)\r
 !ENDIF\r
 \r
 !IFDEF WINDOWS\r
 CCFLAGS=$(CCFLAGS) /DWINDOWS\r
 !ENDIF\r
 \r
+OBJECTS=exactinf$(OE)\r
 !IFDEF WITH_BP\r
 CCFLAGS=$(CCFLAGS) /DWITH_BP\r
-OBJECTS=$(OBJECTS) bp.obj\r
+OBJECTS=$(OBJECTS) bp$(OE)\r
 !ENDIF\r
 !IFDEF WITH_MF\r
 CCFLAGS=$(CCFLAGS) /DWITH_MF\r
-OBJECTS=$(OBJECTS) mf.obj\r
+OBJECTS=$(OBJECTS) mf$(OE)\r
 !ENDIF\r
 !IFDEF WITH_HAK\r
 CCFLAGS=$(CCFLAGS) /DWITH_HAK\r
-OBJECTS=$(OBJECTS) hak.obj\r
+OBJECTS=$(OBJECTS) hak$(OE)\r
 !ENDIF\r
 !IFDEF WITH_LC\r
 CCFLAGS=$(CCFLAGS) /DWITH_LC\r
-OBJECTS=$(OBJECTS) lc.obj\r
+OBJECTS=$(OBJECTS) lc$(OE)\r
 !ENDIF\r
 !IFDEF WITH_TREEEP\r
 CCFLAGS=$(CCFLAGS) /DWITH_TREEEP\r
-OBJECTS=$(OBJECTS) treeep.obj\r
+OBJECTS=$(OBJECTS) treeep$(OE)\r
 !ENDIF\r
 !IFDEF WITH_JTREE\r
 CCFLAGS=$(CCFLAGS) /DWITH_JTREE\r
-OBJECTS=$(OBJECTS) jtree.obj\r
+OBJECTS=$(OBJECTS) jtree$(OE)\r
 !ENDIF\r
 !IFDEF WITH_MR\r
 CCFLAGS=$(CCFLAGS) /DWITH_MR\r
-OBJECTS=$(OBJECTS) mr.obj\r
+OBJECTS=$(OBJECTS) mr$(OE)\r
 !ENDIF\r
 \r
 !IFDEF WITH_MATLAB\r
 # Replace the following by the directory where Matlab has been installed\r
-MATLABDIR = /opt/matlab/bin\r
+MATLABDIR=/opt/matlab/bin\r
 # Replace the following with the extension of compiled MEX files on this platform, e.g. .mexglx for x86\r
-MEXEXT = .mexglx\r
-MEX = $(MATLABDIR)/mex\r
-MEXFLAGS = -I.\r
+ME=.mexglx\r
+MEX=$(MATLABDIR)/mex\r
+MEXFLAGS=-I.\r
 !IFDEF DEBUG\r
-MEXFLAGS = $(MEXFLAGS) -g /DDAI_DEBUG\r
+MEXFLAGS=$(MEXFLAGS) -g /DDAI_DEBUG\r
 !ENDIF\r
 !IFDEF NEW_MATLAB\r
-MEXFLAGS = $(MEXFLAGS) -largeArrayDims\r
+MEXFLAGS=$(MEXFLAGS) -largeArrayDims\r
 !ELSE\r
-MEXFLAGS = $(MEXFLAGS) /DSMALLMEM\r
+MEXFLAGS=$(MEXFLAGS) /DSMALLMEM\r
 !ENDIF\r
 !ENDIF\r
 \r
-HEADERS = $(INC)/bipgraph.h $(INC)/diffs.h $(INC)/index.h $(INC)/var.h $(INC)/factor.h $(INC)/varset.h $(INC)/prob.h $(INC)/daialg.h $(INC)/properties.h $(INC)/alldai.h $(INC)/enum.h $(INC)/x2x.h $(INC)/exceptions.h\r
+HEADERS=$(INC)/bipgraph.h $(INC)/diffs.h $(INC)/index.h $(INC)/var.h $(INC)/factor.h $(INC)/varset.h $(INC)/prob.h $(INC)/daialg.h $(INC)/properties.h $(INC)/alldai.h $(INC)/enum.h $(INC)/x2x.h $(INC)/exceptions.h\r
 \r
-TARGETS = tests utils $(LIB)/libdai.lib example.exe\r
-# testregression disabled, it uses sh and awk\r
+TARGETS=tests utils $(LIB)/libdai$(LE) example$(EE)\r
+# testregression disabled, it uses diff\r
 # doc disabled, it uses doxygen\r
 !IFDEF WITH_MATLAB\r
 TARGETS = $(TARGETS) matlabs\r
 !ENDIF\r
 all : $(TARGETS)\r
 \r
-matlabs : matlab/dai.$(MEXEXT) matlab/dai_readfg.$(MEXEXT) matlab/dai_writefg.$(MEXEXT) matlab/dai_removeshortloops.$(MEXEXT) matlab/dai_potstrength.$(MEXEXT)\r
+matlabs : matlab/dai.$(ME) matlab/dai_readfg.$(ME) matlab/dai_writefg.$(ME) matlab/dai_potstrength.$(ME)\r
 \r
-$(LIB)/libdai.lib : bipgraph.obj daialg.obj alldai.obj clustergraph.obj factorgraph.obj properties.obj regiongraph.obj util.obj weightedgraph.obj x2x.obj exceptions.obj $(OBJECTS)\r
-       lib /out:$(LIB)/libdai.lib bipgraph.obj daialg.obj alldai.obj clustergraph.obj factorgraph.obj properties.obj regiongraph.obj util.obj weightedgraph.obj x2x.obj exceptions.obj $(OBJECTS)\r
+$(LIB)/libdai$(LE) : bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) x2x$(OE) exceptions$(OE) $(OBJECTS)\r
+       lib /out:$(LIB)/libdai$(LE) bipgraph$(OE) daialg$(OE) alldai$(OE) clustergraph$(OE) factorgraph$(OE) properties$(OE) regiongraph$(OE) util$(OE) weightedgraph$(OE) x2x$(OE) exceptions$(OE) $(OBJECTS)\r
 \r
-tests : tests/test.exe\r
+tests : tests/test$(EE)\r
 \r
-utils : utils/createfg.exe utils/fg2dot.exe utils/remove_short_loops.exe utils/fginfo.exe\r
+utils : utils/createfg$(EE) utils/fg2dot$(EE) utils/fginfo$(EE)\r
 \r
 testregression : tests/test\r
        echo Testing...this can take a while...\r
@@ -135,111 +138,108 @@ doc : $(INC)/*.h $(SRC)/*.cpp doxygen.conf
        doxygen doxygen.conf\r
 \r
 clean :\r
-       del *.obj *.ilk *.pdb *.exe matlab\*.$(MEXEXT) matlab\*.obj tests\test.exe tests\*.pdb tests\*.ilk utils\*.exe utils\*.pdb utils\*.ilk $(LIB)\libdai.lib\r
+       del *$(OE) *.ilk *.pdb *$(EE) matlab\*.$(ME) matlab\*$(OE) tests\test$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE)\r
 \r
 \r
-bipgraph.obj : $(SRC)/bipgraph.cpp $(HEADERS)\r
+bipgraph$(OE) : $(SRC)/bipgraph.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/bipgraph.cpp\r
 \r
-daialg.obj : $(SRC)/daialg.cpp $(HEADERS)\r
+daialg$(OE) : $(SRC)/daialg.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/daialg.cpp\r
 \r
-bp.obj : $(SRC)/bp.cpp $(INC)/bp.h $(HEADERS)\r
+exactinf$(OE) : $(SRC)/exactinf.cpp $(INC)/exactinf.h $(HEADERS)\r
+       $(CC) $(CCFLAGS) -c $(SRC)/exactinf.cpp\r
+\r
+bp$(OE) : $(SRC)/bp.cpp $(INC)/bp.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/bp.cpp\r
 \r
-lc.obj : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)\r
+lc$(OE) : $(SRC)/lc.cpp $(INC)/lc.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/lc.cpp\r
 \r
-mf.obj : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)\r
+mf$(OE) : $(SRC)/mf.cpp $(INC)/mf.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/mf.cpp\r
 \r
-factorgraph.obj : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)\r
+factorgraph$(OE) : $(SRC)/factorgraph.cpp $(INC)/factorgraph.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/factorgraph.cpp\r
 \r
-util.obj : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)\r
+util$(OE) : $(SRC)/util.cpp $(INC)/util.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/util.cpp\r
 \r
-regiongraph.obj : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)\r
+regiongraph$(OE) : $(SRC)/regiongraph.cpp $(INC)/regiongraph.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/regiongraph.cpp\r
 \r
-hak.obj : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h\r
+hak$(OE) : $(SRC)/hak.cpp $(INC)/hak.h $(HEADERS) $(INC)/regiongraph.h\r
        $(CC) $(CCFLAGS) -c $(SRC)/hak.cpp\r
 \r
-clustergraph.obj : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)\r
+clustergraph$(OE) : $(SRC)/clustergraph.cpp $(INC)/clustergraph.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/clustergraph.cpp\r
 \r
-jtree.obj : $(SRC)/jtree.cpp $(INC)/jtree.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h\r
+jtree$(OE) : $(SRC)/jtree.cpp $(INC)/jtree.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h\r
        $(CC) $(CCFLAGS) -c $(SRC)/jtree.cpp\r
 \r
-treeep.obj : $(SRC)/treeep.cpp $(INC)/treeep.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h $(INC)/jtree.h\r
+treeep$(OE) : $(SRC)/treeep.cpp $(INC)/treeep.h $(HEADERS) $(INC)/weightedgraph.h $(INC)/clustergraph.h $(INC)/regiongraph.h $(INC)/jtree.h\r
        $(CC) $(CCFLAGS) -c $(SRC)/treeep.cpp\r
 \r
-weightedgraph.obj : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)\r
+weightedgraph$(OE) : $(SRC)/weightedgraph.cpp $(INC)/weightedgraph.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/weightedgraph.cpp\r
 \r
-mr.obj : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)\r
+mr$(OE) : $(SRC)/mr.cpp $(INC)/mr.h $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/mr.cpp\r
 \r
-properties.obj : $(SRC)/properties.cpp $(HEADERS)\r
+properties$(OE) : $(SRC)/properties.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/properties.cpp\r
 \r
-exceptions.obj : $(SRC)/exceptions.cpp $(HEADERS)\r
+exceptions$(OE) : $(SRC)/exceptions.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/exceptions.cpp\r
 \r
-alldai.obj : $(SRC)/alldai.cpp $(HEADERS)\r
+alldai$(OE) : $(SRC)/alldai.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/alldai.cpp\r
 \r
-x2x.obj : $(SRC)/x2x.cpp $(HEADERS)\r
+x2x$(OE) : $(SRC)/x2x.cpp $(HEADERS)\r
        $(CC) $(CCFLAGS) -c $(SRC)/x2x.cpp\r
 \r
 \r
 # EXAMPLE\r
 ##########\r
 \r
-example.exe : example.cpp $(HEADERS) $(LIB)/libdai.lib\r
-       $(CC) $(CCFLAGS) /Feexample example.cpp /link $(LIB)/libdai.lib $(LIBS)\r
+example$(EE) : example.cpp $(HEADERS) $(LIB)/libdai$(LE)\r
+       $(CC) $(CCFLAGS) /Feexample example.cpp $(LIBS)\r
 \r
 \r
 # TESTS\r
 ########\r
 \r
-tests/test.exe : tests/test.cpp $(HEADERS) $(LIB)/libdai.lib\r
-       $(CC) $(CCFLAGS) /Fetests/test tests/test.cpp /link $(LIB)/libdai.lib $(LIBS) $(BOOSTLIBS)\r
+tests/test$(EE) : tests/test.cpp $(HEADERS) $(LIB)/libdai$(LE)\r
+       $(CC) $(CCFLAGS) /Fetests/test tests/test.cpp $(LIBS) $(BOOSTLIBS)\r
 \r
 \r
 # MATLAB INTERFACE\r
 ###################\r
 \r
-matlab/dai.$(MEXEXT) : matlab/dai.cpp $(HEADERS) matlab/matlab.obj $(LIB)/libdai.lib\r
-       $(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab.obj $(LIB)/libdai.lib\r
-\r
-matlab/dai_readfg.$(MEXEXT) : matlab/dai_readfg.cpp $(HEADERS) factorgraph.obj matlab/matlab.obj\r
-       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph.obj matlab/matlab.obj\r
+matlab/dai.$(ME) : matlab/dai.cpp $(HEADERS) matlab/matlab$(OE) $(LIB)/libdai$(LE)\r
+       $(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab$(OE) $(LIB)/libdai$(LE)\r
 \r
-matlab/dai_writefg.$(MEXEXT) : matlab/dai_writefg.cpp $(HEADERS) factorgraph.obj matlab/matlab.obj\r
-       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph.obj matlab/matlab.obj\r
+matlab/dai_readfg.$(ME) : matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)\r
+       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)\r
 \r
-matlab/dai_removeshortloops.$(MEXEXT) : matlab/dai_removeshortloops.cpp $(HEADERS) factorgraph.obj matlab/matlab.obj\r
-       $(MEX) $(MEXFLAGS) -o matlab/dai_removeshortloops matlab/dai_removeshortloops.cpp factorgraph.obj matlab/matlab.obj\r
+matlab/dai_writefg.$(ME) : matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)\r
+       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)\r
 \r
-matlab/dai_potstrength.$(MEXEXT) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab.obj\r
-       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab.obj\r
+matlab/dai_potstrength.$(ME) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab$(OE) exceptions$(OE)\r
+       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab$(OE) exceptions$(OE)\r
 \r
-matlab/matlab.obj : matlab/matlab.cpp matlab/matlab.h $(HEADERS)\r
+matlab/matlab$(OE) : matlab/matlab.cpp matlab/matlab.h $(HEADERS)\r
        $(MEX) $(MEXFLAGS) -outdir matlab -c matlab/matlab.cpp\r
 \r
 \r
 # UTILS\r
 ########\r
 \r
-utils/createfg.exe : utils/createfg.cpp $(HEADERS) factorgraph.obj weightedgraph.obj util.obj bipgraph.obj exceptions.obj\r
-       $(CC) $(CCFLAGS) /Feutils/createfg utils/createfg.cpp factorgraph.obj weightedgraph.obj util.obj bipgraph.obj exceptions.obj /link $(LIBS) $(BOOSTLIBS)\r
-\r
-utils/fg2dot.exe : utils/fg2dot.cpp $(HEADERS) factorgraph.obj exceptions.obj\r
-       $(CC) $(CCFLAGS) /Feutils/fg2dot utils/fg2dot.cpp factorgraph.obj exceptions.obj /link $(LIBS)\r
+utils/createfg$(EE) : utils/createfg.cpp $(HEADERS) $(LIB)/libdai$(LE)\r
+       $(CC) $(CCFLAGS) /Feutils/createfg utils/createfg.cpp $(LIBS) $(BOOSTLIBS)\r
 \r
-utils/remove_short_loops.exe : utils/remove_short_loops.cpp $(HEADERS) factorgraph.obj exceptions.obj\r
-       $(CC) $(CCFLAGS) /Feutils/remove_short_loops utils/remove_short_loops.cpp factorgraph.obj exceptions.obj /link $(LIBS)\r
+utils/fg2dot$(EE) : utils/fg2dot.cpp $(HEADERS) $(LIB)/libdai$(LE)\r
+       $(CC) $(CCFLAGS) /Feutils/fg2dot utils/fg2dot.cpp $(LIBS)\r
 \r
-utils/fginfo.exe : utils/fginfo.cpp $(HEADERS) factorgraph.obj bipgraph.obj exceptions.obj\r
-       $(CC) $(CCFLAGS) /Feutils/fginfo utils/fginfo.cpp factorgraph.obj bipgraph.obj exceptions.obj /link $(LIBS)\r
+utils/fginfo$(EE) : utils/fginfo.cpp $(HEADERS) $(LIB)/libdai$(LE)\r
+       $(CC) $(CCFLAGS) /Feutils/fginfo utils/fginfo.cpp $(LIBS)\r
diff --git a/STATUS b/STATUS
index be9e25f..96a993c 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -19,14 +19,16 @@ A disadvantage of this approach may be worse cachability.
 - Can the FactorGraph constructors be optimized further?
 - Solve the proliferation of type checks for all different ENUM's in
 properties.cpp
+- Remove x2x?
 
 TODO FOR RELEASE:
 - Test Visual C++ compatibility
 - Figure out which libraries are required and document in README
   boost headers, boost::program_options library, boost::graph library,
   boost::math library (under Windows)
+- Change email address
 
-FILES IN SVN HEAD THAT ARE NO LONGER RELEVANT FOR GIT MASTER
+FILES IN SVN HEAD THAT ARE NO LONGER RELEVANT FOR GIT MASTER:
 diffs.h
 index.h
 util.h
@@ -41,6 +43,51 @@ utils/createfg.cpp
 exceptions.h
 exceptions.cpp
 enum.h
+doxygen.conf
+example.cpp
+FILEFORMAT
+Makefile
+exact.h
+exact.cpp
+alldai.h
+alldai.cpp
+
+FILES IN SVN HEAD THAT ARE STILL RELEVANT:
+weightedgraph.cpp
+ChangeLog
+README
+TODO
+prob.h
+properties.h
+properties.cpp
+factor.h
+factor.cpp
+factorgraph.h
+factorgraph.cpp
+regiongraph.h
+regiongraph.cpp
+
+daialg.h
+daialg.cpp
+bp.h
+bp.cpp
+hak.h
+hak.cpp
+jtree.h
+jtree.cpp
+lc.h
+lc.cpp
+mf.h
+mf.cpp
+mr.h
+mr.cpp
+treeep.h
+treeep.cpp
+
+matlab/*
+tests/*
+utils/*
+
 
 DOCUMENTATION READY:
 - bipgraph.h, bipgraph.cpp
index cca85a8..9e72056 100644 (file)
@@ -40,7 +40,7 @@ int main( int argc, char *argv[] ) {
             cout << "Error reading " << argv[1] << endl;
             return 2;
         } else {
-            size_t  maxiter = 1000;
+            size_t  maxiter = 10000;
             double  tol = 1e-9;
             size_t  verb = 1;
 
@@ -53,17 +53,28 @@ int main( int argc, char *argv[] ) {
             jt.init();
             jt.run();
 
+            BP bp(fg, opts("updates",string("SEQFIX"))("logdomain",false));
+            bp.init();
+            bp.run();
+
             cout << "Exact single node marginals:" << endl;
             for( size_t i = 0; i < fg.nrVars(); i++ )
                 cout << jt.belief(fg.var(i)) << endl;
 
-            BP bp(fg, opts("updates",string("SEQMAX"))("logdomain",false));
-            bp.init();
-            bp.run();
-
             cout << "Approximate (loopy belief propagation) single node marginals:" << endl;
             for( size_t i = 0; i < fg.nrVars(); i++ )
                 cout << bp.belief(fg.var(i)) << endl;
+
+            cout << "Exact factor marginals:" << endl;
+            for( size_t I = 0; I < fg.nrFactors(); I++ )
+                cout << jt.belief(fg.factor(I).vars()) << endl;
+
+            cout << "Approximate (loopy belief propagation) factor marginals:" << endl;
+            for( size_t I = 0; I < fg.nrFactors(); I++ )
+                cout << bp.belief(fg.factor(I).vars()) << "=" << bp.beliefF(I) << endl;
+
+            cout << "Exact log partition sum: " << jt.logZ() << endl;
+            cout << "Approximate (loopy belief propagation) log partition sum: " << bp.logZ() << endl;
         }
     }
 
index 4d5e178..3f46faa 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include <dai/daialg.h>
 #include <dai/properties.h>
+#include <dai/exactinf.h>
 #ifdef WITH_BP
     #include <dai/bp.h>
 #endif
@@ -61,6 +62,7 @@ InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const Propert
 /// DAINames contains the names of all approximate inference algorithms
 
 static const char* DAINames[] = {
+    ExactInf::Name,
 #ifdef WITH_BP
     BP::Name, 
 #endif
diff --git a/include/dai/exactinf.h b/include/dai/exactinf.h
new file mode 100644 (file)
index 0000000..ca21ce4
--- /dev/null
@@ -0,0 +1,137 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [j dot mooij at science dot ru dot nl]
+    Radboud University Nijmegen, The Netherlands
+    
+    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
+*/
+
+
+#ifndef __defined_libdai_exactinf_h
+#define __defined_libdai_exactinf_h
+
+
+#include <dai/daialg.h>
+#include <dai/properties.h>
+#include <dai/factorgraph.h>
+#include <dai/enum.h>
+
+
+namespace dai {
+
+
+class ExactInf : public DAIAlgFG {
+    public:
+        struct Properties {
+            size_t verbose;
+        } props;
+
+    private:
+        std::vector<Factor> _beliefsV;
+        std::vector<Factor> _beliefsF;
+        Real                _logZ;
+
+    public:
+        /// Default constructor
+        ExactInf() : DAIAlgFG(), props(), _beliefsV(), _beliefsF(), _logZ(0) {}
+        
+        /// Copy constructor
+        ExactInf( const ExactInf &x ) : DAIAlgFG(x), props(x.props), _beliefsV(x._beliefsV), _beliefsF(x._beliefsF), _logZ(x._logZ) {}
+
+        /// Clone (virtual copy constructor)
+        virtual ExactInf* clone() const {
+            return new ExactInf(*this);
+        }
+
+        /// Construct from FactorGraph fg and PropertySet opts
+        ExactInf( const FactorGraph &fg, const PropertySet &opts ) : DAIAlgFG(fg), props(), _beliefsV(), _beliefsF(), _logZ() {
+            setProperties( opts );
+            create();
+        }
+        
+        /// Assignment operator
+        ExactInf& operator=( const ExactInf &x ) {
+            if( this != &x ) {
+                DAIAlgFG::operator=( x );
+                props     = x.props;
+                _beliefsV = x._beliefsV;
+                _beliefsF = x._beliefsF;
+                _logZ     = x._logZ;
+            }
+            return *this;
+        }
+
+/*        /// Create (virtual constructor)
+        virtual ExactInf* create() const {
+            return new ExactInf();
+        }
+*/
+        /// Return maximum difference between single node 
+        /// beliefs for two consecutive iterations
+        virtual double maxDiff() const {
+            DAI_THROW(NOT_IMPLEMENTED);
+            return 0.0;
+        }
+        
+        /// Identifies itself for logging purposes
+        virtual std::string identify() const;
+
+        /// Get single node belief
+        virtual Factor belief( const Var &n ) const {
+            return beliefV( findVar( n ) ); 
+        }
+
+        /// Get general belief
+        virtual Factor belief( const VarSet &n ) const;
+
+        /// Get all beliefs
+        virtual std::vector<Factor> beliefs() const;
+
+        /// Get log partition sum
+        virtual Real logZ() const {
+            return _logZ;
+        }
+
+        /// Clear messages and beliefs
+        virtual void init();
+
+        /// Clear messages and beliefs corresponding to the nodes in ns
+        virtual void init( const VarSet &/*ns*/ ) {}
+
+        /// The actual approximate inference algorithm
+        virtual double run();
+
+        /// Name of this inference method
+        static const char *Name;
+
+        void create();
+        void undoProbs( const VarSet &ns ) { FactorGraph::undoProbs(ns); init(ns); }
+        void setProperties( const PropertySet &opts );
+        PropertySet getProperties() const;
+
+        Factor beliefV( size_t i ) const { 
+            return _beliefsV[i]; 
+        }
+
+        Factor beliefF( size_t I ) const { 
+            return _beliefsF[I]; 
+        }
+};
+
+
+} // end of namespace dai
+
+
+#endif
index 05359ba..ebabd1f 100644 (file)
@@ -32,6 +32,8 @@ using namespace std;
 
 
 InfAlg *newInfAlg( const string &name, const FactorGraph &fg, const PropertySet &opts ) {
+    if( name == ExactInf::Name )
+        return new ExactInf (fg, opts);
 #ifdef WITH_BP
     if( name == BP::Name ) 
         return new BP (fg, opts);
diff --git a/src/exactinf.cpp b/src/exactinf.cpp
new file mode 100644 (file)
index 0000000..96ae3e8
--- /dev/null
@@ -0,0 +1,124 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [j dot mooij at science dot ru dot nl]
+    Radboud University Nijmegen, The Netherlands
+    
+    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
+*/
+
+
+#include <dai/exactinf.h>
+#include <sstream>
+
+
+namespace dai {
+
+
+using namespace std;
+
+
+const char *ExactInf::Name = "EXACT";
+
+
+void ExactInf::setProperties( const PropertySet &opts ) {
+    assert( opts.hasKey("verbose") );
+    
+    props.verbose = opts.getStringAs<size_t>("verbose");
+}
+
+
+PropertySet ExactInf::getProperties() const {
+    PropertySet opts;
+    opts.Set( "verbose", props.verbose );
+    return opts;
+}
+
+
+void ExactInf::create() {
+    // clear variable beliefs and reserve space
+    _beliefsV.clear();
+    _beliefsV.reserve( nrVars() );
+    for( size_t i = 0; i < nrVars(); i++ )
+        _beliefsV.push_back( Factor( var(i) ) );
+
+    // clear factor beliefs and reserve space
+    _beliefsF.clear();
+    _beliefsF.reserve( nrFactors() );
+    for( size_t I = 0; I < nrFactors(); I++ )
+        _beliefsF.push_back( Factor( factor(I).vars() ) );
+}
+
+
+void ExactInf::init() {
+    for( size_t i = 0; i < nrVars(); i++ )
+        _beliefsV[i].fill( 1.0 );
+    for( size_t I = 0; I < nrFactors(); I++ )
+        _beliefsF[I].fill( 1.0 );
+}
+
+
+double ExactInf::run() {
+    if( props.verbose >= 1 )
+        cout << "Starting " << identify() << "...";
+
+    Factor P;
+    for( size_t I = 0; I < nrFactors(); I++ )
+        P *= factor(I);
+
+    Real Z = P.totalSum();
+    _logZ = std::log(Z);
+    for( size_t i = 0; i < nrVars(); i++ )
+        _beliefsV[i] = P.marginal(var(i));
+    for( size_t I = 0; I < nrFactors(); I++ )
+        _beliefsF[I] = P.marginal(factor(I).vars());
+
+    if( props.verbose >= 1 )
+        cout << "finished" << endl;
+
+    return 0.0;
+}
+
+
+vector<Factor> ExactInf::beliefs() const {
+    vector<Factor> result = _beliefsV;
+    result.insert( result.end(), _beliefsF.begin(), _beliefsF.end() );
+    return result;
+}
+
+
+Factor ExactInf::belief( const VarSet &ns ) const {
+    if( ns.size() == 0 )
+        return Factor();
+    else if( ns.size() == 1 ) {
+        return belief( *(ns.begin()) );
+    } else {
+        size_t I;
+        for( I = 0; I < nrFactors(); I++ )
+            if( factor(I).vars() >> ns )
+                break;
+        assert( I != nrFactors() );
+        return beliefF(I).marginal(ns);
+    }
+}
+
+
+string ExactInf::identify() const { 
+    stringstream result (stringstream::out);
+    result << Name << getProperties();
+    return result.str();
+}
+
+
+} // end of namespace dai
index f749c2a..1078c40 100644 (file)
@@ -57,28 +57,3 @@ HAK_LOOP4:                      HAK[doubleloop=1,clusters=LOOP,loopdepth=4,tol=1
 HAK_LOOP5:                      HAK[doubleloop=1,clusters=LOOP,loopdepth=5,tol=1e-9,maxiter=10000,verbose=0]
 HAK_LOOP6:                      HAK[doubleloop=1,clusters=LOOP,loopdepth=6,tol=1e-9,maxiter=10000,verbose=0]
 HAK_LOOP8:                      HAK[doubleloop=1,clusters=LOOP,loopdepth=8,tol=1e-9,maxiter=10000,verbose=0]
-
-#---------------------------------------------------------------
-#EXACT
-#
-#
-#} else if( method.substr(0,5) == "EXACT" ) { // EXACT
-#    // Look if the network is small enough to do brute-force exact method
-#    bool toolarge = false;
-#    size_t total_statespace = 1;
-#    for( size_t i = 0; i < fg.nrVars(); i++ ) {
-#        total_statespace *= fg.var(i).states();
-#        if( total_statespace > (1UL << 16) )
-#            toolarge = true;
-#    }
-#
-#    if( !toolarge ) {
-#        Factor piet;
-#        for( size_t I = 0; I < fg.nrFactors(); I++ )
-#            piet *= fg.factor( I );
-#        for( size_t i = 0; i < fg.nrVars(); i++ )
-#            q.push_back(piet.marginal(fg.var(i)));
-#        time += toc() - tic;
-#        logZ = fg.ExactlogZ();
-#    } else
-#        throw "Network too large for EXACT method";
index d33880f..76ea915 100644 (file)
@@ -48,34 +48,12 @@ class TestAI {
         double          maxdiff;
         double          time;
         bool            has_logZ;
+        bool            has_maxdiff;
 
         TestAI( const FactorGraph &fg, const string &_name, const PropertySet &opts ) : obj(NULL), name(_name), err(), q(), logZ(0.0), maxdiff(0.0), time(0), has_logZ(true) {
             double tic = toc();
             obj = newInfAlg( name, fg, opts );
             time += toc() - tic;
-/*
-            } else if( method.substr(0,5) == "EXACT" ) { // EXACT
-                // Look if the network is small enough to do brute-force exact method
-                bool toolarge = false;
-                size_t total_statespace = 1;
-                for( size_t i = 0; i < fg.nrVars(); i++ ) {
-                    total_statespace *= fg.var(i).states();
-                    if( total_statespace > (1UL << 16) )
-                        toolarge = true;
-                }
-
-                if( !toolarge ) {
-                    Factor piet;
-                    for( size_t I = 0; I < fg.nrFactors(); I++ )
-                        piet *= fg.factor( I );
-                    for( size_t i = 0; i < fg.nrVars(); i++ )
-                        q.push_back(piet.marginal(fg.var(i)));
-                    time += toc() - tic;
-                    logZ = fg.ExactlogZ();
-                } else
-                    throw "Network too large for EXACT method";
-            }
-*/
         }
 
         ~TestAI() { 
@@ -99,9 +77,6 @@ class TestAI {
 
         void doAI() {
             double tic = toc();
-//            if( name == "EXACT" ) {
-//                // calculation has already been done
-//            } 
             if( obj != NULL ) {
                 obj->init();
                 obj->run();
@@ -112,7 +87,12 @@ class TestAI {
                 } catch( Exception &e ) {
                     has_logZ = false;
                 }
-                maxdiff = obj->maxDiff();
+                try {
+                    maxdiff = obj->maxDiff();
+                    has_maxdiff = true;
+                } catch( Exception &e ) {
+                    has_maxdiff = false;
+                }
                 q = allBeliefs();
             };
         }
@@ -185,6 +165,7 @@ int main( int argc, char *argv[] ) {
         double tol;
         size_t maxiter;
         size_t verbose;
+        bool marginals = false;
         bool report_time = true;
 
         po::options_description opts_required("Required options");
@@ -200,6 +181,7 @@ int main( int argc, char *argv[] ) {
             ("tol", po::value< double >(&tol), "Override tolerance")
             ("maxiter", po::value< size_t >(&maxiter), "Override maximum number of iterations")
             ("verbose", po::value< size_t >(&verbose), "Override verbosity")
+            ("marginals", po::value< bool >(&marginals), "Output single node marginals?")
             ("report-time", po::value< bool >(&report_time), "Report calculation time")
         ;
 
@@ -314,14 +296,23 @@ int main( int argc, char *argv[] ) {
                         cout << "N/A         ";
                     }
                     cout.width( 10 );
-                    double md = clipdouble( piet.maxdiff, 1e-9 );
-                    if( isnan( me ) )
-                        md = me;
-                    if( isnan( ae ) )
-                        md = ae;
-                    cout << md << endl;
+                    if( piet.has_maxdiff ) {
+                        double md = clipdouble( piet.maxdiff, 1e-9 );
+                        if( isnan( me ) )
+                            md = me;
+                        if( isnan( ae ) )
+                            md = ae;
+                        cout << md << endl;
+                    } else {
+                        cout << "N/A       ";
+                    }
                 } else
                     cout << endl;
+
+                if( marginals ) {
+                    for( size_t i = 0; i < piet.q.size(); i++ )
+                        cout << "# " << piet.q[i] << endl;
+                }
             }
         }
     } catch(const char *e) {
index aecb684..9fae84a 100755 (executable)
@@ -1,2 +1,2 @@
 #!/bin/bash
-./test --report-time false --aliases aliases.conf --filename $1 --methods JTREE_HUGIN JTREE_SHSH BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG MF_SEQRND TREEEP TREEEPWC GBP_MIN GBP_DELTA GBP_LOOP3 GBP_LOOP4 HAK_MIN HAK_DELTA HAK_LOOP3 HAK_LOOP4 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP_FULLCAV_SEQFIX LCBP_FULLCAVin_SEQFIX LCBP_FULLCAV_SEQRND LCBP_FULLCAVin_SEQRND LCBP_FULLCAV_NONE LCBP_FULLCAVin_NONE LCBP_PAIRCAV_SEQFIX LCBP_PAIRCAVin_SEQFIX LCBP_PAIRCAV_SEQRND LCBP_PAIRCAVin_SEQRND LCBP_PAIRCAV_NONE LCBP_PAIRCAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND
+./test --report-time false --aliases aliases.conf --filename $1 --methods EXACT[verbose=0] JTREE_HUGIN JTREE_SHSH BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG MF_SEQRND TREEEP TREEEPWC GBP_MIN GBP_DELTA GBP_LOOP3 GBP_LOOP4 HAK_MIN HAK_DELTA HAK_LOOP3 HAK_LOOP4 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP_FULLCAV_SEQFIX LCBP_FULLCAVin_SEQFIX LCBP_FULLCAV_SEQRND LCBP_FULLCAVin_SEQRND LCBP_FULLCAV_NONE LCBP_FULLCAVin_NONE LCBP_PAIRCAV_SEQFIX LCBP_PAIRCAVin_SEQFIX LCBP_PAIRCAV_SEQRND LCBP_PAIRCAVin_SEQRND LCBP_PAIRCAV_NONE LCBP_PAIRCAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND
index dc568a9..70a9460 100755 (executable)
@@ -1 +1 @@
-test --report-time false --aliases aliases.conf --filename %1 --methods JTREE_HUGIN JTREE_SHSH BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG MF_SEQRND TREEEP TREEEPWC GBP_MIN GBP_DELTA GBP_LOOP3 GBP_LOOP4 HAK_MIN HAK_DELTA HAK_LOOP3 HAK_LOOP4 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP_FULLCAV_SEQFIX LCBP_FULLCAVin_SEQFIX LCBP_FULLCAV_SEQRND LCBP_FULLCAVin_SEQRND LCBP_FULLCAV_NONE LCBP_FULLCAVin_NONE LCBP_PAIRCAV_SEQFIX LCBP_PAIRCAVin_SEQFIX LCBP_PAIRCAV_SEQRND LCBP_PAIRCAVin_SEQRND LCBP_PAIRCAV_NONE LCBP_PAIRCAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND
+test --report-time false --aliases aliases.conf --filename %1 --methods EXACT[verbose=0] JTREE_HUGIN JTREE_SHSH BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG MF_SEQRND TREEEP TREEEPWC GBP_MIN GBP_DELTA GBP_LOOP3 GBP_LOOP4 HAK_MIN HAK_DELTA HAK_LOOP3 HAK_LOOP4 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP_FULLCAV_SEQFIX LCBP_FULLCAVin_SEQFIX LCBP_FULLCAV_SEQRND LCBP_FULLCAVin_SEQRND LCBP_FULLCAV_NONE LCBP_FULLCAVin_NONE LCBP_PAIRCAV_SEQFIX LCBP_PAIRCAVin_SEQFIX LCBP_PAIRCAV_SEQRND LCBP_PAIRCAVin_SEQRND LCBP_PAIRCAV_NONE LCBP_PAIRCAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND
index ff7e880..fa0b4e0 100644 (file)
@@ -1,6 +1,7 @@
 # testfast.fg
 # METHOD                                  MAX ERROR   AVG ERROR   LOGZ ERROR  MAXDIFF   
-JTREE_HUGIN                               
+EXACT[verbose=0]                          
+JTREE_HUGIN                               1.000e-09   1.000e-09   1.000e-09   1.000e-09 
 JTREE_SHSH                                1.000e-09   1.000e-09   1.000e-09   1.000e-09 
 BP_SEQFIX                                 9.483e-02   3.078e-02   1.737e-02   1.000e-09 
 BP_SEQRND                                 9.483e-02   3.078e-02   1.737e-02   1.000e-09