├── AUTHORS ├── ChangeLog ├── LICENSE ├── Makefile ├── Makefile.ALL ├── Makefile.CYGWIN ├── Makefile.LINUX ├── Makefile.MACOSX ├── Makefile.MACOSX64 ├── Makefile.WINDOWS ├── README ├── customdoxygen.css ├── doxygen.conf ├── examples ├── Makefile ├── example.cpp ├── example_bipgraph.cpp ├── example_bipgraph.out ├── example_imagesegmentation.cpp ├── example_img_in1.jpg ├── example_img_in2.jpg ├── example_permute.cpp ├── example_permute.out ├── example_sprinkler.cpp ├── example_sprinkler.dot ├── example_sprinkler.png ├── example_sprinkler_em.cpp ├── example_sprinkler_gibbs.cpp ├── example_varset.cpp ├── example_varset.out ├── sprinkler.em └── uai2010-aie-solver.cpp ├── include └── dai │ ├── alldai.h │ ├── bbp.h │ ├── bipgraph.h │ ├── bp.h │ ├── bp_dual.h │ ├── cbp.h │ ├── clustergraph.h │ ├── dag.h │ ├── daialg.h │ ├── decmap.h │ ├── doc.h │ ├── emalg.h │ ├── enum.h │ ├── evidence.h │ ├── exactinf.h │ ├── exceptions.h │ ├── factor.h │ ├── factorgraph.h │ ├── fbp.h │ ├── gibbs.h │ ├── graph.h │ ├── hak.h │ ├── index.h │ ├── io.h │ ├── jtree.h │ ├── lc.h │ ├── matlab │ └── matlab.h │ ├── mf.h │ ├── mr.h │ ├── prob.h │ ├── properties.h │ ├── regiongraph.h │ ├── smallset.h │ ├── treeep.h │ ├── trwbp.h │ ├── util.h │ ├── var.h │ ├── varset.h │ └── weightedgraph.h ├── matlab ├── dai.m ├── dai_potstrength.m ├── dai_readfg.m └── dai_writefg.m ├── scripts ├── convert-fastInf-DAI.pl ├── makeREADME └── regenerate-properties ├── src ├── alldai.cpp ├── bbp.cpp ├── bipgraph.cpp ├── bp.cpp ├── bp_dual.cpp ├── cbp.cpp ├── clustergraph.cpp ├── dag.cpp ├── daialg.cpp ├── decmap.cpp ├── emalg.cpp ├── evidence.cpp ├── exactinf.cpp ├── exceptions.cpp ├── factor.cpp ├── factorgraph.cpp ├── fbp.cpp ├── gibbs.cpp ├── graph.cpp ├── hak.cpp ├── io.cpp ├── jtree.cpp ├── lc.cpp ├── matlab │ ├── dai.cpp │ ├── dai_potstrength.cpp │ ├── dai_readfg.cpp │ ├── dai_writefg.cpp │ └── matlab.cpp ├── mf.cpp ├── mr.cpp ├── properties.cpp ├── regiongraph.cpp ├── treeep.cpp ├── trwbp.cpp ├── util.cpp ├── varset.cpp └── weightedgraph.cpp ├── swig ├── Makefile ├── README ├── dai.i ├── example_sprinkler.m └── example_sprinkler.py ├── tests ├── alarm.fg ├── aliases.conf ├── hoi1.fg ├── hoi2.fg ├── hoi3.fg ├── hoi4.fg ├── jtreemapbug.fg ├── maxprodbug.fg ├── maxprodbug2.fg ├── maxprodbug3.fg ├── testall ├── testall.bat ├── testbbp.cpp ├── testdai.cpp ├── testem │ ├── 2var.em │ ├── 2var.fg │ ├── 2var_data.tab │ ├── 3var.em │ ├── 3var.fg │ ├── hoi1_data.tab │ ├── hoi1_infer_f2.em │ ├── hoi1_share_f0_f1_f2.em │ ├── hoi1_share_f0_f2.em │ ├── runtests │ ├── runtests.bat │ ├── testem.cpp │ └── testem.out ├── testfast.fg ├── testfast.out ├── testregression ├── testregression.bat ├── twofactors.fg ├── unit │ ├── alldai_test.cpp │ ├── bipgraph_test.cpp │ ├── clustergraph_test.cpp │ ├── dag_test.cpp │ ├── daialg_test.cpp │ ├── enum_test.cpp │ ├── exceptions_test.cpp │ ├── factor_test.cpp │ ├── factorgraph_test.cpp │ ├── graph_test.cpp │ ├── index_test.cpp │ ├── prob_test.cpp │ ├── properties_test.cpp │ ├── regiongraph_test.cpp │ ├── smallset_test.cpp │ ├── util_test.cpp │ ├── var_test.cpp │ ├── varset_test.cpp │ └── weightedgraph_test.cpp └── zeroes1.fg └── utils ├── createfg.cpp ├── fg2dot.cpp ├── fginfo.cpp ├── uai2fg.cpp └── viewfg /AUTHORS: -------------------------------------------------------------------------------- 1 | libDAI was written by Joris M. Mooij with the help of the following people: 2 | 3 | Martijn Leisink (laid down the foundations for the library), 4 | Frederik Eaton (contributed the Gibbs sampler, conditioned BP, fractional BP and various other improvements), 5 | Charles Vaske (contributed the parameter learning algorithms), 6 | Giuseppe Passino (contributed the findMaximum function, and various other improvements), 7 | Bastian Wemmenhove (contributed the MR algorithm), 8 | Patrick Pletscher (contributed the SWIG interface). 9 | 10 | Smaller contributions (bug fixes and miscellaneous smaller patches) have been made by: 11 | Claudio Lima, Christian Wojek, Sebastian Nowozin, Stefano Pellegrini, Ofer Meshi, 12 | Dan Preston, Peter Gober, Jiuxiang Hu, Peter Rockett, Dhruv Batra, Alexander Schwing, 13 | Alejandro Lage, Matt Dunham, Laurens van der Maaten, Jerome Maye, Priya, Hynek Urban, 14 | Avneesh Saluja, Thomas Mensink. 15 | 16 | Part of this work was part of the Interactive Collaborative Information Systems (ICIS) 17 | project, supported by the Dutch Ministry of Economic Affairs, grant BSIK03024. The 18 | Radboud University Nijmegen, The Netherlands, is one of the copyright holders. 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2011, the libDAI authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright notice, 9 | this list of conditions and the following disclaimer in the documentation 10 | and/or other materials provided with the distribution. 11 | 12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 16 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 17 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 19 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 20 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 21 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | -------------------------------------------------------------------------------- /Makefile.ALL: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This file can be used to configure compile time options of libDAI. 9 | # Here the user can enable or disable various approximate inference 10 | # methods and additional build targets (documentation, MatLab interface) 11 | # and specify whether to build with debug information included. 12 | # 13 | # It is platform independent and is included by Makefile. 14 | # 15 | # A boolean variable VAR can be set to true ("VAR=true") or to false ("VAR=") 16 | 17 | 18 | # COMPILATION AND BUILD FLAGS 19 | 20 | # Enable/disable various approximate inference methods 21 | WITH_BP=true 22 | WITH_FBP=true 23 | WITH_TRWBP=true 24 | WITH_MF=true 25 | WITH_HAK=true 26 | WITH_LC=true 27 | WITH_TREEEP=true 28 | WITH_JTREE=true 29 | WITH_MR=true 30 | WITH_GIBBS=true 31 | WITH_CBP=true 32 | WITH_DECMAP=true 33 | 34 | # Build with debug info? (slower but safer) 35 | DEBUG=true 36 | 37 | # Build doxygen documentation? (doxygen and TeX need to be installed) 38 | WITH_DOC= 39 | 40 | # Build MatLab interface? (MatLab needs to be installed) 41 | WITH_MATLAB= 42 | 43 | # Build image segmentation example? (CImg needs to be installed) 44 | WITH_CIMG= 45 | -------------------------------------------------------------------------------- /Makefile.CYGWIN: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This template contains configurations for compiling libDAI under Cygwin 9 | # 10 | # It has been tested with Windows XP, Cygwin 1.7.4 and Boost 1.42.0 11 | # 12 | # To use it, simply copy this file to 'Makefile.conf' and adapt 'Makefile.conf' 13 | # to your local setup 14 | 15 | 16 | # OPERATING SYSTEM 17 | # Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX} 18 | OS=CYGWIN 19 | 20 | # FILE EXTENSIONS 21 | # Static library 22 | LE=.a 23 | # Object file 24 | OE=.o 25 | # Binary executable 26 | EE= 27 | # MatLab compiled MEX file 28 | ME=.mexglx 29 | 30 | # COMPILER 31 | # Compile using GNU C++ Compiler 32 | CC=g++ 33 | # Output filename option of the compiler 34 | CCO=-o 35 | # Flags for the C++ compiler 36 | CCFLAGS=-Wno-deprecated -Wall -W -Wextra -DCYGWIN 37 | # Flags to add in debugging mode (if DEBUG=true) 38 | CCDEBUGFLAGS=-O3 -g -DDAI_DEBUG 39 | # Flags to add in non-debugging mode (if DEBUG=false) 40 | CCNODEBUGFLAGS=-O3 41 | # Standard include directories 42 | CCINC=-Iinclude -I/cygdrive/e/cygwin/boost_1_42_0 43 | 44 | # LINKER 45 | # Standard libraries to include 46 | LIBS=-ldai -lgmpxx -lgmp 47 | # For linking with BOOST libraries 48 | BOOSTLIBS_PO=-lboost_program_options 49 | BOOSTLIBS_UTF=-lboost_unit_test_framework 50 | # Additional library search paths for linker 51 | CCLIB=-Llib -L/cygdrive/e/cygwin/boost_1_42_0/stage/lib 52 | 53 | # MATLAB 54 | # MatLab version 7.3 (R2006b) or newer? 55 | NEW_MATLAB=true 56 | # Replace the following by the directory where MatLab has been installed 57 | MATLABDIR=/agbs/share/sw/matlab 58 | # The following should resolve to the MatLab mex compile command 59 | MEX=$(MATLABDIR)/bin/mex 60 | # Specify the same C++ compiler and flags to mex 61 | MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)' 62 | # Standard include directories for MEX 63 | MEXINC:=$(CCINC) 64 | # Standard libraries to include 65 | MEXLIBS=-lgmpxx -lgmp 66 | # Additional library search paths for MEX 67 | MEXLIB= 68 | 69 | # SWIG PYTHON INTERFACE 70 | # The following should resolve to the SWIG command 71 | SWIG=swig 72 | # Location of Python header files 73 | INCLUDE_PYTHON=/usr/include/python2.5 74 | # Location of Boost C++ library header files 75 | INCLUDE_BOOST=/cygdrive/e/cygwin/boost_1_42_0 76 | 77 | # CIMG 78 | # CImg version 1.3.0 or newer? 79 | NEW_CIMG=true 80 | # Include directory for image segmentation example 81 | CIMGINC=-I/cygdrive/e/cygwin/CImg-1.3.9 82 | # Libraries for image segmentation example 83 | CIMGLIBS=-lpthread -lX11 84 | -------------------------------------------------------------------------------- /Makefile.LINUX: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This template contains configurations for compiling libDAI under GNU/Linux 9 | # and other UNIX variants 10 | # 11 | # It has been tested with Ubuntu 8.04, Ubuntu 9.04 and Debian testing 12 | # 13 | # To use it, simply copy this file to 'Makefile.conf' and adapt 'Makefile.conf' 14 | # to your local setup 15 | 16 | 17 | # OPERATING SYSTEM 18 | # Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX} 19 | OS=LINUX 20 | 21 | # FILE EXTENSIONS 22 | # Static library 23 | LE=.a 24 | # Object file 25 | OE=.o 26 | # Binary executable 27 | EE= 28 | # MatLab compiled MEX file 29 | ME=.mexglx 30 | 31 | # COMPILER 32 | # Compile using GNU C++ Compiler 33 | CC=g++ 34 | # Output filename option of the compiler 35 | CCO=-o 36 | # Flags for the C++ compiler 37 | CCFLAGS=-Wno-deprecated -Wall -W -Wextra -fpic 38 | # Flags to add in debugging mode (if DEBUG=true) 39 | CCDEBUGFLAGS=-O3 -g -DDAI_DEBUG 40 | # Flags to add in non-debugging mode (if DEBUG=false) 41 | CCNODEBUGFLAGS=-O3 42 | # Standard include directories 43 | CCINC=-Iinclude 44 | 45 | # LINKER 46 | # Standard libraries to include 47 | LIBS=-ldai -lgmpxx -lgmp 48 | # For linking with BOOST libraries 49 | BOOSTLIBS_PO=-lboost_program_options-mt 50 | BOOSTLIBS_UTF=-lboost_unit_test_framework-mt 51 | # Additional library search paths for linker 52 | CCLIB=-Llib 53 | 54 | # MATLAB 55 | # MatLab version 7.3 (R2006b) or newer? 56 | NEW_MATLAB=true 57 | # Replace the following by the directory where MatLab has been installed 58 | MATLABDIR=/opt/Matlab-R2010b 59 | # The following should resolve to the MatLab mex compile command 60 | MEX=$(MATLABDIR)/bin/mex 61 | # Specify the C++ compiler and flags for MEX 62 | MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)' 63 | # Standard include directories for MEX 64 | MEXINC:=$(CCINC) 65 | # Standard libraries to include 66 | MEXLIBS=-lgmpxx -lgmp 67 | # Additional library search paths for MEX 68 | MEXLIB= 69 | 70 | # SWIG PYTHON INTERFACE 71 | # The following should resolve to the SWIG command 72 | SWIG=swig 73 | # Location of Python header files 74 | INCLUDE_PYTHON=/usr/include/python2.7 75 | # Location of Boost C++ library header files 76 | INCLUDE_BOOST=/usr/include/boost 77 | 78 | # CIMG 79 | # CImg version 1.3.0 or newer? 80 | NEW_CIMG=true 81 | # Include directory for image segmentation example 82 | CIMGINC= 83 | # Libraries for image segmentation example 84 | CIMGLIBS=-lpthread -lX11 85 | -------------------------------------------------------------------------------- /Makefile.MACOSX: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This template contains configurations for compiling libDAI under Mac OS X (64-bits) 9 | # 10 | # To use it, simply copy this file to 'Makefile.conf' and adapt 'Makefile.conf' 11 | # to your local setup 12 | 13 | 14 | # OPERATING SYSTEM 15 | # Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX} 16 | OS=MACOSX 17 | 18 | # FILE EXTENSIONS 19 | # Static library 20 | LE=.a 21 | # Object file 22 | OE=.o 23 | # Binary executable 24 | EE= 25 | # MatLab compiled MEX file 26 | ME=.mexglx 27 | 28 | # COMPILER 29 | # Compile using GNU C++ Compiler 30 | CC=g++ 31 | # Output filename option of the compiler 32 | CCO=-o 33 | # Flags for the C++ compiler 34 | CCFLAGS=-Wno-deprecated -Wall -W -Wextra -fPIC -DMACOSX -arch i386 35 | # Flags to add in debugging mode (if DEBUG=true) 36 | CCDEBUGFLAGS=-O3 -g -DDAI_DEBUG 37 | # Flags to add in non-debugging mode (if DEBUG=false) 38 | CCNODEBUGFLAGS=-O3 39 | # Standard include directories 40 | CCINC=-Iinclude -I/opt/local/include 41 | 42 | # LINKER 43 | # Standard libraries to include 44 | LIBS=-ldai -lgmpxx -lgmp -arch i386 45 | # For linking with BOOST libraries 46 | BOOSTLIBS_PO=-lboost_program_options 47 | BOOSTLIBS_UTF=-lboost_unit_test_framework 48 | # Additional library search paths for linker 49 | CCLIB=-Llib -L/opt/local/lib 50 | 51 | # MATLAB 52 | # MatLab version 7.3 (R2006b) or newer? 53 | NEW_MATLAB=true 54 | # Replace the following by the directory where MatLab has been installed 55 | MATLABDIR=/opt/Matlab-R2010b 56 | # The following should resolve to the MatLab mex compile command 57 | MEX=$(MATLABDIR)/bin/mex 58 | # Specify the C++ compiler and flags for MEX 59 | MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)' 60 | # Standard include directories for MEX 61 | MEXINC:=$(CCINC) 62 | # Standard libraries to include 63 | MEXLIBS=-lgmpxx -lgmp 64 | # Additional library search paths for MEX 65 | MEXLIB= 66 | 67 | # SWIG PYTHON INTERFACE 68 | # The following should resolve to the SWIG command 69 | SWIG=swig 70 | # Location of Python header files 71 | INCLUDE_PYTHON=/usr/include/python2.5 72 | # Location of Boost C++ library header files 73 | INCLUDE_BOOST=/usr/include/boost 74 | 75 | # CIMG 76 | # CImg version 1.3.0 or newer? 77 | NEW_CIMG=true 78 | # Include directory for image segmentation example 79 | CIMGINC= 80 | # Libraries for image segmentation example 81 | CIMGLIBS=-lpthread -lX11 82 | -------------------------------------------------------------------------------- /Makefile.MACOSX64: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This template contains configurations for compiling libDAI under Mac OS X 9 | # 10 | # To use it, simply copy this file to 'Makefile.conf' and adapt 'Makefile.conf' 11 | # to your local setup 12 | 13 | 14 | # OPERATING SYSTEM 15 | # Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX} 16 | OS=MACOSX 17 | 18 | # FILE EXTENSIONS 19 | # Static library 20 | LE=.a 21 | # Object file 22 | OE=.o 23 | # Binary executable 24 | EE= 25 | # MatLab compiled MEX file 26 | ME=.mexglx 27 | 28 | # COMPILER 29 | # Compile using GNU C++ Compiler 30 | CC=g++ 31 | # Output filename option of the compiler 32 | CCO=-o 33 | # Flags for the C++ compiler 34 | CCFLAGS=-Wno-deprecated -Wall -W -Wextra -fPIC -DMACOSX -arch x86_64 35 | # Flags to add in debugging mode (if DEBUG=true) 36 | CCDEBUGFLAGS=-O3 -g -DDAI_DEBUG 37 | # Flags to add in non-debugging mode (if DEBUG=false) 38 | CCNODEBUGFLAGS=-O3 39 | # Standard include directories 40 | CCINC=-Iinclude -I/opt/local/include 41 | 42 | # LINKER 43 | # Standard libraries to include 44 | LIBS=-ldai -lgmpxx -lgmp -arch x86_64 45 | # For linking with BOOST libraries 46 | BOOSTLIBS_PO=-lboost_program_options 47 | BOOSTLIBS_UTF=-lboost_unit_test_framework 48 | # Additional library search paths for linker 49 | CCLIB=-Llib -L/opt/local/lib 50 | 51 | # MATLAB 52 | # MatLab version 7.3 (R2006b) or newer? 53 | NEW_MATLAB=true 54 | # Replace the following by the directory where MatLab has been installed 55 | MATLABDIR=/opt/Matlab-R2010b 56 | # The following should resolve to the MatLab mex compile command 57 | MEX=$(MATLABDIR)/bin/mex 58 | # Specify the C++ compiler and flags for MEX 59 | MEXFLAGS:=CXX\#$(CC) CXXFLAGS\#'$(CCFLAGS)' 60 | # Standard include directories for MEX 61 | MEXINC:=$(CCINC) 62 | # Standard libraries to include 63 | MEXLIBS=-lgmpxx -lgmp 64 | # Additional library search paths for MEX 65 | MEXLIB= 66 | 67 | # SWIG PYTHON INTERFACE 68 | # The following should resolve to the SWIG command 69 | SWIG=swig 70 | # Location of Python header files 71 | INCLUDE_PYTHON=/usr/include/python2.5 72 | # Location of Boost C++ library header files 73 | INCLUDE_BOOST=/usr/include/boost 74 | 75 | # CIMG 76 | # CImg version 1.3.0 or newer? 77 | NEW_CIMG=true 78 | # Include directory for image segmentation example 79 | CIMGINC= 80 | # Libraries for image segmentation example 81 | CIMGLIBS=-lpthread -lX11 82 | -------------------------------------------------------------------------------- /Makefile.WINDOWS: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This template contains configurations for compiling libDAI with Visual C++ 9 | # under Windows (and GNU Make) 10 | # 11 | # TODO: the latest libDAI version depends on GMP (Windows users can use MPIR) 12 | # This file has to be updated in order to link with the right GMP/MPIR libraries 13 | # 14 | # To use it, simply copy this file to 'Makefile.conf' and adapt 'Makefile.conf' 15 | # to your local setup 16 | 17 | 18 | # OPERATING SYSTEM 19 | # Choose OS from {LINUX, WINDOWS, CYGWIN, MACOSX} 20 | OS=WINDOWS 21 | 22 | # FILE EXTENSIONS 23 | # Static library 24 | LE=.lib 25 | # Object file 26 | OE=.obj 27 | # Binary executable 28 | EE=.exe 29 | # MatLab compiled MEX file 30 | ME=.mexw32 31 | 32 | # COMPILER 33 | # Compile using Visual C++ Compiler 34 | CC=cl 35 | # Output filename option of the compiler 36 | CCO=/Fe 37 | # Flags for the C++ compiler 38 | CCFLAGS=/EHac /GR /W3 /DWINDOWS /DNOMINMAX /MD 39 | # For MatLab R2008b, the following flag seems to be necessary: /D_SECURE_SCL=0 40 | # but it generates exceptions in normal executables... therefore, the MatLab 41 | # interface is now built from source completely using mex 42 | # Flags to add in debugging mode (if DEBUG=true) 43 | CCDEBUGFLAGS=/Ox /Zi /DDAI_DEBUG 44 | # Flags to add in non-debugging mode (if DEBUG=false) 45 | CCNODEBUGFLAGS=/Ox 46 | # Standard include directories 47 | CCINC=-Iinclude -IE:\windows\boost_1_42_0 48 | 49 | # LINKER 50 | # Standard libraries to include 51 | LIBS=/link $(LIB)/libdai$(LE) 52 | # For linking with BOOST libraries 53 | BOOSTLIBS_PO=/LIBPATH:E:\windows\boost_1_42_0\stage\lib 54 | BOOSTLIBS_UTF=/LIBPATH:E:\windows\boost_1_42_0\stage\lib 55 | # Additional library search paths for linker 56 | # (For some reason, we have to add the VC library path, although it is in the environment) 57 | CCLIB=/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" 58 | 59 | # MATLAB 60 | # MatLab version 7.3 (R2006b) or newer? 61 | NEW_MATLAB=true 62 | # Replace the following by the directory where MatLab has been installed 63 | MATLABDIR=c:\matlab\R2008b 64 | # The following should resolve to the MatLab mex compile command 65 | MEX=$(MATLABDIR)\bin\mex 66 | # Flags for MEX 67 | MEXFLAGS:=-DWINDOWS -DNOMINMAX 68 | # Standard include directories for MEX 69 | MEXINC:=$(CCINC) 70 | # Standard libraries to include 71 | MEXLIBS= 72 | # Additional library search paths for MEX 73 | MEXLIB= 74 | 75 | # SWIG PYTHON INTERFACE 76 | # The following should resolve to the SWIG command 77 | SWIG=swig 78 | # Location of Python header files 79 | INCLUDE_PYTHON=C:\python2.5 80 | # Location of Boost C++ library header files 81 | INCLUDE_BOOST=E:\windows\boost_1_42_0 82 | 83 | # CIMG 84 | # CImg version 1.3.0 or newer? 85 | NEW_CIMG=true 86 | # Include directory for image segmentation example 87 | CIMGINC=-IE:\windows\CImg-1.3.9 88 | # Libraries for image segmentation example 89 | CIMGLIBS=gdi32.lib user32.lib shell32.lib 90 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | # Include flags 2 | INC=-I../include 3 | # Library path flags 4 | LIBS=-lgmpxx -lgmp 5 | # Location of libDAI library 6 | LIB=../lib 7 | # Compiler 8 | CC=g++ 9 | # Compiler flags 10 | CCFLAGS=-Wno-deprecated -Wall -W -Wextra -fpic -O3 -static $(INC) 11 | 12 | all : uai2010-aie-solver 13 | 14 | uai2010-aie-solver : uai2010-aie-solver.cpp $(LIB)/libdai.a 15 | $(CC) $(CCFLAGS) -o$@ $< $(LIB)/libdai.a $(LIBS) 16 | 17 | # CLEAN 18 | ######## 19 | 20 | .PHONY : clean 21 | clean : 22 | -rm uai2010-aie-solver 23 | -------------------------------------------------------------------------------- /examples/example_bipgraph.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | using namespace std; 12 | using namespace dai; 13 | 14 | int main() { 15 | // Create a list of edges 16 | vector edges; 17 | edges.reserve( 5 ); 18 | edges.push_back( Edge(0, 0) ); 19 | edges.push_back( Edge(1, 0) ); 20 | edges.push_back( Edge(2, 0) ); 21 | edges.push_back( Edge(1, 1) ); 22 | edges.push_back( Edge(2, 1) ); 23 | 24 | // Create a bipartite graph with 3 nodes of type 1, 25 | // 2 nodes of type 2 and edge list edges. 26 | BipartiteGraph G( 3, 2, edges.begin(), edges.end() ); 27 | 28 | // Display some information about G 29 | cout << "G has " << G.nrNodes1() << " nodes of type 1, " << G.nrNodes2() << " nodes of type 2 and " << G.nrEdges() << " edges." << endl << endl; 30 | 31 | // Iterate over all nodes n1 of type 1 32 | for( size_t n1 = 0; n1 < G.nrNodes1(); n1++ ) { 33 | cout << "Node " << n1 << " of type 1 has " << G.nb1(n1).size() << " neighbors:" << endl; 34 | // Iterate over all neighbors n2 of n1 35 | bforeach( const Neighbor &n2, G.nb1(n1) ) { 36 | // The n2.iter'th neighbor of n1 is n2: 37 | DAI_ASSERT( G.nb1(n1)[n2.iter] == n2 ); 38 | 39 | // The n2.dual'th neighbor of n2 is n1: 40 | DAI_ASSERT( G.nb2(n2)[n2.dual] == n1 ); 41 | 42 | // n2 can be used as an abbreviation of n2.node: 43 | DAI_ASSERT( static_cast(n2) == n2.node ); 44 | 45 | cout << " the " << n2.iter << "'th neighbor is node " << n2 << " of type 2" << endl; 46 | } 47 | cout << endl; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /examples/example_bipgraph.out: -------------------------------------------------------------------------------- 1 | G has 3 nodes of type 1, 2 nodes of type 2 and 5 edges. 2 | 3 | Node 0 of type 1 has 1 neighbors: 4 | the 0'th neighbor is node 0 of type 2 5 | 6 | Node 1 of type 1 has 2 neighbors: 7 | the 0'th neighbor is node 0 of type 2 8 | the 1'th neighbor is node 1 of type 2 9 | 10 | Node 2 of type 1 has 2 neighbors: 11 | the 0'th neighbor is node 0 of type 2 12 | the 1'th neighbor is node 1 of type 2 13 | 14 | -------------------------------------------------------------------------------- /examples/example_img_in1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbtsai/libDAI/6df66a8ce7eb6f669bae933ab6ec35bbba56182f/examples/example_img_in1.jpg -------------------------------------------------------------------------------- /examples/example_img_in2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbtsai/libDAI/6df66a8ce7eb6f669bae933ab6ec35bbba56182f/examples/example_img_in2.jpg -------------------------------------------------------------------------------- /examples/example_permute.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | using namespace dai; 16 | 17 | int main() { 18 | Var x0(0, 2); // Define binary variable x0 (with label 0) 19 | Var x1(1, 3); // Define ternary variable x1 (with label 1) 20 | Var x2(2, 2); // Define binary variable x2 (with label 2) 21 | 22 | // Define vector V = (x1, x2, x0) 23 | vector V; // Define a vector of variables 24 | V.push_back( x1 ); // V[0] = x1; 25 | V.push_back( x2 ); // V[1] = x2; 26 | V.push_back( x0 ); // V[2] = x0; 27 | cout << "V = " << V << endl; // Note that the elements of X are not necessarily ordered according to their labels 28 | 29 | // Define set X = {x0, x1, x2} 30 | VarSet X; // empty 31 | X |= x2; // X = {x2} 32 | X |= x0; // X = {x0, x2} 33 | X |= x1; // X = {x0, x1, x2} 34 | cout << "X = " << X << endl; // Note that the elements of X are ordered according to their labels 35 | 36 | cout << "Note that the ordering of the variables in X is the canonical ordering" << endl; 37 | cout << "(ascendingly according to their labels) but the ordering in V is different." << endl << endl; 38 | 39 | // N = number of variables in V (and X) 40 | size_t N = V.size(); 41 | 42 | // Define a Permute object based on the variables in V 43 | Permute sigma(V); 44 | // Each Var in V corresponds with a dimension in a multi-dimensional array. 45 | // The permutation sigma permutes these dimensions from the canonical ordering 46 | // (sorted ascendingly on the label of the variable, i.e., the same ordering as 47 | // in X) into the ordering these variables have in V. 48 | cout << "The permutation between both variable orderings is sigma = " << sigma.sigma() << ", or more verbosely:" << endl; 49 | for( size_t n = 0; n < N; n++ ) 50 | cout << " sigma[" << n << "] = " << sigma[n] << endl; 51 | cout << "This means that variable V[sigma[n]] should correspond with the n'th variable in X (for n=0,...," << (N-1) << ")..."; 52 | // Check whether the permutation works as advertised 53 | VarSet::const_iterator X_n = X.begin(); 54 | for( size_t n = 0; n < N; n++, X_n++ ) 55 | DAI_ASSERT( V[sigma[n]] == *X_n ); 56 | cout << "OK. " << endl << endl; 57 | 58 | // Iterate over the joint states of the variables, according to the ordering in V 59 | cout << "The states of the variables x0,x1,x2 are, according to the ordering in V:" << endl; 60 | cout << "SV: x0: x1: x2:" << endl; 61 | std::vector ranges; 62 | for( size_t i = 0; i < V.size(); i++ ) 63 | ranges.push_back( V[i].states() ); 64 | for( multifor SV(ranges); SV.valid(); ++SV ) 65 | cout << setw(2) << (size_t)SV << " " << SV[sigma[0]] << " " << SV[sigma[1]] << " " << SV[sigma[2]] << endl; 66 | cout << endl; 67 | 68 | // Iterate over the joint states of the variables, according to the canonical ordering in X 69 | cout << "The states of the variables x0,x1,x2 are, according to the canonical ordering in X:" << endl; 70 | cout << "SX: x0: x1: x2:" << endl; 71 | for( State SX(X); SX.valid(); SX++ ) 72 | cout << setw(2) << SX << " " << SX(x0) << " " << SX(x1) << " " << SX(x2) << endl; 73 | cout << endl; 74 | 75 | // The main functionality of the Permute object is to calculate the induced permutation of linear indices of joint states 76 | cout << "The permutation sigma induces the following permutation of linear indices of joint states:" << endl; 77 | cout << "SV: SX:" << endl; 78 | for( size_t li = 0; li < X.nrStates(); li++ ) 79 | cout << setw(2) << li << " " << setw(2) << sigma.convertLinearIndex( li ) << endl; 80 | 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /examples/example_permute.out: -------------------------------------------------------------------------------- 1 | V = (x1, x2, x0) 2 | X = {x0, x1, x2} 3 | Note that the ordering of the variables in X is the canonical ordering 4 | (ascendingly according to their labels) but the ordering in V is different. 5 | 6 | The permutation between both variable orderings is sigma = (2, 0, 1), or more verbosely: 7 | sigma[0] = 2 8 | sigma[1] = 0 9 | sigma[2] = 1 10 | This means that variable V[sigma[n]] should correspond with the n'th variable in X (for n=0,...,2)...OK. 11 | 12 | The states of the variables x0,x1,x2 are, according to the ordering in V: 13 | SV: x0: x1: x2: 14 | 0 0 0 0 15 | 1 0 1 0 16 | 2 0 2 0 17 | 3 0 0 1 18 | 4 0 1 1 19 | 5 0 2 1 20 | 6 1 0 0 21 | 7 1 1 0 22 | 8 1 2 0 23 | 9 1 0 1 24 | 10 1 1 1 25 | 11 1 2 1 26 | 27 | The states of the variables x0,x1,x2 are, according to the canonical ordering in X: 28 | SX: x0: x1: x2: 29 | 0 0 0 0 30 | 1 1 0 0 31 | 2 0 1 0 32 | 3 1 1 0 33 | 4 0 2 0 34 | 5 1 2 0 35 | 6 0 0 1 36 | 7 1 0 1 37 | 8 0 1 1 38 | 9 1 1 1 39 | 10 0 2 1 40 | 11 1 2 1 41 | 42 | The permutation sigma induces the following permutation of linear indices of joint states: 43 | SV: SX: 44 | 0 0 45 | 1 2 46 | 2 4 47 | 3 6 48 | 4 8 49 | 5 10 50 | 6 1 51 | 7 3 52 | 8 5 53 | 9 7 54 | 10 9 55 | 11 11 56 | -------------------------------------------------------------------------------- /examples/example_sprinkler.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace dai; 15 | 16 | int main() { 17 | // This example program illustrates how to construct a factorgraph 18 | // by means of the sprinkler network example discussed at 19 | // http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html 20 | 21 | Var C(0, 2); // Define binary variable Cloudy (with label 0) 22 | Var S(1, 2); // Define binary variable Sprinkler (with label 1) 23 | Var R(2, 2); // Define binary variable Rain (with label 2) 24 | Var W(3, 2); // Define binary variable Wetgrass (with label 3) 25 | 26 | // Define probability distribution for C 27 | Factor P_C( C ); 28 | P_C.set(0, 0.5); // C = 0 29 | P_C.set(1, 0.5); // C = 1 30 | 31 | // Define conditional probability of S given C 32 | Factor P_S_given_C( VarSet( S, C ) ); 33 | P_S_given_C.set(0, 0.5); // C = 0, S = 0 34 | P_S_given_C.set(1, 0.9); // C = 1, S = 0 35 | P_S_given_C.set(2, 0.5); // C = 0, S = 1 36 | P_S_given_C.set(3, 0.1); // C = 1, S = 1 37 | 38 | // Define conditional probability of R given C 39 | Factor P_R_given_C( VarSet( R, C ) ); 40 | P_R_given_C.set(0, 0.8); // C = 0, R = 0 41 | P_R_given_C.set(1, 0.2); // C = 1, R = 0 42 | P_R_given_C.set(2, 0.2); // C = 0, R = 1 43 | P_R_given_C.set(3, 0.8); // C = 1, R = 1 44 | 45 | // Define conditional probability of W given S and R 46 | Factor P_W_given_S_R( VarSet( S, R ) | W ); 47 | P_W_given_S_R.set(0, 1.0); // S = 0, R = 0, W = 0 48 | P_W_given_S_R.set(1, 0.1); // S = 1, R = 0, W = 0 49 | P_W_given_S_R.set(2, 0.1); // S = 0, R = 1, W = 0 50 | P_W_given_S_R.set(3, 0.01); // S = 1, R = 1, W = 0 51 | P_W_given_S_R.set(4, 0.0); // S = 0, R = 0, W = 1 52 | P_W_given_S_R.set(5, 0.9); // S = 1, R = 0, W = 1 53 | P_W_given_S_R.set(6, 0.9); // S = 0, R = 1, W = 1 54 | P_W_given_S_R.set(7, 0.99); // S = 1, R = 1, W = 1 55 | 56 | // Build factor graph consisting of those four factors 57 | vector SprinklerFactors; 58 | SprinklerFactors.push_back( P_C ); 59 | SprinklerFactors.push_back( P_R_given_C ); 60 | SprinklerFactors.push_back( P_S_given_C ); 61 | SprinklerFactors.push_back( P_W_given_S_R ); 62 | FactorGraph SprinklerNetwork( SprinklerFactors ); 63 | 64 | // Write factorgraph to a file 65 | SprinklerNetwork.WriteToFile( "sprinkler.fg" ); 66 | cout << "Sprinkler network written to sprinkler.fg" << endl; 67 | 68 | // Output some information about the factorgraph 69 | cout << SprinklerNetwork.nrVars() << " variables" << endl; 70 | cout << SprinklerNetwork.nrFactors() << " factors" << endl; 71 | 72 | // Calculate joint probability of all four variables 73 | Factor P; 74 | for( size_t I = 0; I < SprinklerNetwork.nrFactors(); I++ ) 75 | P *= SprinklerNetwork.factor( I ); 76 | // P.normalize(); // Not necessary: a Bayesian network is already normalized by definition 77 | 78 | // Calculate some probabilities 79 | Real denom = P.marginal( W )[1]; 80 | cout << "P(W=1) = " << denom << endl; 81 | cout << "P(S=1 | W=1) = " << P.marginal( VarSet( S, W ) )[3] / denom << endl; 82 | cout << "P(R=1 | W=1) = " << P.marginal( VarSet( R, W ) )[3] / denom << endl; 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /examples/example_sprinkler.dot: -------------------------------------------------------------------------------- 1 | graph Sprinkler { 2 | node[shape=circle]; 3 | C; 4 | S; 5 | R; 6 | W; 7 | node[shape=box]; 8 | f0 [label="P (C)"]; 9 | f1 [label="P (S|C)"]; 10 | f2 [label="P (R|C)"]; 11 | f3 [label="P (W|S,R)"]; 12 | 13 | f0 -- C; 14 | f1 -- S; 15 | f1 -- C; 16 | f2 -- R; 17 | f2 -- C; 18 | f3 -- W; 19 | f3 -- S; 20 | f3 -- R; 21 | }; 22 | -------------------------------------------------------------------------------- /examples/example_sprinkler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbtsai/libDAI/6df66a8ce7eb6f669bae933ab6ec35bbba56182f/examples/example_sprinkler.png -------------------------------------------------------------------------------- /examples/example_sprinkler_em.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace dai; 15 | 16 | int main() { 17 | // This example program illustrates how to learn the 18 | // parameters of a Bayesian network from a sample of 19 | // the sprinkler network discussed at 20 | // http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html 21 | // 22 | // The factor graph file (sprinkler.fg) has to be generated first 23 | // by running example_sprinkler, and the data sample file 24 | // (sprinkler.tab) by running example_sprinkler_gibbs 25 | 26 | // Read the factorgraph from the file 27 | FactorGraph SprinklerNetwork; 28 | SprinklerNetwork.ReadFromFile( "sprinkler.fg" ); 29 | 30 | // Prepare junction-tree object for doing exact inference for E-step 31 | PropertySet infprops; 32 | infprops.set( "verbose", (size_t)1 ); 33 | infprops.set( "updates", string("HUGIN") ); 34 | InfAlg* inf = newInfAlg( "JTREE", SprinklerNetwork, infprops ); 35 | inf->init(); 36 | 37 | // Read sample from file 38 | Evidence e; 39 | ifstream estream( "sprinkler.tab" ); 40 | e.addEvidenceTabFile( estream, SprinklerNetwork ); 41 | cout << "Number of samples: " << e.nrSamples() << endl; 42 | 43 | // Read EM specification 44 | ifstream emstream( "sprinkler.em" ); 45 | EMAlg em(e, *inf, emstream); 46 | 47 | // Iterate EM until convergence 48 | while( !em.hasSatisfiedTermConditions() ) { 49 | Real l = em.iterate(); 50 | cout << "Iteration " << em.Iterations() << " likelihood: " << l <fg(); 62 | 63 | // Clean up 64 | delete inf; 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /examples/example_sprinkler_gibbs.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | using namespace dai; 17 | 18 | int main() { 19 | // This example program illustrates how to use Gibbs sampling 20 | // to sample from a joint probability distribution described 21 | // by a factor graph, using the sprinkler network example discussed at 22 | // http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html 23 | // 24 | // The file sprinkler.fg has to be generated by first running 25 | // example_sprinkler 26 | 27 | // Read the factorgraph from the file 28 | FactorGraph SprinklerNetwork; 29 | SprinklerNetwork.ReadFromFile( "sprinkler.fg" ); 30 | cout << "Sprinkler network read from sprinkler.fg" << endl; 31 | 32 | // Output some information about the factorgraph 33 | cout << SprinklerNetwork.nrVars() << " variables" << endl; 34 | cout << SprinklerNetwork.nrFactors() << " factors" << endl; 35 | 36 | // Prepare a Gibbs sampler 37 | PropertySet gibbsProps; 38 | gibbsProps.set("maxiter", size_t(100)); // number of Gibbs sampler iterations 39 | gibbsProps.set("burnin", size_t(0)); 40 | gibbsProps.set("verbose", size_t(0)); 41 | Gibbs gibbsSampler( SprinklerNetwork, gibbsProps ); 42 | 43 | // Open a .tab file for writing 44 | ofstream outfile; 45 | outfile.open( "sprinkler.tab" ); 46 | if( !outfile.is_open() ) 47 | throw "Cannot write to file!"; 48 | 49 | // Write header (consisting of variable labels) 50 | for( size_t i = 0; i < SprinklerNetwork.nrVars(); i++ ) 51 | outfile << (i == 0 ? "" : "\t") << SprinklerNetwork.var(i).label(); 52 | outfile << endl << endl; 53 | 54 | // Draw samples from joint distribution using Gibbs sampling 55 | // and write them to the .tab file 56 | size_t nrSamples = 1000; 57 | std::vector state; 58 | for( size_t t = 0; t < nrSamples; t++ ) { 59 | gibbsSampler.init(); 60 | gibbsSampler.run(); 61 | state = gibbsSampler.state(); 62 | for( size_t i = 0; i < state.size(); i++ ) 63 | outfile << (i == 0 ? "" : "\t") << state[i]; 64 | outfile << endl; 65 | } 66 | cout << nrSamples << " samples written to sprinkler.tab" << endl; 67 | 68 | // Close the .tab file 69 | outfile.close(); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /examples/example_varset.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | using namespace dai; 15 | 16 | int main() { 17 | Var x0(0, 2); // Define binary variable x0 (with label 0) 18 | Var x1(1, 3); // Define ternary variable x1 (with label 1) 19 | 20 | // Define set X = {x0, x1} 21 | VarSet X; // empty 22 | X |= x1; // X = {x1} 23 | X |= x0; // X = {x1, x0} 24 | cout << "X = " << X << endl << endl; // Note that the elements of X are ordered according to their labels 25 | 26 | // Output some information about x0, x1 and X 27 | cout << "Var " << x0 << " has " << x0.states() << " states (possible values)." << endl; 28 | cout << "Var " << x1 << " has " << x1.states() << " states." << endl << endl; 29 | cout << "VarSet " << X << " has " << X.nrStates() << " states (joint assignments of its variables)." << endl << endl; 30 | 31 | cout << "States of VarSets correspond to states of their constituent Vars:" << endl; 32 | cout << " state of x0: state of x1: (linear) state of X:" << endl; 33 | for( size_t s1 = 0; s1 < x1.states(); s1++ ) // for all states s1 of x1 34 | for( size_t s0 = 0; s0 < x0.states(); s0++ ) { // for all states s0 of x0 35 | // store s0 and s1 in a map "states" 36 | map states; 37 | states[x0] = s0; 38 | states[x1] = s1; 39 | 40 | // output states of x0, x1 and corresponding state of X 41 | cout << " " << s0 << " " << s1 << " " << calcLinearState(X,states) << endl; 42 | 43 | // calcState() is the inverse of calcLinearState() 44 | DAI_ASSERT( calcState(X, calcLinearState(X, states)) == states ); 45 | } 46 | 47 | cout << endl << "And vice versa:" << endl; 48 | cout << " state of x0: state of x1: (linear) state of X:" << endl; 49 | for( size_t S = 0; S < X.nrStates(); S++ ) { // for all (joint) states of X 50 | // calculate states of x0 and x1 corresponding to state S of X 51 | map states = calcState(X,S); 52 | 53 | // output state of X and corresponding states of x0, x1 54 | cout << " " << states[x0] << " " << states[x1] << " " << S << endl; 55 | 56 | // calcLinearState() is the inverse of calcState() 57 | DAI_ASSERT( calcLinearState(X, calcState(X,S)) == S ); 58 | } 59 | 60 | cout << endl << "Iterating over all joint states using the State class:" << endl; 61 | cout << " state of x0: state of x1: (linear) state of X: state of X (as a map):" << endl; 62 | for( State S(X); S.valid(); S++ ) { 63 | // output state of X and corresponding states of x0, x1 64 | cout << " " << S(x0) << " " << S(x1) << " " << S << " " << S.get() << endl; 65 | } 66 | 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /examples/example_varset.out: -------------------------------------------------------------------------------- 1 | X = {x0,x1} 2 | 3 | Var x0 has 2 states (possible values). 4 | Var x1 has 3 states. 5 | 6 | VarSet {x0,x1} has 6 states (joint assignments of its variables). 7 | 8 | States of VarSets correspond to states of their constituent Vars: 9 | state of x0: state of x1: state of X: 10 | 0 0 0 11 | 1 0 1 12 | 0 1 2 13 | 1 1 3 14 | 0 2 4 15 | 1 2 5 16 | 17 | And vice versa: 18 | state of x0: state of x1: state of X: 19 | 0 0 0 20 | 1 0 1 21 | 0 1 2 22 | 1 1 3 23 | 0 2 4 24 | 1 2 5 25 | -------------------------------------------------------------------------------- /examples/sprinkler.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 4 4 | CondProbEstimation [target_dim=2,total_dim=2,pseudo_count=1] 5 | 1 6 | 0 0 7 | CondProbEstimation [target_dim=2,total_dim=4,pseudo_count=1] 8 | 1 9 | 1 2 0 10 | CondProbEstimation [target_dim=2,total_dim=4,pseudo_count=1] 11 | 1 12 | 2 1 0 13 | CondProbEstimation [target_dim=2,total_dim=8,pseudo_count=1] 14 | 1 15 | 3 3 1 2 16 | -------------------------------------------------------------------------------- /include/dai/bp_dual.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class BP_dual, which is used primarily by BBP. 11 | /// \idea BP_dual replicates a large part of the functionality of BP; would it not be more efficient to adapt BP instead? 12 | /// \author Frederik Eaton 13 | 14 | 15 | #ifndef __defined_libdai_bp_dual_h 16 | #define __defined_libdai_bp_dual_h 17 | 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | namespace dai { 25 | 26 | 27 | /// Calculates both types of BP messages and their normalizers from an InfAlg. 28 | /** BP_dual calculates "dual" versions of BP messages (both messages from factors 29 | * to variables and messages from variables to factors), and normalizers, given an InfAlg. 30 | * These are computed from the variable and factor beliefs of the InfAlg. 31 | * This class is used primarily by BBP. 32 | * 33 | * \author Frederik Eaton 34 | */ 35 | class BP_dual { 36 | protected: 37 | /// Convenience label for storing edge properties 38 | template 39 | struct _edges_t : public std::vector > {}; 40 | 41 | /// Groups together the data structures for storing the two types of messages and their normalizers 42 | struct messages { 43 | /// Unnormalized variable->factor messages 44 | _edges_t n; 45 | /// Normalizers of variable->factor messages 46 | _edges_t Zn; 47 | /// Unnormalized Factor->variable messages 48 | _edges_t m; 49 | /// Normalizers of factor->variable messages 50 | _edges_t Zm; 51 | }; 52 | /// Stores all messages 53 | messages _msgs; 54 | 55 | /// Groups together the data structures for storing the two types of beliefs and their normalizers 56 | struct beliefs { 57 | /// Unnormalized variable beliefs 58 | std::vector b1; 59 | /// Normalizers of variable beliefs 60 | std::vector Zb1; 61 | /// Unnormalized factor beliefs 62 | std::vector b2; 63 | /// Normalizers of factor beliefs 64 | std::vector Zb2; 65 | }; 66 | /// Stores all beliefs 67 | beliefs _beliefs; 68 | 69 | /// Pointer to the InfAlg object 70 | const InfAlg *_ia; 71 | 72 | /// Does all necessary preprocessing 73 | void init(); 74 | /// Allocates space for \a _msgs 75 | void regenerateMessages(); 76 | /// Allocates space for \a _beliefs 77 | void regenerateBeliefs(); 78 | 79 | /// Calculate all messages from InfAlg beliefs 80 | void calcMessages(); 81 | /// Update factor->variable message (\a i -> \a I) 82 | void calcNewM(size_t i, size_t _I); 83 | /// Update variable->factor message (\a I -> \a i) 84 | void calcNewN(size_t i, size_t _I); 85 | 86 | /// Calculate all variable and factor beliefs from messages 87 | void calcBeliefs(); 88 | /// Calculate belief of variable \a i 89 | void calcBeliefV(size_t i); 90 | /// Calculate belief of factor \a I 91 | void calcBeliefF(size_t I); 92 | 93 | public: 94 | /// Construct BP_dual object from (converged) InfAlg object's beliefs and factors. 95 | /** \warning A pointer to the the InfAlg object is stored, 96 | * so the object must not be destroyed before the BP_dual is destroyed. 97 | */ 98 | BP_dual( const InfAlg *ia ) : _ia(ia) { init(); } 99 | 100 | /// Returns the underlying FactorGraph 101 | const FactorGraph& fg() const { return _ia->fg(); } 102 | 103 | /// Returns reference to factor->variable message (\a I -> \a i) 104 | Prob & msgM( size_t i, size_t _I ) { return _msgs.m[i][_I]; } 105 | /// Returns constant reference to factor->variable message (\a I -> \a i) 106 | const Prob & msgM( size_t i, size_t _I ) const { return _msgs.m[i][_I]; } 107 | /// Returns reference to variable -> factor message (\a i -> \a I) 108 | Prob & msgN( size_t i, size_t _I ) { return _msgs.n[i][_I]; } 109 | /// Returns constant reference to variable -> factor message (\a i -> \a I) 110 | const Prob & msgN( size_t i, size_t _I ) const { return _msgs.n[i][_I]; } 111 | /// Returns reference to normalizer for factor->variable message (\a I -> \a i) 112 | Real & zM( size_t i, size_t _I ) { return _msgs.Zm[i][_I]; } 113 | /// Returns constant reference to normalizer for factor->variable message (\a I -> \a i) 114 | const Real & zM( size_t i, size_t _I ) const { return _msgs.Zm[i][_I]; } 115 | /// Returns reference to normalizer for variable -> factor message (\a i -> \a I) 116 | Real & zN( size_t i, size_t _I ) { return _msgs.Zn[i][_I]; } 117 | /// Returns constant reference to normalizer for variable -> factor message (\a i -> \a I) 118 | const Real & zN( size_t i, size_t _I ) const { return _msgs.Zn[i][_I]; } 119 | 120 | /// Returns belief of variable \a i 121 | Factor beliefV( size_t i ) const { return Factor( _ia->fg().var(i), _beliefs.b1[i] ); } 122 | /// Returns belief of factor \a I 123 | Factor beliefF( size_t I ) const { return Factor( _ia->fg().factor(I).vars(), _beliefs.b2[I] ); } 124 | 125 | /// Returns normalizer for belief of variable \a i 126 | Real beliefVZ( size_t i ) const { return _beliefs.Zb1[i]; } 127 | /// Returns normalizer for belief of factor \a I 128 | Real beliefFZ( size_t I ) const { return _beliefs.Zb2[I]; } 129 | }; 130 | 131 | 132 | } // end of namespace dai 133 | 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /include/dai/decmap.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class DecMAP, which constructs a MAP state by decimation 11 | 12 | 13 | #ifndef __defined_libdai_decmap_h 14 | #define __defined_libdai_decmap_h 15 | 16 | 17 | #include 18 | 19 | 20 | namespace dai { 21 | 22 | 23 | /// Approximate inference algorithm DecMAP, which constructs a MAP state by decimation 24 | /** Decimation involves repeating the following two steps until no free variables remain: 25 | * - run an approximate inference algorithm, 26 | * - clamp the factor with the lowest entropy to its most probable state 27 | */ 28 | class DecMAP : public DAIAlgFG { 29 | private: 30 | /// Stores the final MAP state 31 | std::vector _state; 32 | /// Stores the log probability of the MAP state 33 | Real _logp; 34 | /// Maximum difference encountered so far 35 | Real _maxdiff; 36 | /// Number of iterations needed 37 | size_t _iters; 38 | 39 | public: 40 | /// Parameters for DecMAP 41 | struct Properties { 42 | /// Verbosity (amount of output sent to stderr) 43 | size_t verbose; 44 | 45 | /// Complete or partial reinitialization of clamped subgraphs? 46 | bool reinit; 47 | 48 | /// Name of the algorithm used to calculate the beliefs on clamped subgraphs 49 | std::string ianame; 50 | 51 | /// Parameters for the algorithm used to calculate the beliefs on clamped subgraphs 52 | PropertySet iaopts; 53 | } props; 54 | 55 | public: 56 | /// Default constructor 57 | DecMAP() : DAIAlgFG(), _state(), _logp(), _maxdiff(), _iters(), props() {} 58 | 59 | /// Construct from FactorGraph \a fg and PropertySet \a opts 60 | /** \param fg Factor graph. 61 | * \param opts Parameters @see Properties 62 | */ 63 | DecMAP( const FactorGraph &fg, const PropertySet &opts ); 64 | 65 | 66 | /// \name General InfAlg interface 67 | //@{ 68 | virtual DecMAP* clone() const { return new DecMAP(*this); } 69 | virtual DecMAP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new DecMAP( fg, opts ); } 70 | virtual std::string name() const { return "DECMAP"; } 71 | virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); } 72 | virtual Factor belief( const VarSet &/*vs*/ ) const; 73 | virtual Factor beliefV( size_t i ) const; 74 | virtual Factor beliefF( size_t I ) const { return belief( factor(I).vars() ); } 75 | virtual std::vector beliefs() const; 76 | virtual Real logZ() const { return _logp; } 77 | virtual std::vector findMaximum() const { return _state; } 78 | virtual void init() { _maxdiff = 0.0; _iters = 0; } 79 | virtual void init( const VarSet &/*ns*/ ) { init(); } 80 | virtual Real run(); 81 | virtual Real maxDiff() const { return _maxdiff; } 82 | virtual size_t Iterations() const { return _iters; } 83 | virtual void setProperties( const PropertySet &opts ); 84 | virtual PropertySet getProperties() const; 85 | virtual std::string printProperties() const; 86 | //@} 87 | }; 88 | 89 | 90 | } // end of namespace dai 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /include/dai/enum.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines the DAI_ENUM macro, which can be used to define an \c enum with additional functionality. 11 | 12 | 13 | #ifndef __defined_libdai_enum_h 14 | #define __defined_libdai_enum_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | /// Extends the C++ \c enum type by supporting input/output streaming and conversion to and from const char* and \c size_t 23 | /** For more details see the source code. 24 | * 25 | * \par Example: 26 | * \code 27 | * DAI_ENUM(colors,RED,GREEN,BLUE) 28 | * \endcode 29 | * defines a class \a colors encapsulating an 30 | * \code 31 | * enum {RED, GREEN, BLUE}; 32 | * \endcode 33 | * which offers additional functionality over the plain \c enum keyword. 34 | */ 35 | #define DAI_ENUM(x,val0,...) class x {\ 36 | public:\ 37 | enum value {val0,__VA_ARGS__};\ 38 | \ 39 | x() : v(val0) {}\ 40 | \ 41 | x(value w) : v(w) {}\ 42 | \ 43 | x(char const *w) {\ 44 | static char const* labelstring = #val0 "," #__VA_ARGS__;\ 45 | size_t pos_begin = 0;\ 46 | size_t i = 0;\ 47 | for( size_t pos_end = 0; ; pos_end++ ) {\ 48 | if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\ 49 | if( (strlen( w ) == pos_end - pos_begin) && (strncmp( labelstring + pos_begin, w, pos_end - pos_begin ) == 0) ) {\ 50 | v = (value)i;\ 51 | return;\ 52 | } else {\ 53 | i++;\ 54 | pos_begin = pos_end + 1;\ 55 | }\ 56 | }\ 57 | if( labelstring[pos_end] == '\0' )\ 58 | break;\ 59 | }\ 60 | DAI_THROWE(UNKNOWN_ENUM_VALUE,"'" + std::string(w) + "' is not in [" + std::string(labelstring) + "]");\ 61 | }\ 62 | \ 63 | operator value() const { return v; }\ 64 | \ 65 | operator size_t() const { return (size_t)v; }\ 66 | \ 67 | operator char const*() const {\ 68 | static char labelstring[] = #val0 "," #__VA_ARGS__;\ 69 | size_t pos_begin = 0;\ 70 | size_t i = 0;\ 71 | for( size_t pos_end = 0; ; pos_end++ )\ 72 | if( (labelstring[pos_end] == ',') || (labelstring[pos_end] == '\0') ) {\ 73 | if( (size_t)v == i ) {\ 74 | labelstring[pos_end] = '\0';\ 75 | return labelstring + pos_begin;\ 76 | } else {\ 77 | i++;\ 78 | pos_begin = pos_end + 1;\ 79 | }\ 80 | }\ 81 | }\ 82 | \ 83 | friend std::istream& operator >> (std::istream& is, x& y) {\ 84 | std::string s;\ 85 | is >> s;\ 86 | y = x(s.c_str());\ 87 | return is;\ 88 | }\ 89 | \ 90 | friend std::ostream& operator << (std::ostream& os, const x& y) {\ 91 | os << (const char *)y;\ 92 | return os;\ 93 | }\ 94 | \ 95 | protected:\ 96 | value v;\ 97 | }; 98 | 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /include/dai/evidence.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class Evidence, which stores multiple observations of joint states of variables 11 | 12 | 13 | #ifndef __defined_libdai_evidence_h 14 | #define __defined_libdai_evidence_h 15 | 16 | 17 | #include 18 | #include 19 | 20 | 21 | namespace dai { 22 | 23 | 24 | /// Stores a data set consisting of multiple samples, where each sample is the observed joint state of some variables. 25 | /** \note Each sample can describe the joint state of a different set of variables, 26 | * in order to be able to deal with missing data. 27 | * 28 | * \author Charles Vaske 29 | */ 30 | class Evidence { 31 | public: 32 | /// Stores joint state of a set of variables 33 | typedef std::map Observation; 34 | 35 | private: 36 | /// Each sample is an observed joint state of some variables 37 | std::vector _samples; 38 | 39 | public: 40 | /// Default constructor 41 | Evidence() : _samples() {} 42 | 43 | /// Construct from \a samples 44 | Evidence( std::vector &samples ) : _samples(samples) {} 45 | 46 | /// Read in tabular data from a stream and add the read samples to \c *this. 47 | /** \param is Input stream in .tab file format, describing joint observations of variables in \a fg 48 | * \param fg Factor graph describing the corresponding variables 49 | * \see \ref fileformats-evidence 50 | * \throw INVALID_EVIDENCE_FILE if the input stream is not valid 51 | */ 52 | void addEvidenceTabFile( std::istream& is, FactorGraph& fg ); 53 | 54 | /// Returns number of stored samples 55 | size_t nrSamples() const { return _samples.size(); } 56 | 57 | /// \name Iterator interface 58 | //@{ 59 | /// Iterator over the samples 60 | typedef std::vector::iterator iterator; 61 | /// Constant iterator over the samples 62 | typedef std::vector::const_iterator const_iterator; 63 | 64 | /// Returns iterator that points to the first sample 65 | iterator begin() { return _samples.begin(); } 66 | /// Returns constant iterator that points to the first sample 67 | const_iterator begin() const { return _samples.begin(); } 68 | /// Returns iterator that points beyond the last sample 69 | iterator end() { return _samples.end(); } 70 | /// Returns constant iterator that points beyond the last sample 71 | const_iterator end() const { return _samples.end(); } 72 | //@} 73 | 74 | private: 75 | /// Read in tabular data from a stream and add the read samples to \c *this. 76 | void addEvidenceTabFile( std::istream& is, std::map &varMap ); 77 | }; 78 | 79 | 80 | } // end of namespace dai 81 | 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /include/dai/exactinf.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines ExactInf class, which can be used for exact inference on small factor graphs. 11 | 12 | 13 | #ifndef __defined_libdai_exactinf_h 14 | #define __defined_libdai_exactinf_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | 23 | namespace dai { 24 | 25 | 26 | /// Exact inference algorithm using brute force enumeration (mainly useful for testing purposes) 27 | /** Inference is done simply by multiplying all factors together into one large factor, 28 | * and then calculating marginals and partition sum from the product. 29 | * \note This inference method can easily exhaust all available memory; in that case, one 30 | * may try the JTree class instead. 31 | */ 32 | class ExactInf : public DAIAlgFG { 33 | public: 34 | /// Parameters for ExactInf 35 | struct Properties { 36 | /// Verbosity (amount of output sent to stderr) 37 | size_t verbose; 38 | } props; 39 | 40 | private: 41 | /// All single variable marginals 42 | std::vector _beliefsV; 43 | /// All factor variable marginals 44 | std::vector _beliefsF; 45 | /// Logarithm of partition sum 46 | Real _logZ; 47 | 48 | public: 49 | /// \name Constructors/destructors 50 | //@{ 51 | /// Default constructor 52 | ExactInf() : DAIAlgFG(), props(), _beliefsV(), _beliefsF(), _logZ(0) {} 53 | 54 | /// Construct from FactorGraph \a fg and PropertySet \a opts 55 | /** \param fg Factor graph. 56 | * \param opts Parameters @see Properties 57 | */ 58 | ExactInf( const FactorGraph &fg, const PropertySet &opts ) : DAIAlgFG(fg), props(), _beliefsV(), _beliefsF(), _logZ() { 59 | setProperties( opts ); 60 | construct(); 61 | } 62 | //@} 63 | 64 | /// \name General InfAlg interface 65 | //@{ 66 | virtual ExactInf* clone() const { return new ExactInf(*this); } 67 | virtual ExactInf* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new ExactInf( fg, opts ); } 68 | virtual std::string name() const { return "EXACT"; } 69 | virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); } 70 | virtual Factor belief( const VarSet &vs ) const; 71 | virtual Factor beliefV( size_t i ) const { return _beliefsV[i]; } 72 | virtual Factor beliefF( size_t I ) const { return _beliefsF[I]; } 73 | virtual std::vector beliefs() const; 74 | virtual Real logZ() const { return _logZ; } 75 | /** \note The complexity of this calculation is exponential in the number of variables. 76 | */ 77 | std::vector findMaximum() const; 78 | virtual void init(); 79 | virtual void init( const VarSet &/*ns*/ ) {} 80 | virtual Real run(); 81 | virtual Real maxDiff() const { DAI_THROW(NOT_IMPLEMENTED); return 0.0; } 82 | virtual size_t Iterations() const { DAI_THROW(NOT_IMPLEMENTED); return 0; } 83 | virtual void setProperties( const PropertySet &opts ); 84 | virtual PropertySet getProperties() const; 85 | virtual std::string printProperties() const; 86 | //@} 87 | 88 | /// \name Additional interface specific for ExactInf 89 | //@{ 90 | /// Calculates marginal probability distribution for variables \a vs 91 | /** \note The complexity of this calculation is exponential in the number of variables. 92 | */ 93 | Factor calcMarginal( const VarSet &vs ) const; 94 | //@} 95 | 96 | private: 97 | /// Helper function for constructors 98 | void construct(); 99 | }; 100 | 101 | 102 | } // end of namespace dai 103 | 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /include/dai/fbp.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class FBP, which implements Fractional Belief Propagation 11 | 12 | 13 | #ifndef __defined_libdai_fbp_h 14 | #define __defined_libdai_fbp_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | namespace dai { 26 | 27 | 28 | /// Approximate inference algorithm "Fractional Belief Propagation" [\ref WiH03] 29 | /** The Fractional Belief Propagation algorithm is like Belief 30 | * Propagation, but associates each factor with a weight (scale parameter) 31 | * which controls the divergence measure being minimized. Standard 32 | * Belief Propagation corresponds to the case of FBP where each weight 33 | * is 1. When cast as an EP algorithm, BP (and EP) minimize 34 | * the inclusive KL-divergence, i.e. \f$\min_q KL(p||q)\f$ (note that the 35 | * Bethe free energy is typically derived from \f$ KL(q||p) \f$). If each 36 | * factor \a I has weight \f$ c_I \f$, then FBP minimizes the 37 | * alpha-divergence with \f$ \alpha=1/c_I \f$ for that factor, which also 38 | * corresponds to Power EP [\ref Min05]. 39 | * 40 | * The messages \f$m_{I\to i}(x_i)\f$ are passed from factors \f$I\f$ to variables \f$i\f$. 41 | * The update equation is given by: 42 | * \f[ m_{I\to i}(x_i) \propto \left( \sum_{x_{N_I\setminus\{i\}}} f_I(x_I)^{1/c_I} \prod_{j\in N_I\setminus\{i\}} m_{I\to j}^{1-1/c_I} \prod_{J\in N_j\setminus\{I\}} m_{J\to j} \right)^{c_I} \f] 43 | * After convergence, the variable beliefs are calculated by: 44 | * \f[ b_i(x_i) \propto \prod_{I\in N_i} m_{I\to i} \f] 45 | * and the factor beliefs are calculated by: 46 | * \f[ b_I(x_I) \propto f_I(x_I)^{1/c_I} \prod_{j \in N_I} m_{I\to j}^{1-1/c_I} \prod_{J\in N_j\setminus\{I\}} m_{J\to j} \f] 47 | * The logarithm of the partition sum is approximated by: 48 | * \f[ \log Z = \sum_{I} \sum_{x_I} b_I(x_I) \big( \log f_I(x_I) - c_I \log b_I(x_I) \big) + \sum_{i} (c_i - 1) \sum_{x_i} b_i(x_i) \log b_i(x_i) \f] 49 | * where the variable weights are defined as 50 | * \f[ c_i := \sum_{I \in N_i} c_I \f] 51 | * 52 | * \todo Add nice way to set weights 53 | * \author Frederik Eaton 54 | */ 55 | class FBP : public BP { 56 | protected: 57 | /// Factor weights (indexed by factor ID) 58 | std::vector _weight; 59 | 60 | public: 61 | /// \name Constructors/destructors 62 | //@{ 63 | /// Default constructor 64 | FBP() : BP(), _weight() {} 65 | 66 | /// Construct from FactorGraph \a fg and PropertySet \a opts 67 | /** \param fg Factor graph. 68 | * \param opts Parameters @see BP::Properties 69 | */ 70 | FBP( const FactorGraph &fg, const PropertySet &opts ) : BP(fg, opts), _weight() { 71 | setProperties( opts ); 72 | construct(); 73 | } 74 | //@} 75 | 76 | /// \name General InfAlg interface 77 | //@{ 78 | virtual FBP* clone() const { return new FBP(*this); } 79 | virtual FBP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new FBP( fg, opts ); } 80 | virtual std::string name() const { return "FBP"; } 81 | virtual Real logZ() const; 82 | //@} 83 | 84 | /// \name FBP accessors/mutators for weights 85 | //@{ 86 | /// Returns weight of the \a I 'th factor 87 | Real Weight( size_t I ) const { return _weight[I]; } 88 | 89 | /// Returns constant reference to vector of all factor weights 90 | const std::vector& Weights() const { return _weight; } 91 | 92 | /// Sets the weight of the \a I 'th factor to \a c 93 | void setWeight( size_t I, Real c ) { _weight[I] = c; } 94 | 95 | /// Sets the weights of all factors simultaenously 96 | /** \note Faster than calling setWeight(size_t,Real) for each factor 97 | */ 98 | void setWeights( const std::vector &c ) { _weight = c; } 99 | 100 | protected: 101 | /// Calculate the product of factor \a I and the incoming messages 102 | /** If \a without_i == \c true, the message coming from variable \a i is omitted from the product 103 | * \note This function is used by calcNewMessage() and calcBeliefF() 104 | */ 105 | virtual Prob calcIncomingMessageProduct( size_t I, bool without_i, size_t i ) const; 106 | 107 | // Calculate the updated message from the \a _I 'th neighbor of variable \a i to variable \a i 108 | virtual void calcNewMessage( size_t i, size_t _I ); 109 | 110 | // Calculates unnormalized belief of factor \a I 111 | virtual void calcBeliefF( size_t I, Prob &p ) const { 112 | p = calcIncomingMessageProduct( I, false, 0 ); 113 | } 114 | 115 | // Helper function for constructors 116 | virtual void construct(); 117 | }; 118 | 119 | 120 | } // end of namespace dai 121 | 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /include/dai/gibbs.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class Gibbs, which implements Gibbs sampling 11 | 12 | 13 | #ifndef __defined_libdai_gibbs_h 14 | #define __defined_libdai_gibbs_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | namespace dai { 23 | 24 | 25 | /// Approximate inference algorithm "Gibbs sampling" 26 | /** \author Frederik Eaton 27 | */ 28 | class Gibbs : public DAIAlgFG { 29 | private: 30 | /// Type used to store the counts of various states 31 | typedef std::vector _count_t; 32 | /// Type used to store the joint state of all variables 33 | typedef std::vector _state_t; 34 | /// Number of samples counted so far (excluding burn-in periods) 35 | size_t _sample_count; 36 | /// State counts for each variable 37 | std::vector<_count_t> _var_counts; 38 | /// State counts for each factor 39 | std::vector<_count_t> _factor_counts; 40 | /// Number of iterations done (including burn-in periods) 41 | size_t _iters; 42 | /// Current joint state of all variables 43 | _state_t _state; 44 | /// Joint state with maximum probability seen so far 45 | _state_t _max_state; 46 | /// Highest score so far 47 | Real _max_score; 48 | 49 | public: 50 | /// Parameters for Gibbs 51 | struct Properties { 52 | /// Maximum number of iterations 53 | size_t maxiter; 54 | 55 | /// Maximum time (in seconds) 56 | double maxtime; 57 | 58 | /// Number of iterations after which a random restart is made 59 | size_t restart; 60 | 61 | /// Number of "burn-in" iterations after each (re)start (for which no statistics are gathered) 62 | size_t burnin; 63 | 64 | /// Verbosity (amount of output sent to stderr) 65 | size_t verbose; 66 | } props; 67 | 68 | public: 69 | /// Default constructor 70 | Gibbs() : DAIAlgFG(), _sample_count(0), _var_counts(), _factor_counts(), _iters(0), _state(), _max_state(), _max_score(-INFINITY) {} 71 | 72 | /// Construct from FactorGraph \a fg and PropertySet \a opts 73 | /** \param fg Factor graph. 74 | * \param opts Parameters @see Properties 75 | */ 76 | Gibbs( const FactorGraph &fg, const PropertySet &opts ) : DAIAlgFG(fg), _sample_count(0), _var_counts(), _factor_counts(), _iters(0), _state(), _max_state(), _max_score(-INFINITY) { 77 | setProperties( opts ); 78 | construct(); 79 | } 80 | 81 | 82 | /// \name General InfAlg interface 83 | //@{ 84 | virtual Gibbs* clone() const { return new Gibbs(*this); } 85 | virtual Gibbs* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new Gibbs( fg, opts ); } 86 | virtual std::string name() const { return "GIBBS"; } 87 | virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); } 88 | virtual Factor belief( const VarSet &vs ) const; 89 | virtual Factor beliefV( size_t i ) const; 90 | virtual Factor beliefF( size_t I ) const; 91 | virtual std::vector beliefs() const; 92 | virtual Real logZ() const { DAI_THROW(NOT_IMPLEMENTED); return 0.0; } 93 | std::vector findMaximum() const { return _max_state; } 94 | virtual void init(); 95 | virtual void init( const VarSet &/*ns*/ ) { init(); } 96 | virtual Real run(); 97 | virtual Real maxDiff() const { DAI_THROW(NOT_IMPLEMENTED); return 0.0; } 98 | virtual size_t Iterations() const { return _iters; } 99 | virtual void setMaxIter( size_t maxiter ) { props.maxiter = maxiter; } 100 | virtual void setProperties( const PropertySet &opts ); 101 | virtual PropertySet getProperties() const; 102 | virtual std::string printProperties() const; 103 | //@} 104 | 105 | 106 | /// \name Additional interface specific for Gibbs 107 | //@{ 108 | /// Draw the current joint state of all variables from a uniform random distribution 109 | void randomizeState(); 110 | /// Return reference to current state of all variables 111 | std::vector& state() { return _state; } 112 | /// Return constant reference to current state of all variables 113 | const std::vector& state() const { return _state; } 114 | //@} 115 | 116 | private: 117 | /// Helper function for constructors 118 | void construct(); 119 | /// Updates all counts (_sample_count, _var_counts, _factor_counts) based on current state 120 | void updateCounts(); 121 | /// Calculate conditional distribution of variable \a i, given the current state 122 | Prob getVarDist( size_t i ); 123 | /// Draw state of variable \a i randomly from its conditional distribution and update the current state 124 | void resampleVar( size_t i ); 125 | /// Calculates linear index into factor \a I corresponding to the current state 126 | size_t getFactorEntry( size_t I ); 127 | /// Calculates the differences between linear indices into factor \a I corresponding with a state change of variable \a i 128 | size_t getFactorEntryDiff( size_t I, size_t i ); 129 | }; 130 | 131 | 132 | /// Runs Gibbs sampling for \a maxiter iterations (of which \a burnin for burn-in) on FactorGraph \a fg, and returns the resulting state 133 | /** \relates Gibbs 134 | */ 135 | std::vector getGibbsState( const FactorGraph &fg, size_t maxiter ); 136 | 137 | 138 | } // end of namespace dai 139 | 140 | 141 | /** \example example_sprinkler_gibbs.cpp 142 | * This example shows how to use the Gibbs class. 143 | */ 144 | 145 | 146 | #endif 147 | -------------------------------------------------------------------------------- /include/dai/io.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Provides functionality for input/output of data structures in various file formats 11 | 12 | 13 | #ifndef __defined_libdai_io_h 14 | #define __defined_libdai_io_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | namespace dai { 23 | 24 | 25 | /// Reads factor graph (as a pair of a variable vector and factor vector) from a file in the UAI approximate inference challenge format 26 | /** \param[in] filename The filename (usually ends with ".uai") 27 | * \param[in] verbose The amount of output sent to cout 28 | * \param[out] vars Array of variables read from the file 29 | * \param[out] factors Array of factors read from the file 30 | * \param[out] permutations Array of permutations, which permute between libDAI canonical ordering and ordering specified by the file 31 | * \see http://www.cs.huji.ac.il/project/UAI10 and http://graphmod.ics.uci.edu/uai08 32 | */ 33 | void ReadUaiAieFactorGraphFile( const char *filename, size_t verbose, std::vector& vars, std::vector& factors, std::vector& permutations ); 34 | 35 | 36 | /// Reads evidence (a mapping from observed variable labels to the observed values) from a file in the UAI approximate inference challenge format 37 | /** \param[in] filename The filename (usually ends with ".uai.evid") 38 | * \param[in] verbose The amount of output sent to cout 39 | * \see http://www.cs.huji.ac.il/project/UAI10 and http://graphmod.ics.uci.edu/uai08 40 | */ 41 | std::vector > ReadUaiAieEvidenceFile( const char* filename, size_t verbose ); 42 | 43 | 44 | } // end of namespace dai 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /include/dai/matlab/matlab.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines some utility functions for interfacing with MatLab 11 | 12 | 13 | #ifndef __defined_libdai_matlab_h 14 | #define __defined_libdai_matlab_h 15 | 16 | 17 | #include "mex.h" 18 | #include 19 | 20 | 21 | namespace dai { 22 | 23 | 24 | #ifdef SMALLMEM 25 | typedef int mwSize; 26 | typedef int mwIndex; 27 | #endif 28 | 29 | 30 | /// Convert vector structure to a cell vector of CPTAB-like structs 31 | mxArray *Factors2mx(const std::vector &Ps); 32 | 33 | /// Convert cell vector of CPTAB-like structs to vector 34 | std::vector mx2Factors(const mxArray *psi, long verbose); 35 | 36 | /// Convert CPTAB-like struct to Factor 37 | Factor mx2Factor(const mxArray *psi); 38 | 39 | 40 | } // end of namespace dai 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /include/dai/mf.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class MF which implements the Mean Field algorithm 11 | 12 | 13 | #ifndef __defined_libdai_mf_h 14 | #define __defined_libdai_mf_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | 24 | namespace dai { 25 | 26 | 27 | /// Approximate inference algorithm "Mean Field" 28 | /** The Mean Field algorithm iteratively calculates approximations of 29 | * single variable marginals (beliefs). The update equation for 30 | * a single belief \f$b_i\f$ is given by: 31 | * \f[ b_i^{\mathrm{new}}(x_i) \propto \prod_{I\in N_i} \exp \left( \sum_{x_{N_I \setminus \{i\}}} \log f_I(x_I) \prod_{j \in N_I \setminus \{i\}} b_j(x_j) \right) \f] 32 | * for naive mean field and by 33 | * \f[ b_i^{\mathrm{new}}(x_i) \propto \prod_{I\in N_i} \left( \sum_{x_{N_I \setminus \{i\}}} f_I(x_I) \prod_{j \in N_I \setminus \{i\}} b_j(x_j) \right) \f] 34 | * for hard-spin mean field. 35 | * These update equations are performed for all variables until convergence. 36 | */ 37 | class MF : public DAIAlgFG { 38 | private: 39 | /// Current approximations of single variable marginals 40 | std::vector _beliefs; 41 | /// Maximum difference encountered so far 42 | Real _maxdiff; 43 | /// Number of iterations needed 44 | size_t _iters; 45 | 46 | public: 47 | /// Parameters for MF 48 | struct Properties { 49 | /// Enumeration of possible message initializations 50 | DAI_ENUM(InitType,UNIFORM,RANDOM); 51 | 52 | /// Enumeration of possible update types 53 | DAI_ENUM(UpdateType,NAIVE,HARDSPIN); 54 | 55 | /// Verbosity (amount of output sent to stderr) 56 | size_t verbose; 57 | 58 | /// Maximum number of iterations 59 | size_t maxiter; 60 | 61 | /// Tolerance for convergence test 62 | Real tol; 63 | 64 | /// Damping constant (0.0 means no damping, 1.0 is maximum damping) 65 | Real damping; 66 | 67 | /// How to initialize the messages/beliefs 68 | InitType init; 69 | 70 | /// How to update the messages/beliefs 71 | UpdateType updates; 72 | } props; 73 | 74 | public: 75 | /// \name Constructors/destructors 76 | //@{ 77 | /// Default constructor 78 | MF() : DAIAlgFG(), _beliefs(), _maxdiff(0.0), _iters(0U), props() {} 79 | 80 | /// Construct from FactorGraph \a fg and PropertySet \a opts 81 | /** \param fg Factor graph. 82 | * \param opts Parameters @see Properties 83 | */ 84 | MF( const FactorGraph &fg, const PropertySet &opts ) : DAIAlgFG(fg), _beliefs(), _maxdiff(0.0), _iters(0U), props() { 85 | setProperties( opts ); 86 | construct(); 87 | } 88 | //@} 89 | 90 | /// \name General InfAlg interface 91 | //@{ 92 | virtual MF* clone() const { return new MF(*this); } 93 | virtual MF* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new MF( fg, opts ); } 94 | virtual std::string name() const { return "MF"; } 95 | virtual Factor belief( const Var &v ) const { return beliefV( findVar( v ) ); } 96 | virtual Factor belief( const VarSet &vs ) const; 97 | virtual Factor beliefV( size_t i ) const; 98 | virtual std::vector beliefs() const; 99 | virtual Real logZ() const; 100 | virtual void init(); 101 | virtual void init( const VarSet &ns ); 102 | virtual Real run(); 103 | virtual Real maxDiff() const { return _maxdiff; } 104 | virtual size_t Iterations() const { return _iters; } 105 | virtual void setMaxIter( size_t maxiter ) { props.maxiter = maxiter; } 106 | virtual void setProperties( const PropertySet &opts ); 107 | virtual PropertySet getProperties() const; 108 | virtual std::string printProperties() const; 109 | //@} 110 | 111 | private: 112 | /// Helper function for constructors 113 | void construct(); 114 | 115 | /// Calculates an updated belief of variable \a i 116 | Factor calcNewBelief( size_t i ); 117 | }; 118 | 119 | 120 | } // end of namespace dai 121 | 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /include/dai/trwbp.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class TRWBP, which implements Tree-Reweighted Belief Propagation 11 | 12 | 13 | #ifndef __defined_libdai_trwbp_h 14 | #define __defined_libdai_trwbp_h 15 | 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | 25 | namespace dai { 26 | 27 | 28 | /// Approximate inference algorithm "Tree-Reweighted Belief Propagation" [\ref WJW03] 29 | /** The Tree-Reweighted Belief Propagation algorithm is like Belief 30 | * Propagation, but associates each factor with a scale parameter. 31 | * which controls the divergence measure being minimized. 32 | * 33 | * The messages \f$m_{I\to i}(x_i)\f$ are passed from factors \f$I\f$ to variables \f$i\f$. 34 | * The update equation is given by: 35 | * \f[ m_{I\to i}(x_i) \propto \sum_{x_{N_I\setminus\{i\}}} f_I(x_I)^{1/c_I} \prod_{j\in N_I\setminus\{i\}} m_{I\to j}^{c_I-1} \prod_{J\in N_j\setminus\{I\}} m_{J\to j}^{c_J} \f] 36 | * After convergence, the variable beliefs are calculated by: 37 | * \f[ b_i(x_i) \propto \prod_{I\in N_i} m_{I\to i}^{c_I} \f] 38 | * and the factor beliefs are calculated by: 39 | * \f[ b_I(x_I) \propto f_I(x_I)^{1/c_I} \prod_{j \in N_I} m_{I\to j}^{c_I-1} \prod_{J\in N_j\setminus\{I\}} m_{J\to j}^{c_J} \f] 40 | * The logarithm of the partition sum is approximated by: 41 | * \f[ \log Z = \sum_{I} \sum_{x_I} b_I(x_I) \big( \log f_I(x_I) - c_I \log b_I(x_I) \big) + \sum_{i} (c_i - 1) \sum_{x_i} b_i(x_i) \log b_i(x_i) \f] 42 | * where the variable weights are defined as 43 | * \f[ c_i := \sum_{I \in N_i} c_I \f] 44 | * 45 | * \note TRWBP is actually equivalent to FBP 46 | * \todo Merge code of FBP and TRWBP 47 | */ 48 | class TRWBP : public BP { 49 | protected: 50 | /// "Edge weights" (indexed by factor ID) 51 | /** In [\ref WJW03], only unary or pairwise factors are considered. 52 | * Here we are more general by having a weight for each factor in the 53 | * factor graph. If unary factors have weight 1, and higher-order factors 54 | * are absent, then we have the special case considered in [\ref WJW03]. 55 | */ 56 | std::vector _weight; 57 | 58 | public: 59 | /// Size of sample of trees used to set the weights 60 | /** \todo See if there is a way to wrap TRWBP::nrtrees in a props struct 61 | * together with the other properties currently in TRWBP::props 62 | * (without copying al lot of BP code literally) 63 | */ 64 | size_t nrtrees; 65 | 66 | public: 67 | /// \name Constructors/destructors 68 | //@{ 69 | /// Default constructor 70 | TRWBP() : BP(), _weight() {} 71 | 72 | /// Construct from FactorGraph \a fg and PropertySet \a opts. 73 | /** There is an additional property "nrtrees" which allows to specify the 74 | * number of random spanning trees used to set the scale parameters. 75 | * \param fg Factor graph. 76 | * \param opts Parameters @see BP::Properties. 77 | */ 78 | TRWBP( const FactorGraph &fg, const PropertySet &opts ) : BP(fg, opts), _weight() { 79 | setProperties( opts ); 80 | construct(); 81 | } 82 | //@} 83 | 84 | /// \name General InfAlg interface 85 | //@{ 86 | virtual TRWBP* clone() const { return new TRWBP(*this); } 87 | virtual TRWBP* construct( const FactorGraph &fg, const PropertySet &opts ) const { return new TRWBP( fg, opts ); } 88 | virtual std::string name() const { return "TRWBP"; } 89 | virtual Real logZ() const; 90 | virtual void setProperties( const PropertySet &opts ); 91 | virtual PropertySet getProperties() const; 92 | virtual std::string printProperties() const; 93 | //@} 94 | 95 | /// \name TRWBP accessors/mutators for scale parameters 96 | //@{ 97 | /// Returns weight corresponding to the \a I 'th factor 98 | Real Weight( size_t I ) const { return _weight[I]; } 99 | 100 | /// Returns constant reference to vector of all weights 101 | const std::vector& Weights() const { return _weight; } 102 | 103 | /// Sets the weight of the \a I 'th factor to \a c 104 | void setWeight( size_t I, Real c ) { _weight[I] = c; } 105 | 106 | /// Sets the weights of all factors simultaenously 107 | /** \note Faster than calling setWeight(size_t,Real) for each factor 108 | */ 109 | void setWeights( const std::vector &c ) { _weight = c; } 110 | 111 | /// Increases weights corresponding to pairwise factors in \a tree with 1 112 | void addTreeToWeights( const RootedTree &tree ); 113 | 114 | /// Samples weights from a sample of \a nrTrees random spanning trees 115 | void sampleWeights( size_t nrTrees ); 116 | 117 | protected: 118 | /// Calculate the product of factor \a I and the incoming messages 119 | /** If \a without_i == \c true, the message coming from variable \a i is omitted from the product 120 | * \note This function is used by calcNewMessage() and calcBeliefF() 121 | */ 122 | virtual Prob calcIncomingMessageProduct( size_t I, bool without_i, size_t i ) const; 123 | 124 | /// Calculates unnormalized belief of variable \a i 125 | virtual void calcBeliefV( size_t i, Prob &p ) const; 126 | 127 | // Calculates unnormalized belief of factor \a I 128 | virtual void calcBeliefF( size_t I, Prob &p ) const { 129 | p = calcIncomingMessageProduct( I, false, 0 ); 130 | } 131 | 132 | // Helper function for constructors 133 | virtual void construct(); 134 | }; 135 | 136 | 137 | } // end of namespace dai 138 | 139 | 140 | #endif 141 | -------------------------------------------------------------------------------- /include/dai/var.h: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | /// \file 10 | /// \brief Defines class Var, which represents a discrete random variable. 11 | 12 | 13 | #ifndef __defined_libdai_var_h 14 | #define __defined_libdai_var_h 15 | 16 | 17 | #include 18 | #include 19 | 20 | 21 | namespace dai { 22 | 23 | 24 | /// Represents a discrete random variable. 25 | /** A Var stores the \a label of the variable (an unsigned integer-valued 26 | * unique ID) and the number of possible values (\a states) of that variable. 27 | * Two Var objects with the same label are assumed to be identical (i.e., it 28 | * is assumed that they have the same number of possible states). 29 | * 30 | * In the documentation, we use the following notational conventions. The discrete 31 | * random variable with label \f$l\f$ is denoted as \f$x_l\f$, and the number 32 | * of possible values of this variable as \f$S_l\f$; this is represented in 33 | * code by the object Var(\f$l\f$,\f$S_l\f$). The set of possible values of 34 | * variable \f$x_l\f$ is denoted \f$X_l := \{0,1,\dots,S_l-1\}\f$. 35 | */ 36 | class Var { 37 | private: 38 | /// Label of the variable (its unique ID) 39 | size_t _label; 40 | 41 | /// Number of possible values 42 | size_t _states; 43 | 44 | public: 45 | /// Default constructor (creates a variable with label 0 and 0 states) 46 | Var() : _label(0), _states(0) {} 47 | /// Constructs a variable with a given label and number of states 48 | Var( size_t label, size_t states ) : _label(label), _states(states) {} 49 | 50 | /// Returns the label 51 | size_t label() const { return _label; } 52 | /// Returns reference to label 53 | size_t& label() { return _label; } 54 | 55 | /// Returns the number of states 56 | size_t states() const { return _states; } 57 | /// Returns reference to number of states 58 | size_t& states() { return _states; } 59 | 60 | /// Smaller-than operator (only compares labels) 61 | bool operator< ( const Var& n ) const { 62 | #ifdef DAI_DEBUG 63 | if( _label == n._label ) 64 | DAI_ASSERT( _states == n._states ); 65 | #endif 66 | return( _label < n._label ); 67 | } 68 | 69 | /// Larger-than operator (only compares labels) 70 | bool operator> ( const Var& n ) const { 71 | #ifdef DAI_DEBUG 72 | if( _label == n._label ) 73 | DAI_ASSERT( _states == n._states ); 74 | #endif 75 | return( _label > n._label ); 76 | } 77 | 78 | /// Smaller-than-or-equal-to operator (only compares labels) 79 | bool operator<= ( const Var& n ) const { 80 | #ifdef DAI_DEBUG 81 | if( _label == n._label ) 82 | DAI_ASSERT( _states == n._states ); 83 | #endif 84 | return( _label <= n._label ); 85 | } 86 | 87 | /// Larger-than-or-equal-to operator (only compares labels) 88 | bool operator>= ( const Var& n ) const { 89 | #ifdef DAI_DEBUG 90 | if( _label == n._label ) 91 | DAI_ASSERT( _states == n._states ); 92 | #endif 93 | return( _label >= n._label ); 94 | } 95 | 96 | /// Not-equal-to operator (only compares labels) 97 | bool operator!= ( const Var& n ) const { 98 | #ifdef DAI_DEBUG 99 | if( _label == n._label ) 100 | DAI_ASSERT( _states == n._states ); 101 | #endif 102 | return( _label != n._label ); 103 | } 104 | 105 | /// Equal-to operator (only compares labels) 106 | bool operator== ( const Var& n ) const { 107 | #ifdef DAI_DEBUG 108 | if( _label == n._label ) 109 | DAI_ASSERT( _states == n._states ); 110 | #endif 111 | return( _label == n._label ); 112 | } 113 | 114 | /// Writes a Var to an output stream 115 | friend std::ostream& operator << ( std::ostream& os, const Var& n ) { 116 | return( os << "x" << n.label() ); 117 | } 118 | }; 119 | 120 | 121 | } // end of namespace dai 122 | 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /matlab/dai.m: -------------------------------------------------------------------------------- 1 | % [logZ,q,md,qv,qf,qmap] = dai(psi,method,opts) 2 | % 3 | % INPUT: psi = linear cell array containing the factors 4 | % (psi{i} should be a structure with a Member field 5 | % and a P field). 6 | % method = name of the method. 7 | % opts = string of options. 8 | % 9 | % OUTPUT: logZ = approximation of the logarithm of the partition sum. 10 | % q = linear cell array containing all final beliefs. 11 | % md = maxdiff (final linf-dist between new and old single node beliefs). 12 | % qv = linear cell array containing all variable beliefs. 13 | % qf = linear cell array containing all factor beliefs. 14 | % qmap = linear array containing the MAP state (only for BP,JTree). 15 | -------------------------------------------------------------------------------- /matlab/dai_potstrength.m: -------------------------------------------------------------------------------- 1 | % N = dai_potstrength (psi, i, j) 2 | % 3 | % INPUT: psi = structure with a Member field and a P field, like a CPTAB. 4 | % i = label of a variable in psi. 5 | % j = label of another variable in psi. 6 | % 7 | % OUTPUT: N = strength of psi in direction i->j. 8 | -------------------------------------------------------------------------------- /matlab/dai_readfg.m: -------------------------------------------------------------------------------- 1 | % [psi] = dai_readfg (filename) 2 | % 3 | % INPUT: filename = filename of a .fg file 4 | % 5 | % OUTPUT: psi = linear cell array containing the factors 6 | % (psi{i} is a structure with a Member field 7 | % and a P field, like a CPTAB). 8 | -------------------------------------------------------------------------------- /matlab/dai_writefg.m: -------------------------------------------------------------------------------- 1 | % dai_writefg(psi,filename) 2 | % 3 | % INPUT: psi = linear cell array containing the factors 4 | % (psi{i} should be a structure with a Member field 5 | % and a P field, like a CPTAB). 6 | % filename = filename of a .fg file 7 | -------------------------------------------------------------------------------- /scripts/convert-fastInf-DAI.pl: -------------------------------------------------------------------------------- 1 | #! /usr/local/bin/perl 2 | # 3 | # This file is part of libDAI - http://www.libdai.org/ 4 | # 5 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 6 | # 7 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 8 | 9 | 10 | use strict; 11 | use warnings; 12 | 13 | my $HOME = $ENV{HOME} ; 14 | 15 | if ($#ARGV == 0) { 16 | push (@ARGV,"$ARGV[0].fg") ; 17 | } 18 | 19 | my $expectedArgc = 2 ; 20 | if ($#ARGV != $expectedArgc-1) { 21 | die ("Usage: $0 \n") ; 22 | } 23 | 24 | my ($inModelFile,$outModelFile) = @ARGV ; 25 | 26 | # First we read the model: 27 | my (@variables,@cliques,@measures,%cliq2meas,$truePartition) ; 28 | &readModel ($inModelFile,\@variables,\@cliques,\@measures,\%cliq2meas,\$truePartition) ; 29 | 30 | 31 | open (OUT, ">$outModelFile") or die ("[ERROR] Cannot open output file $outModelFile\n") ; 32 | 33 | print OUT "# Converted $inModelFile from fastInf format into DAI format\n" ; 34 | 35 | print OUT scalar(@cliques), "\n\n" ; 36 | 37 | for (my $i=0 ; $i)) { 70 | 71 | if ($line =~ m/^\@Variables/) { 72 | &readLines (*MOD_IN , $variables) ; 73 | } 74 | elsif ($line =~ m/^\@Cliques/) { 75 | &readLines (*MOD_IN , $cliques) ; 76 | } 77 | elsif ($line =~ m/^\@Measures/) { 78 | &readLines (*MOD_IN , $measures) ; 79 | } 80 | elsif ($line =~ m/^\@CliqueToMeasure/) { 81 | &readCliq2Meas (*MOD_IN , $cliq2meas) ; 82 | } 83 | elsif ($line =~ m/^# Exact Partitition function:/) { 84 | my $partLine ; 85 | if (not defined ($partLine = )) { die ("[ERROR] Cannot read exact partition function."); } 86 | if ($partLine =~ m/^# (\S+)/) { 87 | $$truePartition = $1 ; 88 | } 89 | } 90 | # else do nothing 91 | 92 | } # while read line from model file 93 | 94 | close MOD_IN ; 95 | } 96 | 97 | sub readLines { 98 | my ($IN,$variables) = @_ ; 99 | 100 | my $endReached = 0 ; 101 | while (defined (my $line = <$IN>)) { 102 | if ($line =~ m/^\@End/) { 103 | $endReached = 1 ; 104 | last ; 105 | } 106 | else { 107 | push (@$variables,$line) ; 108 | } 109 | } 110 | 111 | if (not $endReached) { die ("[ERROR] Could not find \@End statement.\n") ; } 112 | } 113 | 114 | sub readCliq2Meas { 115 | my ($IN,$cliq2meas) = @_ ; 116 | 117 | my $endReached = 0 ; 118 | while (defined (my $line = <$IN>)) { 119 | if ($line =~ m/^\@End/) { 120 | $endReached = 1 ; 121 | last ; 122 | } 123 | else { 124 | my @splitLine = split(/\t/,$line) ; 125 | my $cliq = $splitLine[0] ; 126 | my $meas = $splitLine[1] ; 127 | $cliq2meas->{$cliq} = $meas ; 128 | } 129 | } 130 | 131 | if (not $endReached) { die ("[ERROR] Could not find \@End statement.\n") ; } 132 | } 133 | -------------------------------------------------------------------------------- /scripts/makeREADME: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "libDAI - A free/open source C++ library for Discrete Approximate Inference" > README 3 | echo >> README 4 | echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" >> README 5 | echo >> README 6 | echo "Version: $DAI_VERSION" >> README 7 | echo "Date: $DAI_DATE" >> README 8 | echo "See also: http://www.libdai.org" >> README 9 | echo >> README 10 | w3m -dump doc/html/license.html | awk 'BEGIN {start=0}; $1 ~ /━/ {start=start+1; if (start<2) print $0}; $1 !~ /━/ {if (start>0 && start<2) print $0}' >> README 11 | echo >> README 12 | w3m -dump doc/html/citations.html | awk 'BEGIN {start=0}; $1 ~ /━/ {start=start+1; if (start<2) print $0}; $1 !~ /━/ {if (start>0 && start<2) print $0}' >> README 13 | w3m -dump doc/html/index.html | awk 'BEGIN {start=0}; $1 ~ /━/ {start=start+1; if (start<2) print $0}; $1 !~ /━/ {if (start>0 && start<2) print $0}' >> README 14 | w3m -dump doc/html/build.html | awk 'BEGIN {start=0}; $1 ~ /━/ {start=start+1; if (start>0 && start<5) print $0}; $1 !~ /━/ {if (start>0 && start<5) print $0}' >> README 15 | sed -i 's/━/-/g' README 16 | sed -i 's/•/*/g' README 17 | -------------------------------------------------------------------------------- /src/alldai.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | namespace dai { 17 | 18 | 19 | using namespace std; 20 | 21 | 22 | class _builtinInfAlgs : public std::map { 23 | public: 24 | _builtinInfAlgs() { 25 | operator[]( ExactInf().name() ) = new ExactInf; 26 | #ifdef DAI_WITH_BP 27 | operator[]( BP().name() ) = new BP; 28 | #endif 29 | #ifdef DAI_WITH_FBP 30 | operator[]( FBP().name() ) = new FBP; 31 | #endif 32 | #ifdef DAI_WITH_TRWBP 33 | operator[]( TRWBP().name() ) = new TRWBP; 34 | #endif 35 | #ifdef DAI_WITH_MF 36 | operator[]( MF().name() ) = new MF; 37 | #endif 38 | #ifdef DAI_WITH_HAK 39 | operator[]( HAK().name() ) = new HAK; 40 | #endif 41 | #ifdef DAI_WITH_LC 42 | operator[]( LC().name() ) = new LC; 43 | #endif 44 | #ifdef DAI_WITH_TREEEP 45 | operator[]( TreeEP().name() ) = new TreeEP; 46 | #endif 47 | #ifdef DAI_WITH_JTREE 48 | operator[]( JTree().name() ) = new JTree; 49 | #endif 50 | #ifdef DAI_WITH_MR 51 | operator[]( MR().name() ) = new MR; 52 | #endif 53 | #ifdef DAI_WITH_GIBBS 54 | operator[]( Gibbs().name() ) = new Gibbs; 55 | #endif 56 | #ifdef DAI_WITH_CBP 57 | operator[]( CBP().name() ) = new CBP; 58 | #endif 59 | #ifdef DAI_WITH_DECMAP 60 | operator[]( DecMAP().name() ) = new DecMAP; 61 | #endif 62 | } 63 | 64 | ~_builtinInfAlgs() { 65 | for( iterator it = begin(); it != end(); it++ ) 66 | delete it->second; 67 | } 68 | }; 69 | 70 | 71 | static _builtinInfAlgs allBuiltinInfAlgs; 72 | 73 | 74 | std::map& builtinInfAlgs() { 75 | return allBuiltinInfAlgs; 76 | } 77 | 78 | 79 | std::set builtinInfAlgNames() { 80 | std::set algNames; 81 | for( _builtinInfAlgs::const_iterator it = allBuiltinInfAlgs.begin(); it != allBuiltinInfAlgs.end(); it++ ) 82 | algNames.insert( it->first ); 83 | return algNames; 84 | } 85 | 86 | 87 | InfAlg *newInfAlg( const std::string &name, const FactorGraph &fg, const PropertySet &opts ) { 88 | _builtinInfAlgs::const_iterator i = allBuiltinInfAlgs.find( name ); 89 | if( i == allBuiltinInfAlgs.end() ) 90 | DAI_THROWE(UNKNOWN_DAI_ALGORITHM, "Unknown inference algorithm: " + name); 91 | InfAlg *ia = i->second; 92 | return ia->construct( fg, opts ); 93 | } 94 | 95 | 96 | InfAlg *newInfAlgFromString( const std::string &nameOpts, const FactorGraph &fg ) { 97 | pair no = parseNameProperties( nameOpts ); 98 | return newInfAlg( no.first, fg, no.second ); 99 | } 100 | 101 | 102 | InfAlg *newInfAlgFromString( const std::string &nameOpts, const FactorGraph &fg, const std::map &aliases ) { 103 | pair no = parseNameProperties( nameOpts, aliases ); 104 | return newInfAlg( no.first, fg, no.second ); 105 | } 106 | 107 | 108 | std::pair parseNameProperties( const std::string &s ) { 109 | string::size_type pos = s.find_first_of('['); 110 | string name; 111 | PropertySet opts; 112 | if( pos == string::npos ) { 113 | name = s; 114 | } else { 115 | name = s.substr(0,pos); 116 | 117 | stringstream ss; 118 | ss << s.substr(pos,s.length()); 119 | ss >> opts; 120 | } 121 | return make_pair(name,opts); 122 | } 123 | 124 | 125 | std::pair parseNameProperties( const std::string &s, const std::map &aliases ) { 126 | // break string into method[properties] 127 | pair ps = parseNameProperties(s); 128 | bool looped = false; 129 | 130 | // as long as 'method' is an alias, update: 131 | while( aliases.find(ps.first) != aliases.end() && !looped ) { 132 | string astr = aliases.find(ps.first)->second; 133 | pair aps = parseNameProperties(astr); 134 | if( aps.first == ps.first ) 135 | looped = true; 136 | // override aps properties by ps properties 137 | aps.second.set( ps.second ); 138 | // replace ps by aps 139 | ps = aps; 140 | // repeat until method name == alias name ('looped'), or 141 | // there is no longer an alias 'method' 142 | } 143 | 144 | return ps; 145 | } 146 | 147 | 148 | std::map readAliasesFile( const std::string &filename ) { 149 | // Read aliases 150 | map result; 151 | ifstream infile; 152 | infile.open( filename.c_str() ); 153 | if( infile.is_open() ) { 154 | while( true ) { 155 | string line; 156 | getline( infile,line ); 157 | if( infile.fail() ) 158 | break; 159 | if( (!line.empty()) && (line[0] != '#') ) { 160 | string::size_type pos = line.find(':',0); 161 | if( pos == string::npos ) 162 | DAI_THROWE(INVALID_ALIAS,"Invalid alias '" + line + "'"); 163 | else { 164 | string::size_type posl = line.substr(0, pos).find_last_not_of(" \t"); 165 | string key = line.substr(0, posl + 1); 166 | string::size_type posr = line.substr(pos + 1, line.length()).find_first_not_of(" \t"); 167 | string val = line.substr(pos + 1 + posr, line.length()); 168 | result[key] = val; 169 | } 170 | } 171 | } 172 | infile.close(); 173 | } else 174 | DAI_THROWE(CANNOT_READ_FILE,"Error opening aliases file " + filename); 175 | return result; 176 | } 177 | 178 | 179 | } // end of namespace dai 180 | -------------------------------------------------------------------------------- /src/bp_dual.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | namespace dai { 19 | 20 | 21 | using namespace std; 22 | 23 | 24 | void BP_dual::init() { 25 | regenerateMessages(); 26 | regenerateBeliefs(); 27 | calcMessages(); 28 | calcBeliefs(); 29 | } 30 | 31 | 32 | void BP_dual::regenerateMessages() { 33 | size_t nv = fg().nrVars(); 34 | _msgs.Zn.resize(nv); 35 | _msgs.Zm.resize(nv); 36 | _msgs.m.resize(nv); 37 | _msgs.n.resize(nv); 38 | for( size_t i = 0; i < nv; i++ ) { 39 | size_t nvf = fg().nbV(i).size(); 40 | _msgs.Zn[i].resize(nvf, 1.0); 41 | _msgs.Zm[i].resize(nvf, 1.0); 42 | size_t states = fg().var(i).states(); 43 | _msgs.n[i].resize(nvf, Prob(states)); 44 | _msgs.m[i].resize(nvf, Prob(states)); 45 | } 46 | } 47 | 48 | 49 | void BP_dual::regenerateBeliefs() { 50 | _beliefs.b1.clear(); 51 | _beliefs.b1.reserve(fg().nrVars()); 52 | _beliefs.Zb1.resize(fg().nrVars(), 1.0); 53 | _beliefs.b2.clear(); 54 | _beliefs.b2.reserve(fg().nrFactors()); 55 | _beliefs.Zb2.resize(fg().nrFactors(), 1.0); 56 | 57 | for( size_t i = 0; i < fg().nrVars(); i++ ) 58 | _beliefs.b1.push_back( Prob( fg().var(i).states() ) ); 59 | for( size_t I = 0; I < fg().nrFactors(); I++ ) 60 | _beliefs.b2.push_back( Prob( fg().factor(I).nrStates() ) ); 61 | } 62 | 63 | 64 | void BP_dual::calcMessages() { 65 | // calculate 'n' messages from "factor marginal / factor" 66 | for( size_t I = 0; I < fg().nrFactors(); I++ ) { 67 | Factor f = _ia->beliefF(I) / fg().factor(I); 68 | bforeach( const Neighbor &i, fg().nbF(I) ) 69 | msgN(i, i.dual) = f.marginal( fg().var(i) ).p(); 70 | } 71 | // calculate 'm' messages and normalizers from 'n' messages 72 | for( size_t i = 0; i < fg().nrVars(); i++ ) 73 | bforeach( const Neighbor &I, fg().nbV(i) ) 74 | calcNewM( i, I.iter ); 75 | // recalculate 'n' messages and normalizers from 'm' messages 76 | for( size_t i = 0; i < fg().nrVars(); i++ ) 77 | bforeach( const Neighbor &I, fg().nbV(i) ) 78 | calcNewN(i, I.iter); 79 | } 80 | 81 | 82 | void BP_dual::calcNewM( size_t i, size_t _I ) { 83 | // calculate updated message I->i 84 | const Neighbor &I = fg().nbV(i)[_I]; 85 | Prob prod( fg().factor(I).p() ); 86 | bforeach( const Neighbor &j, fg().nbF(I) ) 87 | if( j != i ) { // for all j in I \ i 88 | Prob &n = msgN(j,j.dual); 89 | IndexFor ind( fg().var(j), fg().factor(I).vars() ); 90 | for( size_t x = 0; ind.valid(); x++, ++ind ) 91 | prod.set( x, prod[x] * n[ind] ); 92 | } 93 | // Marginalize onto i 94 | Prob marg( fg().var(i).states(), 0.0 ); 95 | // ind is the precalculated Index(i,I) i.e. to x_I == k corresponds x_i == ind[k] 96 | IndexFor ind( fg().var(i), fg().factor(I).vars() ); 97 | for( size_t x = 0; ind.valid(); x++, ++ind ) 98 | marg.set( ind, marg[ind] + prod[x] ); 99 | 100 | _msgs.Zm[i][_I] = marg.normalize(); 101 | _msgs.m[i][_I] = marg; 102 | } 103 | 104 | 105 | void BP_dual::calcNewN( size_t i, size_t _I ) { 106 | // calculate updated message i->I 107 | const Neighbor &I = fg().nbV(i)[_I]; 108 | Prob prod( fg().var(i).states(), 1.0 ); 109 | bforeach( const Neighbor &J, fg().nbV(i) ) 110 | if( J.node != I.node ) // for all J in i \ I 111 | prod *= msgM(i,J.iter); 112 | _msgs.Zn[i][_I] = prod.normalize(); 113 | _msgs.n[i][_I] = prod; 114 | } 115 | 116 | 117 | void BP_dual::calcBeliefs() { 118 | for( size_t i = 0; i < fg().nrVars(); i++ ) 119 | calcBeliefV(i); // calculate b_i 120 | for( size_t I = 0; I < fg().nrFactors(); I++ ) 121 | calcBeliefF(I); // calculate b_I 122 | } 123 | 124 | 125 | void BP_dual::calcBeliefV( size_t i ) { 126 | Prob prod( fg().var(i).states(), 1.0 ); 127 | bforeach( const Neighbor &I, fg().nbV(i) ) 128 | prod *= msgM(i,I.iter); 129 | _beliefs.Zb1[i] = prod.normalize(); 130 | _beliefs.b1[i] = prod; 131 | } 132 | 133 | 134 | void BP_dual::calcBeliefF( size_t I ) { 135 | Prob prod( fg().factor(I).p() ); 136 | bforeach( const Neighbor &j, fg().nbF(I) ) { 137 | IndexFor ind( fg().var(j), fg().factor(I).vars() ); 138 | Prob n( msgN(j,j.dual) ); 139 | for( size_t x = 0; ind.valid(); x++, ++ind ) 140 | prod.set( x, prod[x] * n[ind] ); 141 | } 142 | _beliefs.Zb2[I] = prod.normalize(); 143 | _beliefs.b2[I] = prod; 144 | } 145 | 146 | 147 | } // end of namespace dai 148 | -------------------------------------------------------------------------------- /src/clustergraph.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | namespace dai { 17 | 18 | 19 | using namespace std; 20 | 21 | 22 | ClusterGraph::ClusterGraph( const std::vector & cls ) : _G(), _vars(), _clusters() { 23 | // construct vars, clusters and edge list 24 | vector edges; 25 | bforeach( const VarSet &cl, cls ) { 26 | if( find( clusters().begin(), clusters().end(), cl ) == clusters().end() ) { 27 | // add cluster 28 | size_t n2 = nrClusters(); 29 | _clusters.push_back( cl ); 30 | for( VarSet::const_iterator n = cl.begin(); n != cl.end(); n++ ) { 31 | size_t n1 = find( vars().begin(), vars().end(), *n ) - vars().begin(); 32 | if( n1 == nrVars() ) 33 | // add variable 34 | _vars.push_back( *n ); 35 | edges.push_back( Edge( n1, n2 ) ); 36 | } 37 | } // disregard duplicate clusters 38 | } 39 | 40 | // Create bipartite graph 41 | _G.construct( nrVars(), nrClusters(), edges.begin(), edges.end() ); 42 | } 43 | 44 | 45 | ClusterGraph::ClusterGraph( const FactorGraph& fg, bool onlyMaximal ) : _G( fg.nrVars(), 0 ), _vars(), _clusters() { 46 | // copy variables 47 | _vars.reserve( fg.nrVars() ); 48 | for( size_t i = 0; i < fg.nrVars(); i++ ) 49 | _vars.push_back( fg.var(i) ); 50 | 51 | if( onlyMaximal ) { 52 | for( size_t I = 0; I < fg.nrFactors(); I++ ) 53 | if( fg.isMaximal( I ) ) { 54 | _clusters.push_back( fg.factor(I).vars() ); 55 | size_t clind = _G.addNode2(); 56 | bforeach( const Neighbor &i, fg.nbF(I) ) 57 | _G.addEdge( i, clind, true ); 58 | } 59 | } else { 60 | // copy clusters 61 | _clusters.reserve( fg.nrFactors() ); 62 | for( size_t I = 0; I < fg.nrFactors(); I++ ) 63 | _clusters.push_back( fg.factor(I).vars() ); 64 | // copy bipartite graph 65 | _G = fg.bipGraph(); 66 | } 67 | } 68 | 69 | 70 | size_t sequentialVariableElimination::operator()( const ClusterGraph &cl, const std::set &/*remainingVars*/ ) { 71 | return cl.findVar( seq.at(i++) ); 72 | } 73 | 74 | 75 | size_t greedyVariableElimination::operator()( const ClusterGraph &cl, const std::set &remainingVars ) { 76 | set::const_iterator lowest = remainingVars.end(); 77 | size_t lowest_cost = -1UL; 78 | for( set::const_iterator i = remainingVars.begin(); i != remainingVars.end(); i++ ) { 79 | size_t cost = heuristic( cl, *i ); 80 | if( lowest == remainingVars.end() || lowest_cost > cost ) { 81 | lowest = i; 82 | lowest_cost = cost; 83 | } 84 | } 85 | return *lowest; 86 | } 87 | 88 | 89 | size_t eliminationCost_MinNeighbors( const ClusterGraph &cl, size_t i ) { 90 | return cl.bipGraph().delta1( i ).size(); 91 | } 92 | 93 | 94 | size_t eliminationCost_MinWeight( const ClusterGraph &cl, size_t i ) { 95 | SmallSet id_n = cl.bipGraph().delta1( i ); 96 | 97 | size_t cost = 1; 98 | for( SmallSet::const_iterator it = id_n.begin(); it != id_n.end(); it++ ) 99 | cost *= cl.vars()[*it].states(); 100 | 101 | return cost; 102 | } 103 | 104 | 105 | size_t eliminationCost_MinFill( const ClusterGraph &cl, size_t i ) { 106 | SmallSet id_n = cl.bipGraph().delta1( i ); 107 | 108 | size_t cost = 0; 109 | // for each unordered pair {i1,i2} adjacent to n 110 | for( SmallSet::const_iterator it1 = id_n.begin(); it1 != id_n.end(); it1++ ) 111 | for( SmallSet::const_iterator it2 = it1; it2 != id_n.end(); it2++ ) 112 | if( it1 != it2 ) { 113 | // if i1 and i2 are not adjacent, eliminating n would make them adjacent 114 | if( !cl.adj(*it1, *it2) ) 115 | cost++; 116 | } 117 | 118 | return cost; 119 | } 120 | 121 | 122 | size_t eliminationCost_WeightedMinFill( const ClusterGraph &cl, size_t i ) { 123 | SmallSet id_n = cl.bipGraph().delta1( i ); 124 | 125 | size_t cost = 0; 126 | // for each unordered pair {i1,i2} adjacent to n 127 | for( SmallSet::const_iterator it1 = id_n.begin(); it1 != id_n.end(); it1++ ) 128 | for( SmallSet::const_iterator it2 = it1; it2 != id_n.end(); it2++ ) 129 | if( it1 != it2 ) { 130 | // if i1 and i2 are not adjacent, eliminating n would make them adjacent 131 | if( !cl.adj(*it1, *it2) ) 132 | cost += cl.vars()[*it1].states() * cl.vars()[*it2].states(); 133 | } 134 | 135 | return cost; 136 | } 137 | 138 | 139 | } // end of namespace dai 140 | -------------------------------------------------------------------------------- /src/decmap.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | 12 | namespace dai { 13 | 14 | 15 | using namespace std; 16 | 17 | 18 | void DecMAP::setProperties( const PropertySet &opts ) { 19 | DAI_ASSERT( opts.hasKey("ianame") ); 20 | DAI_ASSERT( opts.hasKey("iaopts") ); 21 | 22 | props.ianame = opts.getStringAs("ianame"); 23 | props.iaopts = opts.getStringAs("iaopts"); 24 | if( opts.hasKey("verbose") ) 25 | props.verbose = opts.getStringAs("verbose"); 26 | else 27 | props.verbose = 0; 28 | if( opts.hasKey("reinit") ) 29 | props.reinit = opts.getStringAs("reinit"); 30 | else 31 | props.reinit = true; 32 | } 33 | 34 | 35 | PropertySet DecMAP::getProperties() const { 36 | PropertySet opts; 37 | opts.set( "verbose", props.verbose ); 38 | opts.set( "reinit", props.reinit ); 39 | opts.set( "ianame", props.ianame ); 40 | opts.set( "iaopts", props.iaopts ); 41 | return opts; 42 | } 43 | 44 | 45 | string DecMAP::printProperties() const { 46 | stringstream s( stringstream::out ); 47 | s << "["; 48 | s << "verbose=" << props.verbose << ","; 49 | s << "reinit=" << props.reinit << ","; 50 | s << "ianame=" << props.ianame << ","; 51 | s << "iaopts=" << props.iaopts << "]"; 52 | return s.str(); 53 | } 54 | 55 | 56 | DecMAP::DecMAP( const FactorGraph& fg, const PropertySet& opts ) : DAIAlgFG(fg), _state(), _logp(), _maxdiff(), _iters(), props() { 57 | setProperties( opts ); 58 | 59 | _state = vector( nrVars(), 0 ); 60 | _logp = -INFINITY; 61 | } 62 | 63 | 64 | Factor DecMAP::belief( const VarSet& vs ) const { 65 | if( vs.size() == 0 ) 66 | return Factor(); 67 | else { 68 | map state; 69 | for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) 70 | state[*v] = _state[findVar(*v)]; 71 | return createFactorDelta( vs, calcLinearState( vs, state ) ); 72 | } 73 | } 74 | 75 | 76 | Factor DecMAP::beliefV( size_t i ) const { 77 | return createFactorDelta( var(i), _state[i] ); 78 | } 79 | 80 | 81 | vector DecMAP::beliefs() const { 82 | vector result; 83 | for( size_t i = 0; i < nrVars(); ++i ) 84 | result.push_back( beliefV(i) ); 85 | for( size_t I = 0; I < nrFactors(); ++I ) 86 | result.push_back( beliefF(I) ); 87 | return result; 88 | } 89 | 90 | 91 | Real DecMAP::run() { 92 | if( props.verbose >= 1 ) 93 | cerr << "Starting " << identify() << "..."; 94 | if( props.verbose >= 2 ) 95 | cerr << endl; 96 | 97 | // the variables which have not been clamped yet 98 | SmallSet freeVars; 99 | for( size_t i = 0; i < nrVars(); i++ ) 100 | freeVars |= i; 101 | 102 | // prepare the inference algorithm object 103 | InfAlg *clamped = newInfAlg( props.ianame, fg(), props.iaopts ); 104 | 105 | // decimate until no free variables remain 106 | while( freeVars.size() ) { 107 | Real md = clamped->run(); 108 | if( md > _maxdiff ) 109 | _maxdiff = md; 110 | _iters += clamped->Iterations(); 111 | 112 | // store the variables that need initialization 113 | VarSet varsToInit; 114 | SmallSet varsToClamp; 115 | 116 | // schedule clamping for the free variables with zero entropy 117 | for( SmallSet::const_iterator it = freeVars.begin(); it != freeVars.end(); ) { 118 | if( clamped->beliefV( *it ).entropy() == 0.0 ) { 119 | // this variable should be clamped 120 | varsToInit |= var( *it ); 121 | varsToClamp |= *it; 122 | _state[*it] = clamped->beliefV( *it ).p().argmax().first; 123 | freeVars.erase( *it ); 124 | } else 125 | it++; 126 | } 127 | 128 | // find the free factor with lowest entropy 129 | size_t bestI = 0; 130 | Real bestEnt = INFINITY; 131 | for( size_t I = 0; I < nrFactors(); I++ ) { 132 | // check if the factor is still free 133 | if( freeVars.intersects( bipGraph().nb2Set(I) ) ) { 134 | Real EntI = clamped->beliefF(I).entropy(); 135 | if( EntI < bestEnt ) { 136 | bestI = I; 137 | bestEnt = EntI; 138 | } 139 | } 140 | } 141 | 142 | // schedule clamping for the factor with lowest entropy 143 | vector Istate(1,0); 144 | Istate[0] = clamped->beliefF(bestI).p().argmax().first; 145 | map Istatemap = calcState( factor(bestI).vars(), Istate[0] ); 146 | bforeach( size_t i, bipGraph().nb2Set(bestI) & freeVars ) { 147 | varsToInit |= var(i); 148 | varsToClamp |= i; 149 | _state[i] = Istatemap[var(i)]; 150 | freeVars.erase(i); 151 | } 152 | 153 | // clamp all variables scheduled for clamping 154 | bforeach( size_t i, varsToClamp ) 155 | clamped->clamp( i, _state[i], false ); 156 | 157 | // initialize clamped for the next run 158 | if( props.reinit ) 159 | clamped->init(); 160 | else 161 | clamped->init( varsToInit ); 162 | } 163 | 164 | // calculate MAP state 165 | map state; 166 | for( size_t i = 0; i < nrVars(); i++ ) 167 | state[var(i)] = _state[i]; 168 | _logp = 0.0; 169 | for( size_t I = 0; I < nrFactors(); I++ ) 170 | _logp += dai::log( factor(I)[calcLinearState( factor(I).vars(), state )] ); 171 | 172 | // clean up 173 | delete clamped; 174 | 175 | return _maxdiff; 176 | } 177 | 178 | 179 | } // end of namespace dai 180 | -------------------------------------------------------------------------------- /src/evidence.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | namespace dai { 19 | 20 | 21 | void Evidence::addEvidenceTabFile( std::istream &is, FactorGraph &fg ) { 22 | std::map varMap; 23 | for( std::vector::const_iterator v = fg.vars().begin(); v != fg.vars().end(); ++v ) { 24 | std::stringstream s; 25 | s << v->label(); 26 | varMap[s.str()] = *v; 27 | } 28 | 29 | addEvidenceTabFile( is, varMap ); 30 | } 31 | 32 | 33 | void Evidence::addEvidenceTabFile( std::istream &is, std::map &varMap ) { 34 | std::string line; 35 | getline( is, line ); 36 | size_t line_number = 2; 37 | 38 | // Parse header 39 | std::vector header_fields; 40 | header_fields = tokenizeString( line, true ); 41 | std::vector::const_iterator p_field = header_fields.begin(); 42 | if( p_field == header_fields.end() ) 43 | DAI_THROWE(INVALID_EVIDENCE_FILE,"Empty header line"); 44 | 45 | std::vector vars; 46 | for( ; p_field != header_fields.end(); ++p_field ) { 47 | std::map::iterator elem = varMap.find( *p_field ); 48 | if( elem == varMap.end() ) 49 | DAI_THROWE(INVALID_EVIDENCE_FILE,"Variable " + *p_field + " not known"); 50 | vars.push_back( elem->second ); 51 | } 52 | 53 | getline(is,line); 54 | if( is.fail() || line.size() > 0 ) 55 | DAI_THROWE(INVALID_EVIDENCE_FILE,"Expecting empty line"); 56 | 57 | // Read samples 58 | while( getline(is, line) ) { 59 | line_number++; 60 | 61 | std::vector fields; 62 | fields = tokenizeString( line, true, "\t" ); 63 | if( fields.size() != vars.size() ) 64 | DAI_THROWE(INVALID_EVIDENCE_FILE,"Invalid number of fields in line " + boost::lexical_cast(line_number)); 65 | 66 | Observation sample; 67 | for( size_t i = 0; i < vars.size(); ++i ) { 68 | if( fields[i].size() > 0 ) { // skip if missing observation 69 | if( fields[i].find_first_not_of("0123456789") != std::string::npos ) 70 | DAI_THROWE(INVALID_EVIDENCE_FILE,"Invalid state " + fields[i] + " in line " + boost::lexical_cast(line_number)); 71 | size_t state = fromString( fields[i].c_str() ); 72 | if( state >= vars[i].states() ) 73 | DAI_THROWE(INVALID_EVIDENCE_FILE,"State " + fields[i] + " too large in line " + boost::lexical_cast(line_number)); 74 | sample[vars[i]] = state; 75 | } 76 | } 77 | _samples.push_back( sample ); 78 | } // finished sample line 79 | } 80 | 81 | 82 | } // end of namespace dai 83 | -------------------------------------------------------------------------------- /src/exactinf.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | namespace dai { 14 | 15 | 16 | using namespace std; 17 | 18 | 19 | void ExactInf::setProperties( const PropertySet &opts ) { 20 | if( opts.hasKey("verbose") ) 21 | props.verbose = opts.getStringAs("verbose"); 22 | else 23 | props.verbose = 0; 24 | } 25 | 26 | 27 | PropertySet ExactInf::getProperties() const { 28 | PropertySet opts; 29 | opts.set( "verbose", props.verbose ); 30 | return opts; 31 | } 32 | 33 | 34 | string ExactInf::printProperties() const { 35 | stringstream s( stringstream::out ); 36 | s << "["; 37 | s << "verbose=" << props.verbose << "]"; 38 | return s.str(); 39 | } 40 | 41 | 42 | void ExactInf::construct() { 43 | // clear variable beliefs and reserve space 44 | _beliefsV.clear(); 45 | _beliefsV.reserve( nrVars() ); 46 | for( size_t i = 0; i < nrVars(); i++ ) 47 | _beliefsV.push_back( Factor( var(i) ) ); 48 | 49 | // clear factor beliefs and reserve space 50 | _beliefsF.clear(); 51 | _beliefsF.reserve( nrFactors() ); 52 | for( size_t I = 0; I < nrFactors(); I++ ) 53 | _beliefsF.push_back( Factor( factor(I).vars() ) ); 54 | } 55 | 56 | 57 | void ExactInf::init() { 58 | for( size_t i = 0; i < nrVars(); i++ ) 59 | _beliefsV[i].fill( 1.0 ); 60 | for( size_t I = 0; I < nrFactors(); I++ ) 61 | _beliefsF[I].fill( 1.0 ); 62 | } 63 | 64 | 65 | Real ExactInf::run() { 66 | if( props.verbose >= 1 ) 67 | cerr << "Starting " << identify() << "..."; 68 | 69 | Factor P; 70 | for( size_t I = 0; I < nrFactors(); I++ ) 71 | P *= factor(I); 72 | 73 | Real Z = P.sum(); 74 | _logZ = std::log(Z); 75 | for( size_t i = 0; i < nrVars(); i++ ) 76 | _beliefsV[i] = P.marginal(var(i)); 77 | for( size_t I = 0; I < nrFactors(); I++ ) 78 | _beliefsF[I] = P.marginal(factor(I).vars()); 79 | 80 | if( props.verbose >= 1 ) 81 | cerr << "finished" << endl; 82 | 83 | return 0.0; 84 | } 85 | 86 | 87 | Factor ExactInf::calcMarginal( const VarSet &vs ) const { 88 | Factor P; 89 | for( size_t I = 0; I < nrFactors(); I++ ) 90 | P *= factor(I); 91 | return P.marginal( vs, true ); 92 | } 93 | 94 | 95 | std::vector ExactInf::findMaximum() const { 96 | Factor P; 97 | for( size_t I = 0; I < nrFactors(); I++ ) 98 | P *= factor(I); 99 | size_t linearState = P.p().argmax().first; 100 | 101 | // convert to state 102 | map state = calcState( P.vars(), linearState ); 103 | 104 | // convert to desired output data structure 105 | vector mapState; 106 | mapState.reserve( nrVars() ); 107 | for( size_t i = 0; i < nrVars(); i++ ) 108 | mapState.push_back( state[var(i)] ); 109 | 110 | return mapState; 111 | } 112 | 113 | 114 | vector ExactInf::beliefs() const { 115 | vector result = _beliefsV; 116 | result.insert( result.end(), _beliefsF.begin(), _beliefsF.end() ); 117 | return result; 118 | } 119 | 120 | 121 | Factor ExactInf::belief( const VarSet &ns ) const { 122 | if( ns.size() == 0 ) 123 | return Factor(); 124 | else if( ns.size() == 1 ) { 125 | return beliefV( findVar( *(ns.begin()) ) ); 126 | } else { 127 | size_t I; 128 | for( I = 0; I < nrFactors(); I++ ) 129 | if( factor(I).vars() >> ns ) 130 | break; 131 | if( I == nrFactors() ) 132 | DAI_THROW(BELIEF_NOT_AVAILABLE); 133 | return beliefF(I).marginal(ns); 134 | } 135 | } 136 | 137 | 138 | } // end of namespace dai 139 | -------------------------------------------------------------------------------- /src/exceptions.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | 12 | namespace dai { 13 | 14 | 15 | std::string Exception::ErrorStrings[NUM_ERRORS] = { 16 | "Feature not implemented", 17 | "Assertion failed", 18 | "Impossible typecast", 19 | "Requested object not found", 20 | "Requested belief not available", 21 | "Unknown ENUM value", 22 | "Unknown DAI algorithm", 23 | "Unrecognized parameter estimation method", 24 | "Unknown Property type", 25 | "Unknown Property", 26 | "Malformed Property", 27 | "Not all mandatory Properties specified", 28 | "Invalid alias", 29 | "Cannot read file", 30 | "Cannot write file", 31 | "Invalid FactorGraph file", 32 | "Invalid Evidence file", 33 | "Invalid Expectation-Maximization file", 34 | "Quantity not normalizable", 35 | "Multiple undo levels unsupported", 36 | "FactorGraph is not connected", 37 | "Internal error", 38 | "Runtime error", 39 | "Out of memory" 40 | }; 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/factor.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | 12 | namespace dai { 13 | 14 | 15 | using namespace std; 16 | 17 | 18 | Factor createFactorIsing( const Var &n, Real h ) { 19 | DAI_ASSERT( n.states() == 2 ); 20 | Real buf[2]; 21 | buf[0] = std::exp(-h); 22 | buf[1] = std::exp(h); 23 | return Factor(n, &buf[0]); 24 | } 25 | 26 | 27 | Factor createFactorIsing( const Var &n1, const Var &n2, Real J ) { 28 | DAI_ASSERT( n1.states() == 2 ); 29 | DAI_ASSERT( n2.states() == 2 ); 30 | DAI_ASSERT( n1 != n2 ); 31 | Real buf[4]; 32 | buf[0] = (buf[3] = std::exp(J)); 33 | buf[1] = (buf[2] = std::exp(-J)); 34 | return Factor( VarSet(n1, n2), &buf[0] ); 35 | } 36 | 37 | 38 | Factor createFactorExpGauss( const VarSet &ns, Real beta ) { 39 | Factor fac( ns ); 40 | for( size_t t = 0; t < fac.nrStates(); t++ ) 41 | fac.set( t, std::exp(rnd_stdnormal() * beta) ); 42 | return fac; 43 | } 44 | 45 | 46 | Factor createFactorPotts( const Var &n1, const Var &n2, Real J ) { 47 | Factor fac( VarSet( n1, n2 ), 1.0 ); 48 | DAI_ASSERT( n1.states() == n2.states() ); 49 | for( size_t s = 0; s < n1.states(); s++ ) 50 | fac.set( s * (n1.states() + 1), std::exp(J) ); 51 | return fac; 52 | } 53 | 54 | 55 | Factor createFactorDelta( const Var &v, size_t state ) { 56 | Factor fac( v, 0.0 ); 57 | DAI_ASSERT( state < v.states() ); 58 | fac.set( state, 1.0 ); 59 | return fac; 60 | } 61 | 62 | 63 | Factor createFactorDelta( const VarSet& vs, size_t state ) { 64 | Factor fac( vs, 0.0 ); 65 | DAI_ASSERT( state < vs.nrStates() ); 66 | fac.set( state, 1.0 ); 67 | return fac; 68 | } 69 | 70 | 71 | } // end of namespace dai 72 | -------------------------------------------------------------------------------- /src/fbp.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | 12 | #define DAI_FBP_FAST 1 13 | 14 | 15 | namespace dai { 16 | 17 | 18 | using namespace std; 19 | 20 | 21 | // This code has been copied from bp.cpp, except where comments indicate FBP-specific behaviour 22 | Real FBP::logZ() const { 23 | Real sum = 0.0; 24 | for( size_t I = 0; I < nrFactors(); I++ ) { 25 | sum += (beliefF(I) * factor(I).log(true)).sum(); // FBP 26 | sum += Weight(I) * beliefF(I).entropy(); // FBP 27 | } 28 | for( size_t i = 0; i < nrVars(); ++i ) { 29 | Real c_i = 0.0; 30 | bforeach( const Neighbor &I, nbV(i) ) 31 | c_i += Weight(I); 32 | if( c_i != 1.0 ) 33 | sum += (1.0 - c_i) * beliefV(i).entropy(); // FBP 34 | } 35 | return sum; 36 | } 37 | 38 | 39 | // This code has been copied from bp.cpp, except where comments indicate FBP-specific behaviour 40 | Prob FBP::calcIncomingMessageProduct( size_t I, bool without_i, size_t i ) const { 41 | Real c_I = Weight(I); // FBP: c_I 42 | 43 | Factor Fprod( factor(I) ); 44 | Prob &prod = Fprod.p(); 45 | 46 | if( props.logdomain ) { 47 | prod.takeLog(); 48 | prod /= c_I; // FBP 49 | } else 50 | prod ^= (1.0 / c_I); // FBP 51 | 52 | // Calculate product of incoming messages and factor I 53 | bforeach( const Neighbor &j, nbF(I) ) 54 | if( !(without_i && (j == i)) ) { 55 | // prod_j will be the product of messages coming into j 56 | // FBP: corresponds to messages n_jI 57 | Prob prod_j( var(j).states(), props.logdomain ? 0.0 : 1.0 ); 58 | bforeach( const Neighbor &J, nbV(j) ) 59 | if( J != I ) { // for all J in nb(j) \ I 60 | if( props.logdomain ) 61 | prod_j += message( j, J.iter ); 62 | else 63 | prod_j *= message( j, J.iter ); 64 | } else if( c_I != 1.0 ) { 65 | // FBP: multiply by m_Ij^(1-1/c_I) 66 | if( props.logdomain ) 67 | prod_j += newMessage( j, J.iter) * (1.0 - 1.0 / c_I); 68 | else 69 | prod_j *= newMessage( j, J.iter) ^ (1.0 - 1.0 / c_I); 70 | } 71 | 72 | // multiply prod with prod_j 73 | if( !DAI_FBP_FAST ) { 74 | // UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION 75 | if( props.logdomain ) 76 | Fprod += Factor( var(j), prod_j ); 77 | else 78 | Fprod *= Factor( var(j), prod_j ); 79 | } else { 80 | // OPTIMIZED VERSION 81 | size_t _I = j.dual; 82 | // ind is the precalculated IndexFor(j,I) i.e. to x_I == k corresponds x_j == ind[k] 83 | const ind_t &ind = index(j, _I); 84 | 85 | for( size_t r = 0; r < prod.size(); ++r ) 86 | if( props.logdomain ) 87 | prod.set( r, prod[r] + prod_j[ind[r]] ); 88 | else 89 | prod.set( r, prod[r] * prod_j[ind[r]] ); 90 | } 91 | } 92 | return prod; 93 | } 94 | 95 | 96 | // This code has been copied from bp.cpp, except where comments indicate FBP-specific behaviour 97 | void FBP::calcNewMessage( size_t i, size_t _I ) { 98 | // calculate updated message I->i 99 | size_t I = nbV(i,_I); 100 | 101 | Real c_I = Weight(I); // FBP: c_I 102 | 103 | Factor Fprod( factor(I) ); 104 | Prob &prod = Fprod.p(); 105 | prod = calcIncomingMessageProduct( I, true, i ); 106 | 107 | if( props.logdomain ) { 108 | prod -= prod.max(); 109 | prod.takeExp(); 110 | } 111 | 112 | // Marginalize onto i 113 | Prob marg; 114 | if( !DAI_FBP_FAST ) { 115 | // UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION 116 | if( props.inference == Properties::InfType::SUMPROD ) 117 | marg = Fprod.marginal( var(i) ).p(); 118 | else 119 | marg = Fprod.maxMarginal( var(i) ).p(); 120 | } else { 121 | // OPTIMIZED VERSION 122 | marg = Prob( var(i).states(), 0.0 ); 123 | // ind is the precalculated IndexFor(i,I) i.e. to x_I == k corresponds x_i == ind[k] 124 | const ind_t ind = index(i,_I); 125 | if( props.inference == Properties::InfType::SUMPROD ) 126 | for( size_t r = 0; r < prod.size(); ++r ) 127 | marg.set( ind[r], marg[ind[r]] + prod[r] ); 128 | else 129 | for( size_t r = 0; r < prod.size(); ++r ) 130 | if( prod[r] > marg[ind[r]] ) 131 | marg.set( ind[r], prod[r] ); 132 | marg.normalize(); 133 | } 134 | 135 | // FBP 136 | marg ^= c_I; 137 | 138 | // Store result 139 | if( props.logdomain ) 140 | newMessage(i,_I) = marg.log(); 141 | else 142 | newMessage(i,_I) = marg; 143 | 144 | // Update the residual if necessary 145 | if( props.updates == Properties::UpdateType::SEQMAX ) 146 | updateResidual( i, _I , dist( newMessage( i, _I ), message( i, _I ), DISTLINF ) ); 147 | } 148 | 149 | 150 | void FBP::construct() { 151 | BP::construct(); 152 | _weight.resize( nrFactors(), 1.0 ); 153 | } 154 | 155 | 156 | } // end of namespace dai 157 | -------------------------------------------------------------------------------- /src/matlab/dai.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include "mex.h" 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | using namespace std; 18 | using namespace dai; 19 | 20 | 21 | /* Input Arguments */ 22 | 23 | #define PSI_IN prhs[0] 24 | #define METHOD_IN prhs[1] 25 | #define OPTS_IN prhs[2] 26 | #define NR_IN 3 27 | #define NR_IN_OPT 0 28 | 29 | 30 | /* Output Arguments */ 31 | 32 | #define LOGZ_OUT plhs[0] 33 | #define Q_OUT plhs[1] 34 | #define MD_OUT plhs[2] 35 | #define QV_OUT plhs[3] 36 | #define QF_OUT plhs[4] 37 | #define QMAP_OUT plhs[5] 38 | #define NR_OUT 3 39 | #define NR_OUT_OPT 3 40 | 41 | 42 | void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { 43 | size_t buflen; 44 | 45 | // Check for proper number of arguments 46 | if( ((nrhs < NR_IN) || (nrhs > NR_IN + NR_IN_OPT)) || ((nlhs < NR_OUT) || (nlhs > NR_OUT + NR_OUT_OPT)) ) { 47 | mexErrMsgTxt("Usage: [logZ,q,md,qv,qf,qmap] = dai(psi,method,opts)\n\n" 48 | "\n" 49 | "INPUT: psi = linear cell array containing the factors\n" 50 | " (psi{i} should be a structure with a Member field\n" 51 | " and a P field).\n" 52 | " method = name of the method\n" 53 | " opts = string of options\n" 54 | "\n" 55 | "OUTPUT: logZ = approximation of the logarithm of the partition sum.\n" 56 | " q = linear cell array containing all final beliefs.\n" 57 | " md = maxdiff (final linf-dist between new and old single node beliefs).\n" 58 | " qv = linear cell array containing all variable beliefs.\n" 59 | " qf = linear cell array containing all factor beliefs.\n" 60 | " qmap = linear array containing the MAP state (only for BP,JTree).\n"); 61 | } 62 | 63 | char *method; 64 | char *opts; 65 | 66 | 67 | // Get psi and construct factorgraph 68 | vector factors = mx2Factors(PSI_IN, 0); 69 | FactorGraph fg(factors); 70 | 71 | // Get method 72 | buflen = mxGetN( METHOD_IN ) + 1; 73 | method = (char *)mxCalloc( buflen, sizeof(char) ); 74 | mxGetString( METHOD_IN, method, buflen ); 75 | 76 | // Get options string 77 | buflen = mxGetN( OPTS_IN ) + 1; 78 | opts = (char *)mxCalloc( buflen, sizeof(char) ); 79 | mxGetString( OPTS_IN, opts, buflen ); 80 | // Convert to options object props 81 | stringstream ss; 82 | ss << opts; 83 | PropertySet props; 84 | ss >> props; 85 | 86 | // Construct InfAlg object, init and run 87 | InfAlg *obj = newInfAlg( method, fg, props ); 88 | obj->init(); 89 | obj->run(); 90 | 91 | // Save logZ 92 | double logZ = NAN; 93 | try { 94 | logZ = obj->logZ(); 95 | } 96 | catch( Exception &e ) { 97 | if( e.getCode() == Exception::NOT_IMPLEMENTED ) 98 | mexWarnMsgTxt("Calculating the log-partition function is not supported by this inference algorithm."); 99 | else 100 | throw; 101 | } 102 | 103 | // Save maxdiff 104 | double maxdiff = NAN; 105 | try { 106 | maxdiff = obj->maxDiff(); 107 | } 108 | catch( Exception &e ) { 109 | if( e.getCode() == Exception::NOT_IMPLEMENTED ) 110 | mexWarnMsgTxt("Calculating the max-differences is not supported by this inference algorithm."); 111 | else 112 | throw; 113 | } 114 | 115 | // Hand over results to MATLAB 116 | LOGZ_OUT = mxCreateDoubleMatrix(1,1,mxREAL); 117 | *(mxGetPr(LOGZ_OUT)) = logZ; 118 | 119 | Q_OUT = Factors2mx(obj->beliefs()); 120 | 121 | MD_OUT = mxCreateDoubleMatrix(1,1,mxREAL); 122 | *(mxGetPr(MD_OUT)) = maxdiff; 123 | 124 | if( nlhs >= 4 ) { 125 | vector qv; 126 | qv.reserve( fg.nrVars() ); 127 | for( size_t i = 0; i < fg.nrVars(); i++ ) 128 | qv.push_back( obj->belief( fg.var(i) ) ); 129 | QV_OUT = Factors2mx( qv ); 130 | } 131 | 132 | if( nlhs >= 5 ) { 133 | vector qf; 134 | qf.reserve( fg.nrFactors() ); 135 | for( size_t I = 0; I < fg.nrFactors(); I++ ) 136 | qf.push_back( obj->belief( fg.factor(I).vars() ) ); 137 | QF_OUT = Factors2mx( qf ); 138 | } 139 | 140 | if( nlhs >= 6 ) { 141 | std::vector map_state; 142 | bool supported = true; 143 | try { 144 | map_state = obj->findMaximum(); 145 | } catch( Exception &e ) { 146 | if( e.getCode() == Exception::NOT_IMPLEMENTED ) 147 | supported = false; 148 | else 149 | throw; 150 | } 151 | if( supported ) { 152 | QMAP_OUT = mxCreateNumericMatrix(map_state.size(), 1, mxUINT32_CLASS, mxREAL); 153 | uint32_T* qmap_p = reinterpret_cast(mxGetPr(QMAP_OUT)); 154 | for (size_t n = 0; n < map_state.size(); ++n) 155 | qmap_p[n] = map_state[n]; 156 | } else { 157 | delete obj; 158 | mexErrMsgTxt("Calculating a MAP state is not supported by this inference algorithm."); 159 | } 160 | } 161 | 162 | delete obj; 163 | 164 | return; 165 | } 166 | -------------------------------------------------------------------------------- /src/matlab/dai_potstrength.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include "mex.h" 11 | #include 12 | #include 13 | 14 | 15 | using namespace std; 16 | using namespace dai; 17 | 18 | 19 | /* Input Arguments */ 20 | 21 | #define PSI_IN prhs[0] 22 | #define I_IN prhs[1] 23 | #define J_IN prhs[2] 24 | #define NR_IN 3 25 | 26 | 27 | /* Output Arguments */ 28 | 29 | #define N_OUT plhs[0] 30 | #define NR_OUT 1 31 | 32 | 33 | void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { 34 | size_t ilabel, jlabel; 35 | 36 | // Check for proper number of arguments 37 | if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 38 | mexErrMsgTxt("Usage: N = dai_potstrength(psi,i,j);\n\n" 39 | "\n" 40 | "INPUT: psi = structure with a Member field and a P field, like a CPTAB.\n" 41 | " i = label of a variable in psi.\n" 42 | " j = label of another variable in psi.\n" 43 | "\n" 44 | "OUTPUT: N = strength of psi in direction i->j.\n"); 45 | } 46 | 47 | // Get input parameters 48 | Factor psi = mx2Factor(PSI_IN); 49 | ilabel = (size_t)*mxGetPr(I_IN); 50 | jlabel = (size_t)*mxGetPr(J_IN); 51 | 52 | // Find variable in psi with label ilabel 53 | Var i; 54 | for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ ) 55 | if( n->label() == ilabel ) { 56 | i = *n; 57 | break; 58 | } 59 | DAI_ASSERT( i.label() == ilabel ); 60 | 61 | // Find variable in psi with label jlabel 62 | Var j; 63 | for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ ) 64 | if( n->label() == jlabel ) { 65 | j = *n; 66 | break; 67 | } 68 | DAI_ASSERT( j.label() == jlabel ); 69 | 70 | // Calculate N(psi,i,j); 71 | double N = psi.strength( i, j ); 72 | 73 | // Hand over result to MATLAB 74 | N_OUT = mxCreateDoubleMatrix(1,1,mxREAL); 75 | *(mxGetPr(N_OUT)) = N; 76 | 77 | return; 78 | } 79 | -------------------------------------------------------------------------------- /src/matlab/dai_readfg.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include "mex.h" 11 | #include 12 | #include 13 | 14 | 15 | using namespace std; 16 | using namespace dai; 17 | 18 | 19 | /* Input Arguments */ 20 | 21 | #define FILENAME_IN prhs[0] 22 | #define NR_IN 1 23 | 24 | 25 | /* Output Arguments */ 26 | 27 | #define PSI_OUT plhs[0] 28 | #define NR_OUT 1 29 | 30 | 31 | void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) { 32 | char *filename; 33 | 34 | 35 | // Check for proper number of arguments 36 | if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 37 | mexErrMsgTxt("Usage: [psi] = dai_readfg(filename);\n\n" 38 | "\n" 39 | "INPUT: filename = filename of a .fg file\n" 40 | "\n" 41 | "OUTPUT: psi = linear cell array containing the factors\n" 42 | " (psi{i} is a structure with a Member field\n" 43 | " and a P field, like a CPTAB).\n"); 44 | } 45 | 46 | // Get input parameters 47 | size_t buflen; 48 | buflen = mxGetN( FILENAME_IN ) + 1; 49 | filename = (char *)mxCalloc( buflen, sizeof(char) ); 50 | mxGetString( FILENAME_IN, filename, buflen ); 51 | 52 | 53 | // Read factorgraph 54 | FactorGraph fg; 55 | try { 56 | fg.ReadFromFile( filename ); 57 | } catch( std::exception &e ) { 58 | mexErrMsgTxt( e.what() ); 59 | } 60 | 61 | 62 | // Save factors 63 | vector psi; 64 | for( size_t I = 0; I < fg.nrFactors(); I++ ) 65 | psi.push_back(fg.factor(I)); 66 | 67 | 68 | // Hand over results to MATLAB 69 | PSI_OUT = Factors2mx(psi); 70 | 71 | 72 | return; 73 | } 74 | -------------------------------------------------------------------------------- /src/matlab/dai_writefg.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include "mex.h" 11 | #include 12 | #include 13 | 14 | 15 | using namespace std; 16 | using namespace dai; 17 | 18 | 19 | /* Input Arguments */ 20 | 21 | #define PSI_IN prhs[0] 22 | #define FILENAME_IN prhs[1] 23 | #define NR_IN 2 24 | 25 | 26 | /* Output Arguments */ 27 | 28 | #define NR_OUT 0 29 | 30 | 31 | void mexFunction( int nlhs, mxArray * /*plhs*/[], int nrhs, const mxArray*prhs[] ) { 32 | char *filename; 33 | 34 | // Check for proper number of arguments 35 | if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 36 | mexErrMsgTxt("Usage: dai_writefg(psi,filename);\n\n" 37 | "\n" 38 | "INPUT: psi = linear cell array containing the factors\n" 39 | " (psi{i} should be a structure with a Member field\n" 40 | " and a P field, like a CPTAB).\n" 41 | " filename = filename of a .fg file\n"); 42 | } 43 | 44 | // Get input parameters 45 | vector factors = mx2Factors(PSI_IN,0); 46 | 47 | size_t buflen; 48 | buflen = mxGetN( FILENAME_IN ) + 1; 49 | filename = (char *)mxCalloc( buflen, sizeof(char) ); 50 | mxGetString( FILENAME_IN, filename, buflen ); 51 | 52 | // Construct factorgraph 53 | FactorGraph fg(factors); 54 | 55 | try { 56 | fg.WriteToFile( filename ); 57 | } catch( std::exception &e ) { 58 | mexErrMsgTxt( e.what() ); 59 | } 60 | 61 | return; 62 | } 63 | -------------------------------------------------------------------------------- /src/matlab/matlab.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | namespace dai { 14 | 15 | 16 | using namespace std; 17 | 18 | 19 | /* Convert vector structure to a cell vector of CPTAB-like structs */ 20 | mxArray *Factors2mx(const vector &Ps) { 21 | size_t nr = Ps.size(); 22 | 23 | mxArray *psi = mxCreateCellMatrix(nr,1); 24 | 25 | const char *fieldnames[2]; 26 | fieldnames[0] = "Member"; 27 | fieldnames[1] = "P"; 28 | 29 | size_t I_ind = 0; 30 | for( vector::const_iterator I = Ps.begin(); I != Ps.end(); I++, I_ind++ ) { 31 | mxArray *Bi = mxCreateStructMatrix(1,1,2,fieldnames); 32 | 33 | mxArray *BiMember = mxCreateDoubleMatrix(1,I->vars().size(),mxREAL); 34 | double *BiMember_data = mxGetPr(BiMember); 35 | size_t i = 0; 36 | vector dims; 37 | for( VarSet::const_iterator j = I->vars().begin(); j != I->vars().end(); j++,i++ ) { 38 | BiMember_data[i] = j->label(); 39 | dims.push_back( j->states() ); 40 | } 41 | while( dims.size() <= 2 ) 42 | dims.push_back( 1 ); 43 | 44 | mxArray *BiP = mxCreateNumericArray(dims.size(), &(*(dims.begin())), mxDOUBLE_CLASS, mxREAL); 45 | double *BiP_data = mxGetPr(BiP); 46 | for( size_t j = 0; j < I->nrStates(); j++ ) 47 | BiP_data[j] = (*I)[j]; 48 | 49 | mxSetField(Bi,0,"Member",BiMember); 50 | mxSetField(Bi,0,"P",BiP); 51 | 52 | mxSetCell(psi, I_ind, Bi); 53 | } 54 | return( psi ); 55 | } 56 | 57 | 58 | /* Convert cell vector of CPTAB-like structs to vector */ 59 | vector mx2Factors(const mxArray *psi, long verbose) { 60 | set vars; 61 | vector factors; 62 | 63 | int n1 = mxGetM(psi); 64 | int n2 = mxGetN(psi); 65 | if( n2 != 1 && n1 != 1 ) 66 | mexErrMsgTxt("psi should be a Nx1 or 1xN cell matrix."); 67 | size_t nr_f = n1; 68 | if( n1 == 1 ) 69 | nr_f = n2; 70 | 71 | // interpret psi, linear cell array of cptabs 72 | for( size_t cellind = 0; cellind < nr_f; cellind++ ) { 73 | if( verbose >= 3 ) 74 | cerr << "reading factor " << cellind << ": " << endl; 75 | mxArray *cell = mxGetCell(psi, cellind); 76 | mxArray *mx_member = mxGetField(cell, 0, "Member"); 77 | size_t nr_mem = mxGetN(mx_member); 78 | double *members = mxGetPr(mx_member); 79 | const mwSize *dims = mxGetDimensions(mxGetField(cell,0,"P")); 80 | double *factordata = mxGetPr(mxGetField(cell, 0, "P")); 81 | 82 | // add variables 83 | VarSet factorvars; 84 | vector labels(nr_mem,0); 85 | if( verbose >= 3 ) 86 | cerr << " vars: "; 87 | for( size_t mi = 0; mi < nr_mem; mi++ ) { 88 | labels[mi] = (long)members[mi]; 89 | if( verbose >= 3 ) 90 | cerr << labels[mi] << "(" << dims[mi] << ") "; 91 | vars.insert( Var(labels[mi], dims[mi]) ); 92 | factorvars |= Var(labels[mi], dims[mi]); 93 | } 94 | factors.push_back(Factor(factorvars)); 95 | 96 | // calculate permutation matrix 97 | vector perm(nr_mem,0); 98 | VarSet::iterator j = factorvars.begin(); 99 | for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { 100 | long gezocht = j->label(); 101 | vector::iterator piet = find(labels.begin(),labels.end(),gezocht); 102 | perm[mi] = piet - labels.begin(); 103 | } 104 | 105 | if( verbose >= 3 ) { 106 | cerr << endl << " perm: "; 107 | for( vector::iterator r=perm.begin(); r!=perm.end(); r++ ) 108 | cerr << *r << " "; 109 | cerr << endl; 110 | } 111 | 112 | // read Factor 113 | vector di(nr_mem,0); 114 | size_t prod = 1; 115 | for( size_t k = 0; k < nr_mem; k++ ) { 116 | di[k] = dims[k]; 117 | prod *= dims[k]; 118 | } 119 | Permute permindex( di, perm ); 120 | for( size_t li = 0; li < prod; li++ ) 121 | factors.back().set( permindex.convertLinearIndex(li), factordata[li] ); 122 | } 123 | 124 | if( verbose >= 3 ) { 125 | for(vector::const_iterator I=factors.begin(); I!=factors.end(); I++ ) 126 | cerr << *I << endl; 127 | } 128 | 129 | return( factors ); 130 | } 131 | 132 | 133 | /* Convert CPTAB-like struct to Factor */ 134 | Factor mx2Factor(const mxArray *psi) { 135 | mxArray *mx_member = mxGetField(psi, 0, "Member"); 136 | size_t nr_mem = mxGetN(mx_member); 137 | double *members = mxGetPr(mx_member); 138 | const mwSize *dims = mxGetDimensions(mxGetField(psi,0,"P")); 139 | double *factordata = mxGetPr(mxGetField(psi, 0, "P")); 140 | 141 | // add variables 142 | VarSet vars; 143 | vector labels(nr_mem,0); 144 | for( size_t mi = 0; mi < nr_mem; mi++ ) { 145 | labels[mi] = (long)members[mi]; 146 | vars |= Var(labels[mi], dims[mi]); 147 | } 148 | Factor factor(vars); 149 | 150 | // calculate permutation matrix 151 | vector perm(nr_mem,0); 152 | VarSet::iterator j = vars.begin(); 153 | for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { 154 | long gezocht = j->label(); 155 | vector::iterator piet = find(labels.begin(),labels.end(),gezocht); 156 | perm[mi] = piet - labels.begin(); 157 | } 158 | 159 | // read Factor 160 | vector di(nr_mem,0); 161 | size_t prod = 1; 162 | for( size_t k = 0; k < nr_mem; k++ ) { 163 | di[k] = dims[k]; 164 | prod *= dims[k]; 165 | } 166 | Permute permindex( di, perm ); 167 | for( size_t li = 0; li < prod; li++ ) 168 | factor.set( permindex.convertLinearIndex(li), factordata[li] ); 169 | 170 | return( factor ); 171 | } 172 | 173 | 174 | } 175 | -------------------------------------------------------------------------------- /src/properties.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | namespace dai { 15 | 16 | 17 | std::ostream& operator<< (std::ostream & os, const Property & p) { 18 | os << p.first << "="; 19 | if( p.second.type() == typeid(size_t) ) 20 | os << boost::any_cast(p.second); 21 | else if( p.second.type() == typeid(int) ) 22 | os << boost::any_cast(p.second); 23 | else if( p.second.type() == typeid(std::string) ) 24 | os << boost::any_cast(p.second); 25 | else if( p.second.type() == typeid(double) ) 26 | os << boost::any_cast(p.second); 27 | else if( p.second.type() == typeid(long double) ) 28 | os << boost::any_cast(p.second); 29 | else if( p.second.type() == typeid(bool) ) 30 | os << boost::any_cast(p.second); 31 | else if( p.second.type() == typeid(PropertySet) ) 32 | os << boost::any_cast(p.second); 33 | else 34 | DAI_THROW(UNKNOWN_PROPERTY_TYPE); 35 | return( os ); 36 | } 37 | 38 | 39 | /// Writes a PropertySet object to an output stream 40 | std::ostream& operator<< (std::ostream & os, const PropertySet & ps) { 41 | os << "["; 42 | for( PropertySet::const_iterator p = ps.begin(); p != ps.end(); p++ ) { 43 | if( p != ps.begin() ) 44 | os << ","; 45 | os << (Property)*p; 46 | } 47 | os << "]"; 48 | return os; 49 | } 50 | 51 | 52 | /// Reads a PropertySet object from an input stream, storing values as strings 53 | std::istream& operator>> (std::istream& is, PropertySet & ps) { 54 | ps = PropertySet(); 55 | 56 | std::string s; 57 | is >> s; 58 | 59 | // Check whether s is of the form "[.*]" 60 | if( (s.length() < 2) || (s.at(0) != '[') || (s.at(s.length()-1)) != ']' ) 61 | DAI_THROWE(MALFORMED_PROPERTY,"Malformed PropertySet: " + s); 62 | 63 | size_t N = s.length() - 1; 64 | for( size_t token_start = 1; token_start < N; ) { 65 | size_t token_end; 66 | 67 | // scan until '=' is found 68 | for( token_end = token_start + 1; token_end < N; token_end++ ) 69 | if( s[token_end] == '=' ) 70 | break; 71 | // we found a key 72 | std::string key = s.substr(token_start, token_end - token_start); 73 | if( token_end == N ) 74 | DAI_THROWE(MALFORMED_PROPERTY,"Malformed Property: " + key); 75 | 76 | token_start = token_end + 1; 77 | // scan until matching ',' is found 78 | int level = 0; 79 | for( token_end = token_start; token_end < N; token_end++ ) { 80 | if( s[token_end] == '[' ) 81 | level++; 82 | else if( s[token_end] == ']' ) 83 | level--; 84 | else if( (s[token_end] == ',') && (level == 0) ) 85 | break; 86 | } 87 | if( !(level == 0) ) 88 | DAI_THROWE(MALFORMED_PROPERTY,"Malformed Property: " + s.substr(token_start, token_end - token_start)); 89 | // we found a vlue 90 | std::string value = s.substr(token_start, token_end - token_start); 91 | 92 | // store the key,value pair 93 | ps.set(key,value); 94 | 95 | // go on with the next one 96 | token_start = token_end + 1; 97 | } 98 | 99 | return is; 100 | } 101 | 102 | 103 | } // end of namespace dai 104 | -------------------------------------------------------------------------------- /src/util.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | #ifdef WINDOWS 13 | #include 14 | #include // for atanh 15 | #include // for log1p 16 | #include // for _isnan 17 | #else 18 | // Assume POSIX compliant system. We need the following for querying the system time 19 | #include 20 | #endif 21 | 22 | 23 | #ifdef WINDOWS 24 | double atanh( double x ) { 25 | return boost::math::atanh( x ); 26 | } 27 | double log1p( double x ) { 28 | return boost::math::log1p( x ); 29 | } 30 | #endif 31 | 32 | 33 | namespace dai { 34 | 35 | #if defined CYGWIN 36 | bool isnan( Real x ) { 37 | return __isnand( x ); // isnan() is a macro in Cygwin (as required by C99) 38 | } 39 | #elif defined WINDOWS 40 | bool isnan( Real x ) { 41 | return _isnan( x ); 42 | } 43 | #else 44 | bool isnan( Real x ) { 45 | return std::isnan( x ); 46 | } 47 | #endif 48 | 49 | // Returns user+system time in seconds 50 | double toc() { 51 | #ifdef WINDOWS 52 | SYSTEMTIME tbuf; 53 | GetSystemTime(&tbuf); 54 | return( (double)(tbuf.wSecond + (double)tbuf.wMilliseconds / 1000.0) ); 55 | #else 56 | struct timeval tv; 57 | struct timezone tz; 58 | gettimeofday( &tv, &tz ); 59 | return( (double)(tv.tv_sec + (double)tv.tv_usec / 1000000.0) ); 60 | #endif 61 | } 62 | 63 | /// Type of global random number generator 64 | typedef boost::mt19937 _rnd_gen_type; 65 | 66 | /// Global random number generator 67 | _rnd_gen_type _rnd_gen(42U); 68 | 69 | /// Uniform distribution with values between 0 and 1 (0 inclusive, 1 exclusive). 70 | boost::uniform_real _uni_dist(0,1); 71 | 72 | /// Normal distribution with mean 0 and standard deviation 1. 73 | boost::normal_distribution _normal_dist; 74 | 75 | /// Global uniform random random number 76 | boost::variate_generator<_rnd_gen_type&, boost::uniform_real > _uni_rnd(_rnd_gen, _uni_dist); 77 | 78 | /// Global random number generator with standard normal distribution 79 | boost::variate_generator<_rnd_gen_type&, boost::normal_distribution > _normal_rnd(_rnd_gen, _normal_dist); 80 | 81 | 82 | void rnd_seed( size_t seed ) { 83 | _rnd_gen.seed( static_cast(seed) ); 84 | _normal_rnd.distribution().reset(); // needed for clearing the cache used in boost::normal_distribution 85 | } 86 | 87 | Real rnd_uniform() { 88 | return _uni_rnd(); 89 | } 90 | 91 | Real rnd_stdnormal() { 92 | return _normal_rnd(); 93 | } 94 | 95 | int rnd_int( int min, int max ) { 96 | return (int)floor(_uni_rnd() * (max + 1 - min) + min); 97 | } 98 | 99 | std::vector tokenizeString( const std::string& s, bool singleDelim, const std::string& delim ) { 100 | using namespace std; 101 | vector tokens; 102 | 103 | string::size_type start = 0; 104 | while( start <= s.size() ) { 105 | string::size_type end = s.find_first_of( delim, start ); 106 | if( end == string::npos ) 107 | end = s.size(); 108 | 109 | if( end == start && !singleDelim ) { 110 | // skip to next non-delimiter 111 | start = s.find_first_not_of( delim, start ); 112 | if( start == string::npos ) 113 | break; 114 | } else { // we found a token 115 | tokens.push_back( s.substr(start, end - start) ); 116 | start = end + 1; 117 | } 118 | } 119 | 120 | return tokens; 121 | } 122 | 123 | 124 | } // end of namespace dai 125 | -------------------------------------------------------------------------------- /src/varset.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | 11 | 12 | namespace dai { 13 | 14 | 15 | using namespace std; 16 | 17 | 18 | size_t calcLinearState( const VarSet &vs, const std::map &state ) { 19 | size_t prod = 1; 20 | size_t st = 0; 21 | for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) { 22 | std::map::const_iterator m = state.find( *v ); 23 | if( m != state.end() ) 24 | st += prod * m->second; 25 | prod *= v->states(); 26 | } 27 | return st; 28 | } 29 | 30 | 31 | std::map calcState( const VarSet &vs, size_t linearState ) { 32 | std::map state; 33 | for( VarSet::const_iterator v = vs.begin(); v != vs.end(); v++ ) { 34 | state[*v] = linearState % v->states(); 35 | linearState /= v->states(); 36 | } 37 | DAI_ASSERT( linearState == 0 ); 38 | return state; 39 | } 40 | 41 | 42 | } // end of namespace dai 43 | -------------------------------------------------------------------------------- /src/weightedgraph.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | namespace dai { 16 | 17 | 18 | using namespace std; 19 | 20 | 21 | RootedTree::RootedTree( const GraphEL &T, size_t Root ) { 22 | if( T.size() != 0 ) { 23 | // Make a copy 24 | GraphEL Gr = T; 25 | 26 | // Nodes in the tree 27 | set nodes; 28 | 29 | // Check whether the root is in the tree 30 | bool valid = false; 31 | for( GraphEL::iterator e = Gr.begin(); e != Gr.end() && !valid; e++ ) 32 | if( e->first == Root || e->second == Root ) 33 | valid = true; 34 | if( !valid ) 35 | DAI_THROWE(RUNTIME_ERROR,"Graph does not contain specified root."); 36 | 37 | // Start with the root 38 | nodes.insert( Root ); 39 | 40 | // Keep adding edges until done 41 | bool done = false; 42 | while( !done ) { 43 | bool changed = false; 44 | for( GraphEL::iterator e = Gr.begin(); e != Gr.end(); ) { 45 | bool e1_in_nodes = nodes.count( e->first ); 46 | bool e2_in_nodes = nodes.count( e->second ); 47 | if( e1_in_nodes && e2_in_nodes ) 48 | DAI_THROWE(RUNTIME_ERROR,"Graph is not acyclic."); 49 | if( e1_in_nodes ) { 50 | // Add directed edge, pointing away from the root 51 | push_back( DEdge( e->first, e->second ) ); 52 | nodes.insert( e->second ); 53 | // Erase the edge 54 | Gr.erase( e++ ); 55 | changed = true; 56 | } else if( e2_in_nodes ) { 57 | // Add directed edge, pointing away from the root 58 | push_back( DEdge( e->second, e->first ) ); 59 | nodes.insert( e->first ); 60 | // Erase the edge 61 | Gr.erase( e++ ); 62 | changed = true; 63 | } else 64 | e++; 65 | } 66 | if( Gr.empty() ) 67 | done = true; 68 | if( !changed && !done ) 69 | DAI_THROWE(RUNTIME_ERROR,"Graph is not connected."); 70 | } 71 | } 72 | } 73 | 74 | 75 | } // end of namespace dai 76 | -------------------------------------------------------------------------------- /swig/Makefile: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | include ../Makefile.conf 9 | 10 | .PHONY: all 11 | 12 | all: _dai.so dai.oct 13 | 14 | _dai.so: ../lib/libdai.a dai.i 15 | $(SWIG) -python -classic -c++ dai.i 16 | g++ -Wall -c -O3 -g -fPIC dai_wrap.cxx -I$(INCLUDE_PYTHON) -I$(INCLUDE_BOOST) -I../include -lgmpxx -lgmp 17 | g++ -shared dai_wrap.o -o _dai.so ../lib/libdai.a -lgmpxx -lgmp 18 | 19 | dai.oct: ../lib/libdai.a dai.i 20 | $(SWIG) -octave -c++ -o dai_wrap.cpp dai.i 21 | mkoctfile -I$(INCLUDE_BOOST) -I../include -o dai.oct dai_wrap.cpp ../lib/libdai.a -lgmpxx -lgmp 22 | 23 | .PHONY: clean 24 | 25 | clean: 26 | rm -f dai_wrap.cxx dai_wrap.cpp dai_wrap.o _dai.so dai.oct dai.py dai.pyc sprinkler.fg 27 | -------------------------------------------------------------------------------- /swig/README: -------------------------------------------------------------------------------- 1 | This directory contains preliminary experimental SWIG wrappers for libDAI 2 | written by Patrick Pletscher. They enable usage of libDAI functionality 3 | directly from python and octave. 4 | -------------------------------------------------------------------------------- /swig/dai.i: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | %module dai 10 | 11 | %{ 12 | #include "../include/dai/var.h" 13 | #include "../include/dai/smallset.h" 14 | #include "../include/dai/varset.h" 15 | #include "../include/dai/prob.h" 16 | #include "../include/dai/factor.h" 17 | #include "../include/dai/graph.h" 18 | #include "../include/dai/bipgraph.h" 19 | #include "../include/dai/factorgraph.h" 20 | #include "../include/dai/util.h" 21 | %} 22 | 23 | %ignore dai::TProb::operator[]; 24 | %ignore dai::TFactor::operator[]; 25 | 26 | %ignore dai::Var::label() const; 27 | %ignore dai::Var::states() const; 28 | 29 | %include "../include/dai/util.h" 30 | %include "../include/dai/var.h" 31 | %include "../include/dai/smallset.h" 32 | %template(SmallSetVar) dai::SmallSet< dai::Var >; 33 | %include "../include/dai/varset.h" 34 | %extend dai::VarSet { 35 | inline void append(const dai::Var &v) { (*self) |= v; } /* for python, octave */ 36 | }; 37 | 38 | %include "../include/dai/prob.h" 39 | %template(Prob) dai::TProb; 40 | %extend dai::TProb { 41 | inline dai::Real __getitem__(int i) const {return (*self).get(i);} /* for python */ 42 | inline void __setitem__(int i,dai::Real d) {(*self).set(i,d);} /* for python */ 43 | inline dai::Real __paren(int i) const {return (*self).get(i);} /* for octave */ 44 | inline void __paren_asgn(int i,dai::Real d) {(*self).set(i,d);} /* for octave */ 45 | }; 46 | %include "../include/dai/factor.h" 47 | %extend dai::TFactor { 48 | inline dai::Real __getitem__(int i) const {return (*self).get(i);} /* for python */ 49 | inline void __setitem__(int i,dai::Real d) {(*self).set(i,d);} /* for python */ 50 | inline dai::Real __paren__(int i) const {return (*self).get(i);} /* for octave */ 51 | inline void __paren_asgn__(int i,dai::Real d) {(*self).set(i,d);} /* for octave */ 52 | }; 53 | 54 | %template(Factor) dai::TFactor; 55 | %include "../include/dai/graph.h" 56 | %include "../include/dai/bipgraph.h" 57 | %include "../include/dai/factorgraph.h" 58 | %include "std_vector.i" 59 | // TODO: typemaps for the vectors (input/output python arrays) 60 | %inline{ 61 | typedef std::vector VecFactor; 62 | typedef std::vector< VecFactor > VecVecFactor; 63 | } 64 | %template(VecFactor) std::vector< dai::Factor >; 65 | %template(VecVecFactor) std::vector< VecFactor >; 66 | 67 | %include "../include/dai/index.h" 68 | %extend dai::multifor { 69 | inline size_t __getitem__(int i) const { 70 | return (*self)[i]; 71 | } 72 | inline void next() { 73 | return (*self)++; 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /swig/example_sprinkler.m: -------------------------------------------------------------------------------- 1 | % This file is part of libDAI - http://www.libdai.org/ 2 | % 3 | % Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | % 5 | % Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | % This example program illustrates how to construct a factorgraph 9 | % by means of the sprinkler network example discussed at 10 | % http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html 11 | % using the SWIG octave wrapper of libDAI 12 | 13 | dai 14 | 15 | C = dai.Var(0, 2); % Define binary variable Cloudy (with label 0) 16 | S = dai.Var(1, 2); % Define binary variable Sprinkler (with label 1) 17 | R = dai.Var(2, 2); % Define binary variable Rain (with label 2) 18 | W = dai.Var(3, 2); % Define binary variable Wetgrass (with label 3) 19 | 20 | % Define probability distribution for C 21 | P_C = dai.Factor(C); 22 | P_C(0) = 0.5; % C = 0 23 | P_C(1) = 0.5; % C = 1 24 | 25 | % Define conditional probability of S given C 26 | P_S_given_C = dai.Factor(dai.VarSet(S,C)); 27 | P_S_given_C(0) = 0.5; % C = 0, S = 0 28 | P_S_given_C(1) = 0.9; % C = 1, S = 0 29 | P_S_given_C(2) = 0.5; % C = 0, S = 1 30 | P_S_given_C(3) = 0.1; % C = 1, S = 1 31 | 32 | % Define conditional probability of R given C 33 | P_R_given_C = dai.Factor(dai.VarSet(R,C)); 34 | P_R_given_C(0) = 0.8; % C = 0, R = 0 35 | P_R_given_C(1) = 0.2; % C = 1, R = 0 36 | P_R_given_C(2) = 0.2; % C = 0, R = 1 37 | P_R_given_C(3) = 0.8; % C = 1, R = 1 38 | 39 | % Define conditional probability of W given S and R 40 | SRW = dai.VarSet(S,R); 41 | SRW.append(W); 42 | P_W_given_S_R = dai.Factor(SRW); 43 | P_W_given_S_R(0) = 1.0; % S = 0, R = 0, W = 0 44 | P_W_given_S_R(1) = 0.1; % S = 1, R = 0, W = 0 45 | P_W_given_S_R(2) = 0.1; % S = 0, R = 1, W = 0 46 | P_W_given_S_R(3) = 0.01; % S = 1, R = 1, W = 0 47 | P_W_given_S_R(4) = 0.0; % S = 0, R = 0, W = 1 48 | P_W_given_S_R(5) = 0.9; % S = 1, R = 0, W = 1 49 | P_W_given_S_R(6) = 0.9; % S = 0, R = 1, W = 1 50 | P_W_given_S_R(7) = 0.99; % S = 1, R = 1, W = 1 51 | 52 | % Build factor graph consisting of those four factors 53 | SprinklerFactors = dai.VecFactor(); 54 | SprinklerFactors.append(P_C); 55 | SprinklerFactors.append(P_R_given_C); 56 | SprinklerFactors.append(P_S_given_C); 57 | SprinklerFactors.append(P_W_given_S_R); 58 | SprinklerNetwork = dai.FactorGraph(SprinklerFactors); 59 | 60 | % Write factorgraph to a file 61 | SprinklerNetwork.WriteToFile('sprinkler.fg'); 62 | fprintf('Sprinkler network written to sprinkler.fg\n'); 63 | 64 | % Output some information about the factorgraph 65 | fprintf('%d variables\n', SprinklerNetwork.nrVars()); 66 | fprintf('%d factors\n', SprinklerNetwork.nrFactors()); 67 | 68 | % Calculate joint probability of all four variables 69 | P = dai.Factor(); 70 | for I = 0:(SprinklerNetwork.nrFactors()-1) 71 | P *= SprinklerNetwork.factor(I); 72 | end 73 | P.normalize(); % Not necessary: a Bayesian network is already normalized by definition 74 | 75 | % Calculate some probabilities 76 | denom = P.marginal(dai.VarSet(W))(1); 77 | fprintf('P(W=1) = %f\n', denom); 78 | fprintf('P(S=1 | W=1) = %f\n', P.marginal(dai.VarSet(S,W))(3) / denom); 79 | fprintf('P(R=1 | W=1) = %f\n', P.marginal(dai.VarSet(R,W))(3) / denom); 80 | -------------------------------------------------------------------------------- /swig/example_sprinkler.py: -------------------------------------------------------------------------------- 1 | # This file is part of libDAI - http://www.libdai.org/ 2 | # 3 | # Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | # 5 | # Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | 7 | 8 | # This example program illustrates how to construct a factorgraph 9 | # by means of the sprinkler network example discussed at 10 | # http://www.cs.ubc.ca/~murphyk/Bayes/bnintro.html 11 | # using the SWIG python wrapper of libDAI 12 | 13 | 14 | import dai 15 | 16 | C = dai.Var(0, 2) # Define binary variable Cloudy (with label 0) 17 | S = dai.Var(1, 2) # Define binary variable Sprinkler (with label 1) 18 | R = dai.Var(2, 2) # Define binary variable Rain (with label 2) 19 | W = dai.Var(3, 2) # Define binary variable Wetgrass (with label 3) 20 | 21 | # Define probability distribution for C 22 | P_C = dai.Factor(C) 23 | P_C[0] = 0.5 # C = 0 24 | P_C[1] = 0.5 # C = 1 25 | 26 | # Define conditional probability of S given C 27 | P_S_given_C = dai.Factor(dai.VarSet(S,C)) 28 | P_S_given_C[0] = 0.5 # C = 0, S = 0 29 | P_S_given_C[1] = 0.9 # C = 1, S = 0 30 | P_S_given_C[2] = 0.5 # C = 0, S = 1 31 | P_S_given_C[3] = 0.1 # C = 1, S = 1 32 | 33 | # Define conditional probability of R given C 34 | P_R_given_C = dai.Factor(dai.VarSet(R,C)) 35 | P_R_given_C[0] = 0.8 # C = 0, R = 0 36 | P_R_given_C[1] = 0.2 # C = 1, R = 0 37 | P_R_given_C[2] = 0.2 # C = 0, R = 1 38 | P_R_given_C[3] = 0.8 # C = 1, R = 1 39 | 40 | # Define conditional probability of W given S and R 41 | SRW = dai.VarSet(S,R) 42 | SRW.append(W) 43 | P_W_given_S_R = dai.Factor(SRW) 44 | P_W_given_S_R[0] = 1.0 # S = 0, R = 0, W = 0 45 | P_W_given_S_R[1] = 0.1 # S = 1, R = 0, W = 0 46 | P_W_given_S_R[2] = 0.1 # S = 0, R = 1, W = 0 47 | P_W_given_S_R[3] = 0.01 # S = 1, R = 1, W = 0 48 | P_W_given_S_R[4] = 0.0 # S = 0, R = 0, W = 1 49 | P_W_given_S_R[5] = 0.9 # S = 1, R = 0, W = 1 50 | P_W_given_S_R[6] = 0.9 # S = 0, R = 1, W = 1 51 | P_W_given_S_R[7] = 0.99 # S = 1, R = 1, W = 1 52 | 53 | # Build factor graph consisting of those four factors 54 | SprinklerFactors = dai.VecFactor() 55 | SprinklerFactors.append(P_C) 56 | SprinklerFactors.append(P_R_given_C) 57 | SprinklerFactors.append(P_S_given_C) 58 | SprinklerFactors.append(P_W_given_S_R) 59 | SprinklerNetwork = dai.FactorGraph(SprinklerFactors) 60 | 61 | # Write factorgraph to a file 62 | SprinklerNetwork.WriteToFile('sprinkler.fg') 63 | print 'Sprinkler network written to sprinkler.fg' 64 | 65 | # Output some information about the factorgraph 66 | print SprinklerNetwork.nrVars(), 'variables' 67 | print SprinklerNetwork.nrFactors(), 'factors' 68 | 69 | # Calculate joint probability of all four variables 70 | P = dai.Factor() 71 | for I in range(SprinklerNetwork.nrFactors()): 72 | P *= SprinklerNetwork.factor(I) 73 | P.normalize() # Not necessary: a Bayesian network is already normalized by definition 74 | 75 | # Calculate some probabilities 76 | denom = P.marginal(dai.VarSet(W))[1] 77 | print 'P(W=1) =', denom 78 | print 'P(S=1 | W=1) =', P.marginal(dai.VarSet(S,W))[3] / denom 79 | print 'P(R=1 | W=1) =', P.marginal(dai.VarSet(R,W))[3] / denom 80 | -------------------------------------------------------------------------------- /tests/hoi1.fg: -------------------------------------------------------------------------------- 1 | # Factor graph made by utils/createfg 2 | # type = hoi 3 | # N = 10 4 | # M = 3 5 | # k = 3 6 | # beta = 1 7 | # seed = 12345 8 | 3 9 | 10 | 3 11 | 2 6 7 12 | 2 2 2 13 | 8 14 | 0 2.6190635748817 15 | 1 0.68885412652977 16 | 2 0.83464115122831 17 | 3 0.38475684223169 18 | 4 0.3255025197617 19 | 5 1.9692111887049 20 | 6 0.55208846715017 21 | 7 0.38595110280868 22 | 23 | 3 24 | 0 1 6 25 | 2 2 2 26 | 8 27 | 0 1.0352133626924 28 | 1 1.547478952122 29 | 2 2.3176521897449 30 | 3 1.2804190071868 31 | 4 4.9220798130027 32 | 5 2.5272557501946 33 | 6 0.83127929631575 34 | 7 0.26280563080263 35 | 36 | 3 37 | 1 2 4 38 | 2 2 2 39 | 8 40 | 0 0.2371680948972 41 | 1 3.7876163914702 42 | 2 5.3196087077347 43 | 3 0.96049191560722 44 | 4 4.8483648454236 45 | 5 0.45974506954001 46 | 6 2.1151447659773 47 | 7 0.57337737335857 48 | -------------------------------------------------------------------------------- /tests/hoi2.fg: -------------------------------------------------------------------------------- 1 | # Factor graph made by ../utils/createfg 2 | # type = hoi 3 | # N = 10 4 | # M = 2 5 | # k = 4 6 | # beta = 1 7 | # seed = 1234567 8 | 2 9 | 10 | 4 11 | 0 2 7 8 12 | 2 2 2 2 13 | 16 14 | 0 2.2435781084647 15 | 1 4.0907955014965 16 | 2 1.1211049952628 17 | 3 1.1924200451373 18 | 4 0.6827733720955 19 | 5 10.160805816224 20 | 6 0.67358126735639 21 | 7 0.11391058009404 22 | 8 0.48125062895484 23 | 9 0.72144061373552 24 | 10 0.42394324261549 25 | 11 1.8698790799175 26 | 12 0.751673014734 27 | 13 3.3944709353 28 | 14 3.0697466018763 29 | 15 1.3518859952286 30 | 31 | 4 32 | 1 2 6 7 33 | 2 2 2 2 34 | 16 35 | 0 0.73767149678205 36 | 1 1.0407773095719 37 | 2 3.128053583949 38 | 3 4.9605310970883 39 | 4 0.13720523936748 40 | 5 7.321038643904 41 | 6 0.32066394017723 42 | 7 1.4685064382197 43 | 8 0.17120387482343 44 | 9 0.98014607500624 45 | 10 0.10935224527934 46 | 11 0.67077127555589 47 | 12 1.1255976822923 48 | 13 2.0774604864366 49 | 14 0.36868871983683 50 | 15 0.8542593124821 51 | -------------------------------------------------------------------------------- /tests/hoi3.fg: -------------------------------------------------------------------------------- 1 | # Factor graph made by ../utils/createfg 2 | # type = hoi 3 | # N = 10 4 | # M = 3 5 | # k = 3 6 | # beta = 1 7 | # seed = 1234567 8 | 3 9 | 10 | 3 11 | 0 2 7 12 | 2 2 2 13 | 8 14 | 0 1.4681858088541 15 | 1 0.62677975912889 16 | 2 0.93772291212951 17 | 3 0.55789818196925 18 | 4 2.2169178835152 19 | 5 1.1158597402573 20 | 6 4.3668946864226 21 | 7 0.5386131975631 22 | 23 | 3 24 | 2 5 9 25 | 2 2 2 26 | 8 27 | 0 0.42394324261549 28 | 1 1.8698790799175 29 | 2 0.751673014734 30 | 3 3.3944709353 31 | 4 3.0697466018763 32 | 5 1.3518859952286 33 | 6 0.85108939407003 34 | 7 0.44249854609337 35 | 36 | 3 37 | 1 4 6 38 | 2 2 2 39 | 8 40 | 0 1.7323418161587 41 | 1 1.1774643424739 42 | 2 1.8134284856927 43 | 3 0.46535724537261 44 | 4 2.9520075062676 45 | 5 0.87717718658893 46 | 6 0.30844599722711 47 | 7 0.9045019040901 48 | -------------------------------------------------------------------------------- /tests/hoi4.fg: -------------------------------------------------------------------------------- 1 | # Factor graph made by ../utils/createfg 2 | # type = hoi 3 | # N = 10 4 | # M = 3 5 | # k = 3 6 | # beta = 1 7 | # seed = 123456 8 | 3 9 | 10 | 3 11 | 5 7 9 12 | 2 2 2 13 | 8 14 | 0 0.34695110012176 15 | 1 5.2445568426086 16 | 2 0.40353951923864 17 | 3 0.87337008674168 18 | 4 1.8484229288021 19 | 5 1.3558019751326 20 | 6 0.18957537662536 21 | 7 1.0106086348982 22 | 23 | 3 24 | 7 8 9 25 | 2 2 2 26 | 8 27 | 0 1.4346630217766 28 | 1 1.7381665310949 29 | 2 1.4305082973985 30 | 3 0.93926886261587 31 | 4 0.37893660692703 32 | 5 0.82593511761888 33 | 6 0.24322233722175 34 | 7 0.30679804692782 35 | 36 | 3 37 | 0 6 7 38 | 2 2 2 39 | 8 40 | 0 0.5061849993673 41 | 1 1.6117048972906 42 | 2 2.0693735419645 43 | 3 0.5455720871037 44 | 4 2.0160537987371 45 | 5 0.30172846959351 46 | 6 1.8962849316602 47 | 7 3.5838027075412 48 | -------------------------------------------------------------------------------- /tests/jtreemapbug.fg: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 2 4 | 0 1 5 | 2 2 6 | 4 7 | 0 1 8 | 1 2 9 | 2 2 10 | 3 1 11 | -------------------------------------------------------------------------------- /tests/maxprodbug.fg: -------------------------------------------------------------------------------- 1 | 3 2 | 3 | 2 4 | 1 2 5 | 2 2 6 | 4 7 | 0 1 8 | 1 0 9 | 2 0 10 | 3 1 11 | 12 | 2 13 | 1 3 14 | 2 2 15 | 4 16 | 0 1 17 | 1 1 18 | 2 1 19 | 3 1 20 | 21 | 2 22 | 2 3 23 | 2 2 24 | 4 25 | 0 0 26 | 1 1 27 | 2 1 28 | 3 0 29 | -------------------------------------------------------------------------------- /tests/testall: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Marginal inference 3 | ./testdai --report-iters false --report-time false --marginals VAR --aliases aliases.conf --filename $1 --methods EXACT JTREE_MINFILL_HUGIN JTREE_MINFILL_SHSH JTREE_WEIGHTEDMINFILL_HUGIN JTREE_WEIGHTEDMINFILL_SHSH JTREE_MINWEIGHT_HUGIN JTREE_MINWEIGHT_SHSH JTREE_MINNEIGHBORS_HUGIN JTREE_MINNEIGHBORS_SHSH BP BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG FBP FBP_SEQFIX FBP_SEQRND FBP_SEQMAX FBP_PARALL FBP_SEQFIX_LOG FBP_SEQRND_LOG FBP_SEQMAX_LOG FBP_PARALL_LOG TRWBP TRWBP_SEQFIX TRWBP_SEQRND TRWBP_SEQMAX TRWBP_PARALL TRWBP_SEQFIX_LOG TRWBP_SEQRND_LOG TRWBP_SEQMAX_LOG TRWBP_PARALL_LOG MF MF_NAIVE_UNI MF_NAIVE_RND MF_HARDSPIN_UNI MF_HARDSPIN_RND TREEEP TREEEPWC GBP_MIN GBP_BETHE GBP_LOOP3 HAK_MIN HAK_BETHE HAK_DELTA HAK_LOOP3 HAK_LOOP4 HAK_LOOP5 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP 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_PAIR2CAV_SEQFIX LCBP_PAIR2CAVin_SEQFIX LCBP_PAIR2CAV_SEQRND LCBP_PAIR2CAVin_SEQRND LCBP_PAIR2CAV_NONE LCBP_PAIR2CAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND LCTREEEP BBP 4 | # GBP_DELTA, GBP_LOOP4, GBP_LOOP5, GBP_LOOP6, GBP_LOOP7 misbehave 5 | # MAP inference 6 | ./testdai --report-iters false --report-time false --marginals VAR --aliases aliases.conf --filename $1 --methods JTREE_MINFILL_HUGIN_MAP JTREE_MINFILL_SHSH_MAP JTREE_WEIGHTEDMINFILL_HUGIN_MAP JTREE_WEIGHTEDMINFILL_SHSH_MAP JTREE_MINWEIGHT_HUGIN_MAP JTREE_MINWEIGHT_SHSH_MAP JTREE_MINNEIGHBORS_HUGIN_MAP JTREE_MINNEIGHBORS_SHSH_MAP MP_SEQFIX MP_SEQRND MP_PARALL MP_SEQFIX_LOG MP_SEQRND_LOG MP_PARALL_LOG FMP_SEQFIX FMP_SEQRND FMP_PARALL FMP_SEQFIX_LOG FMP_SEQRND_LOG FMP_PARALL_LOG TRWMP_SEQFIX TRWMP_SEQRND TRWMP_PARALL TRWMP_SEQFIX_LOG TRWMP_SEQRND_LOG TRWMP_PARALL_LOG DECMAP 7 | # *MP_SEQMAX and *MP_SEQMAX_LOG make no sense, apparently 8 | -------------------------------------------------------------------------------- /tests/testall.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM Marginal inference 3 | @testdai --report-iters false --report-time false --marginals VAR --aliases aliases.conf --filename %1 --methods EXACT JTREE_MINFILL_HUGIN JTREE_MINFILL_SHSH JTREE_WEIGHTEDMINFILL_HUGIN JTREE_WEIGHTEDMINFILL_SHSH JTREE_MINWEIGHT_HUGIN JTREE_MINWEIGHT_SHSH JTREE_MINNEIGHBORS_HUGIN JTREE_MINNEIGHBORS_SHSH BP BP_SEQFIX BP_SEQRND BP_SEQMAX BP_PARALL BP_SEQFIX_LOG BP_SEQRND_LOG BP_SEQMAX_LOG BP_PARALL_LOG FBP FBP_SEQFIX FBP_SEQRND FBP_SEQMAX FBP_PARALL FBP_SEQFIX_LOG FBP_SEQRND_LOG FBP_SEQMAX_LOG FBP_PARALL_LOG TRWBP TRWBP_SEQFIX TRWBP_SEQRND TRWBP_SEQMAX TRWBP_PARALL TRWBP_SEQFIX_LOG TRWBP_SEQRND_LOG TRWBP_SEQMAX_LOG TRWBP_PARALL_LOG MF MF_NAIVE_UNI MF_NAIVE_RND MF_HARDSPIN_UNI MF_HARDSPIN_RND TREEEP TREEEPWC GBP_MIN GBP_BETHE GBP_LOOP3 HAK_MIN HAK_BETHE HAK_DELTA HAK_LOOP3 HAK_LOOP4 HAK_LOOP5 MR_RESPPROP_FULL MR_CLAMPING_FULL MR_EXACT_FULL MR_RESPPROP_LINEAR MR_CLAMPING_LINEAR MR_EXACT_LINEAR LCBP 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_PAIR2CAV_SEQFIX LCBP_PAIR2CAVin_SEQFIX LCBP_PAIR2CAV_SEQRND LCBP_PAIR2CAVin_SEQRND LCBP_PAIR2CAV_NONE LCBP_PAIR2CAVin_NONE LCBP_UNICAV_SEQFIX LCBP_UNICAV_SEQRND LCTREEEP BBP 4 | REM GBP_DELTA, GBP_LOOP4, GBP_LOOP5, GBP_LOOP6, GBP_LOOP7 misbehave 5 | 6 | REM MAP inference 7 | @testdai --report-iters false --report-time false --marginals VAR --aliases aliases.conf --filename %1 --methods JTREE_MINFILL_HUGIN_MAP JTREE_MINFILL_SHSH_MAP JTREE_WEIGHTEDMINFILL_HUGIN_MAP JTREE_WEIGHTEDMINFILL_SHSH_MAP JTREE_MINWEIGHT_HUGIN_MAP JTREE_MINWEIGHT_SHSH_MAP JTREE_MINNEIGHBORS_HUGIN_MAP JTREE_MINNEIGHBORS_SHSH_MAP MP_SEQFIX MP_SEQRND MP_PARALL MP_SEQFIX_LOG MP_SEQRND_LOG MP_PARALL_LOG FMP_SEQFIX FMP_SEQRND FMP_PARALL FMP_SEQFIX_LOG FMP_SEQRND_LOG FMP_PARALL_LOG TRWMP_SEQFIX TRWMP_SEQRND TRWMP_PARALL TRWMP_SEQFIX_LOG TRWMP_SEQRND_LOG TRWMP_PARALL_LOG DECMAP 8 | REM *MP_SEQMAX and *MP_SEQMAX_LOG make no sense, apparently 9 | -------------------------------------------------------------------------------- /tests/testbbp.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | using namespace dai; 15 | using namespace std; 16 | 17 | 18 | int main( int argc, char *argv[] ) { 19 | if ( argc != 2 ) { 20 | cout << "Usage: " << argv[0] << " " << endl << endl; 21 | cout << "Reads factor graph and verifies" << endl; 22 | cout << "whether BBP works correctly on it." << endl << endl; 23 | return 1; 24 | } else { 25 | // Read FactorGraph from the file specified by the first command line argument 26 | FactorGraph fg; 27 | fg.ReadFromFile(argv[1]); 28 | 29 | // Set some constants 30 | size_t verbose = 0; 31 | Real tol = 1.0e-9; 32 | size_t maxiter = 10000; 33 | Real damping = 0.0; 34 | 35 | // Store the constants in a PropertySet object 36 | PropertySet opts; 37 | opts.set("verbose",verbose); // Verbosity (amount of output generated) 38 | opts.set("tol",tol); // Tolerance for convergence 39 | opts.set("maxiter",maxiter); // Maximum number of iterations 40 | opts.set("damping",damping); // Amount of damping applied 41 | 42 | // Construct a BP (belief propagation) object from the FactorGraph fg 43 | BP bp(fg, opts("updates",string("SEQFIX"))("logdomain",false)); 44 | bp.recordSentMessages = true; 45 | bp.init(); 46 | bp.run(); 47 | 48 | vector state( fg.nrVars(), 0 ); 49 | 50 | for( size_t t = 0; t < 45; t++ ) { 51 | BBP::Properties::UpdateType updates; 52 | switch( t % 5 ) { 53 | case BBP::Properties::UpdateType::SEQ_FIX: 54 | updates = BBP::Properties::UpdateType::SEQ_FIX; 55 | break; 56 | case BBP::Properties::UpdateType::SEQ_MAX: 57 | updates = BBP::Properties::UpdateType::SEQ_MAX; 58 | break; 59 | case BBP::Properties::UpdateType::SEQ_BP_REV: 60 | updates = BBP::Properties::UpdateType::SEQ_BP_REV; 61 | break; 62 | case BBP::Properties::UpdateType::SEQ_BP_FWD: 63 | updates = BBP::Properties::UpdateType::SEQ_BP_FWD; 64 | break; 65 | case BBP::Properties::UpdateType::PAR: 66 | updates = BBP::Properties::UpdateType::PAR; 67 | break; 68 | } 69 | BBPCostFunction cfn; 70 | switch( (t / 5) % 9 ) { 71 | case 0: 72 | cfn = BBPCostFunction::CFN_GIBBS_B; 73 | break; 74 | case 1: 75 | cfn = BBPCostFunction::CFN_GIBBS_B2; 76 | break; 77 | case 2: 78 | cfn = BBPCostFunction::CFN_GIBBS_EXP; 79 | break; 80 | case 3: 81 | cfn = BBPCostFunction::CFN_GIBBS_B_FACTOR; 82 | break; 83 | case 4: 84 | cfn = BBPCostFunction::CFN_GIBBS_B2_FACTOR; 85 | break; 86 | case 5: 87 | cfn = BBPCostFunction::CFN_GIBBS_EXP_FACTOR; 88 | break; 89 | case 6: 90 | cfn = BBPCostFunction::CFN_VAR_ENT; 91 | break; 92 | case 7: 93 | cfn = BBPCostFunction::CFN_FACTOR_ENT; 94 | break; 95 | case 8: 96 | cfn = BBPCostFunction::CFN_BETHE_ENT; 97 | break; 98 | } 99 | 100 | Real h = 1e-4; 101 | Real result = numericBBPTest( bp, &state, opts("updates",updates), cfn, h ); 102 | cout << "result: " << result << ",\tupdates=" << updates << ", cfn=" << cfn << endl; 103 | } 104 | } 105 | 106 | return 0; 107 | } 108 | -------------------------------------------------------------------------------- /tests/testem/2var.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 1 4 | CondProbEstimation [target_dim=2,total_dim=4,pseudo_count=1] 5 | 1 6 | 0 1 0 7 | -------------------------------------------------------------------------------- /tests/testem/2var.fg: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 2 4 | 0 1 5 | 2 2 6 | 4 7 | 0 0.5 8 | 1 0.5 9 | 2 0.5 10 | 3 0.5 -------------------------------------------------------------------------------- /tests/testem/2var_data.tab: -------------------------------------------------------------------------------- 1 | 0 1 2 | 3 | 0 1 4 | 0 1 5 | 0 1 6 | 0 1 7 | 0 1 8 | 0 1 9 | 0 1 10 | 0 1 11 | 0 1 12 | 0 0 13 | 1 1 14 | 1 1 15 | 1 1 16 | 1 0 17 | 1 0 18 | 1 0 19 | 1 0 20 | 1 0 21 | 1 0 22 | 1 0 23 | -------------------------------------------------------------------------------- /tests/testem/3var.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 1 4 | CondProbEstimation [target_dim=2,total_dim=8,pseudo_count=1] 5 | 1 6 | 0 1 0 2 7 | -------------------------------------------------------------------------------- /tests/testem/3var.fg: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 3 4 | 0 1 2 5 | 2 2 2 6 | 8 7 | 0 0.5 8 | 1 0.5 9 | 2 0.5 10 | 3 0.5 11 | 4 0.5 12 | 5 0.5 13 | 6 0.5 14 | 7 0.5 -------------------------------------------------------------------------------- /tests/testem/hoi1_data.tab: -------------------------------------------------------------------------------- 1 | 0 1 2 4 6 7 2 | 3 | 0 0 1 1 0 4 | 1 1 1 0 5 | 0 1 0 0 0 1 6 | 0 0 0 1 0 0 7 | 1 0 0 1 0 8 | -------------------------------------------------------------------------------- /tests/testem/hoi1_infer_f2.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 1 4 | CondProbEstimation [target_dim=2,total_dim=8,pseudo_count=1] 5 | 1 6 | 2 1 2 4 7 | -------------------------------------------------------------------------------- /tests/testem/hoi1_share_f0_f1_f2.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 1 4 | CondProbEstimation [target_dim=2,total_dim=8,pseudo_count=1] 5 | 3 6 | 2 1 2 4 7 | 1 0 1 6 8 | 0 6 2 7 9 | -------------------------------------------------------------------------------- /tests/testem/hoi1_share_f0_f2.em: -------------------------------------------------------------------------------- 1 | 1 2 | 3 | 1 4 | CondProbEstimation [target_dim=2,total_dim=8,pseudo_count=1] 5 | 2 6 | 2 1 2 4 7 | 0 6 2 7 8 | -------------------------------------------------------------------------------- /tests/testem/runtests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TMPFILE1=`mktemp /var/tmp/testem.XXXXXX` 3 | trap 'rm -f $TMPFILE1' 0 1 15 4 | 5 | ./testem 2var.fg 2var_data.tab 2var.em > $TMPFILE1 6 | ./testem 3var.fg 2var_data.tab 3var.em >> $TMPFILE1 7 | ./testem ../hoi1.fg hoi1_data.tab hoi1_share_f0_f2.em >> $TMPFILE1 8 | ./testem ../hoi1.fg hoi1_data.tab hoi1_share_f0_f1_f2.em >> $TMPFILE1 9 | diff -s $TMPFILE1 testem.out || exit 1 10 | 11 | rm -f $TMPFILE1 12 | -------------------------------------------------------------------------------- /tests/testem/runtests.bat: -------------------------------------------------------------------------------- 1 | testem 2var.fg 2var_data.tab 2var.em > testem.out.tmp 2 | testem 3var.fg 2var_data.tab 3var.em >> testem.out.tmp 3 | testem ..\hoi1.fg hoi1_data.tab hoi1_share_f0_f2.em >> testem.out.tmp 4 | testem ..\hoi1.fg hoi1_data.tab hoi1_share_f0_f1_f2.em >> testem.out.tmp 5 | diff -s testem.out.tmp testem.out 6 | 7 | del testem.out.tmp 8 | -------------------------------------------------------------------------------- /tests/testem/testem.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | using namespace std; 19 | using namespace dai; 20 | 21 | 22 | void usage( const string &msg ) { 23 | cerr << msg << endl; 24 | cerr << "Usage:" << endl; 25 | cerr << " testem factorgraph.fg evidence.tab emconfig.em" << endl; 26 | exit( 1 ); 27 | } 28 | 29 | 30 | int main( int argc, char** argv ) { 31 | if( argc != 4 ) 32 | usage("Incorrect number of arguments."); 33 | 34 | FactorGraph fg; 35 | fg.ReadFromFile( argv[1] ); 36 | 37 | PropertySet infprops; 38 | infprops.set( "verbose", (size_t)0 ); 39 | infprops.set( "updates", string("HUGIN") ); 40 | InfAlg* inf = newInfAlg( "JTREE", fg, infprops ); 41 | inf->init(); 42 | 43 | Evidence e; 44 | ifstream estream( argv[2] ); 45 | e.addEvidenceTabFile( estream, fg ); 46 | 47 | cout << "Number of samples: " << e.nrSamples() << endl; 48 | for( Evidence::iterator ps = e.begin(); ps != e.end(); ps++ ) 49 | cout << "Sample #" << (ps - e.begin()) << " has " << ps->size() << " observations." << endl; 50 | 51 | ifstream emstream( argv[3] ); 52 | EMAlg em(e, *inf, emstream); 53 | 54 | while( !em.hasSatisfiedTermConditions() ) { 55 | Real l = em.iterate(); 56 | cout << "Iteration " << em.Iterations() << " likelihood: " << l <fg(); 62 | 63 | delete inf; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /tests/testem/testem.out: -------------------------------------------------------------------------------- 1 | Number of samples: 20 2 | Sample #0 has 2 observations. 3 | Sample #1 has 2 observations. 4 | Sample #2 has 2 observations. 5 | Sample #3 has 2 observations. 6 | Sample #4 has 2 observations. 7 | Sample #5 has 2 observations. 8 | Sample #6 has 2 observations. 9 | Sample #7 has 2 observations. 10 | Sample #8 has 2 observations. 11 | Sample #9 has 2 observations. 12 | Sample #10 has 2 observations. 13 | Sample #11 has 2 observations. 14 | Sample #12 has 2 observations. 15 | Sample #13 has 2 observations. 16 | Sample #14 has 2 observations. 17 | Sample #15 has 2 observations. 18 | Sample #16 has 2 observations. 19 | Sample #17 has 2 observations. 20 | Sample #18 has 2 observations. 21 | Sample #19 has 2 observations. 22 | Iteration 1 likelihood: -27.7259 23 | Iteration 2 likelihood: -23.4297 24 | Iteration 3 likelihood: -23.4297 25 | 26 | Inferred Factor Graph: 27 | ###################### 28 | 1 29 | 30 | 2 31 | 0 1 32 | 2 2 33 | 4 34 | 0 0.166666666667 35 | 1 0.666666666667 36 | 2 0.833333333333 37 | 3 0.333333333333 38 | Number of samples: 20 39 | Sample #0 has 2 observations. 40 | Sample #1 has 2 observations. 41 | Sample #2 has 2 observations. 42 | Sample #3 has 2 observations. 43 | Sample #4 has 2 observations. 44 | Sample #5 has 2 observations. 45 | Sample #6 has 2 observations. 46 | Sample #7 has 2 observations. 47 | Sample #8 has 2 observations. 48 | Sample #9 has 2 observations. 49 | Sample #10 has 2 observations. 50 | Sample #11 has 2 observations. 51 | Sample #12 has 2 observations. 52 | Sample #13 has 2 observations. 53 | Sample #14 has 2 observations. 54 | Sample #15 has 2 observations. 55 | Sample #16 has 2 observations. 56 | Sample #17 has 2 observations. 57 | Sample #18 has 2 observations. 58 | Sample #19 has 2 observations. 59 | Iteration 1 likelihood: -27.7259 60 | Iteration 2 likelihood: -23.7555 61 | Iteration 3 likelihood: -23.7555 62 | 63 | Inferred Factor Graph: 64 | ###################### 65 | 1 66 | 67 | 3 68 | 0 1 2 69 | 2 2 2 70 | 8 71 | 0 0.214285714286 72 | 1 0.642857142857 73 | 2 0.785714285714 74 | 3 0.357142857143 75 | 4 0.214285714286 76 | 5 0.642857142857 77 | 6 0.785714285714 78 | 7 0.357142857143 79 | Number of samples: 5 80 | Sample #0 has 5 observations. 81 | Sample #1 has 4 observations. 82 | Sample #2 has 6 observations. 83 | Sample #3 has 6 observations. 84 | Sample #4 has 5 observations. 85 | Iteration 1 likelihood: -16.4893 86 | Iteration 2 likelihood: -15.4406 87 | Iteration 3 likelihood: -15.3299 88 | 89 | Inferred Factor Graph: 90 | ###################### 91 | 3 92 | 93 | 3 94 | 2 6 7 95 | 2 2 2 96 | 8 97 | 0 0.396387112396 98 | 1 0.356649908835 99 | 2 0.603612887604 100 | 3 0.643350091165 101 | 4 0.805779039527 102 | 5 0.669278114097 103 | 6 0.194220960473 104 | 7 0.330721885903 105 | 106 | 3 107 | 0 1 6 108 | 2 2 2 109 | 8 110 | 0 1.03521336269 111 | 1 1.54747895212 112 | 2 2.31765218974 113 | 3 1.28041900719 114 | 4 4.922079813 115 | 5 2.52725575019 116 | 6 0.831279296316 117 | 7 0.262805630803 118 | 119 | 3 120 | 1 2 4 121 | 2 2 2 122 | 8 123 | 0 0.396387112396 124 | 1 0.603612887604 125 | 2 0.356649908835 126 | 3 0.643350091165 127 | 4 0.805779039527 128 | 5 0.194220960473 129 | 6 0.669278114097 130 | 7 0.330721885903 131 | Number of samples: 5 132 | Sample #0 has 5 observations. 133 | Sample #1 has 4 observations. 134 | Sample #2 has 6 observations. 135 | Sample #3 has 6 observations. 136 | Sample #4 has 5 observations. 137 | Iteration 1 likelihood: -16.4893 138 | Iteration 2 likelihood: -17.6905 139 | Iteration 3 likelihood: -17.6582 140 | 141 | Inferred Factor Graph: 142 | ###################### 143 | 3 144 | 145 | 3 146 | 2 6 7 147 | 2 2 2 148 | 8 149 | 0 0.495312199726 150 | 1 0.499107942908 151 | 2 0.504687800274 152 | 3 0.500892057092 153 | 4 0.640416549958 154 | 5 0.495122293924 155 | 6 0.359583450042 156 | 7 0.504877706076 157 | 158 | 3 159 | 0 1 6 160 | 2 2 2 161 | 8 162 | 0 0.495312199726 163 | 1 0.504687800274 164 | 2 0.499107942908 165 | 3 0.500892057092 166 | 4 0.640416549958 167 | 5 0.359583450042 168 | 6 0.495122293924 169 | 7 0.504877706076 170 | 171 | 3 172 | 1 2 4 173 | 2 2 2 174 | 8 175 | 0 0.495312199726 176 | 1 0.504687800274 177 | 2 0.499107942908 178 | 3 0.500892057092 179 | 4 0.640416549958 180 | 5 0.359583450042 181 | 6 0.495122293924 182 | 7 0.504877706076 183 | -------------------------------------------------------------------------------- /tests/testfast.fg: -------------------------------------------------------------------------------- 1 | # Factor graph made by ../utils/createfg 2 | # type = GRID 3 | # states = 2 4 | # n1 = 4 5 | # n2 = 4 6 | # options = [mean_th=0,mean_w=0,sigma_th=0.4,sigma_w=0.4] 7 | # N = 16 8 | # seed = 123 9 | 40 10 | 11 | 2 12 | 0 4 13 | 2 2 14 | 4 15 | 0 1.55785 16 | 1 0.641909 17 | 2 0.641909 18 | 3 1.55785 19 | 20 | 2 21 | 0 1 22 | 2 2 23 | 4 24 | 0 1.00773 25 | 1 0.992328 26 | 2 0.992328 27 | 3 1.00773 28 | 29 | 2 30 | 1 5 31 | 2 2 32 | 4 33 | 0 1.78772 34 | 1 0.559373 35 | 2 0.559373 36 | 3 1.78772 37 | 38 | 2 39 | 1 2 40 | 2 2 41 | 4 42 | 0 0.882839 43 | 1 1.13271 44 | 2 1.13271 45 | 3 0.882839 46 | 47 | 2 48 | 2 6 49 | 2 2 50 | 4 51 | 0 1.39819 52 | 1 0.715211 53 | 2 0.715211 54 | 3 1.39819 55 | 56 | 2 57 | 2 3 58 | 2 2 59 | 4 60 | 0 1.13791 61 | 1 0.878807 62 | 2 0.878807 63 | 3 1.13791 64 | 65 | 2 66 | 3 7 67 | 2 2 68 | 4 69 | 0 0.580131 70 | 1 1.72375 71 | 2 1.72375 72 | 3 0.580131 73 | 74 | 2 75 | 4 8 76 | 2 2 77 | 4 78 | 0 2.30325 79 | 1 0.434168 80 | 2 0.434168 81 | 3 2.30325 82 | 83 | 2 84 | 4 5 85 | 2 2 86 | 4 87 | 0 0.795215 88 | 1 1.25752 89 | 2 1.25752 90 | 3 0.795215 91 | 92 | 2 93 | 5 9 94 | 2 2 95 | 4 96 | 0 1.45375 97 | 1 0.687876 98 | 2 0.687876 99 | 3 1.45375 100 | 101 | 2 102 | 5 6 103 | 2 2 104 | 4 105 | 0 2.49364 106 | 1 0.40102 107 | 2 0.40102 108 | 3 2.49364 109 | 110 | 2 111 | 6 10 112 | 2 2 113 | 4 114 | 0 1.08628 115 | 1 0.920573 116 | 2 0.920573 117 | 3 1.08628 118 | 119 | 2 120 | 6 7 121 | 2 2 122 | 4 123 | 0 0.673644 124 | 1 1.48446 125 | 2 1.48446 126 | 3 0.673644 127 | 128 | 2 129 | 7 11 130 | 2 2 131 | 4 132 | 0 0.708219 133 | 1 1.41199 134 | 2 1.41199 135 | 3 0.708219 136 | 137 | 2 138 | 8 12 139 | 2 2 140 | 4 141 | 0 1.38777 142 | 1 0.720582 143 | 2 0.720582 144 | 3 1.38777 145 | 146 | 2 147 | 8 9 148 | 2 2 149 | 4 150 | 0 0.409675 151 | 1 2.44096 152 | 2 2.44096 153 | 3 0.409675 154 | 155 | 2 156 | 9 13 157 | 2 2 158 | 4 159 | 0 1.20244 160 | 1 0.831645 161 | 2 0.831645 162 | 3 1.20244 163 | 164 | 2 165 | 9 10 166 | 2 2 167 | 4 168 | 0 0.700179 169 | 1 1.42821 170 | 2 1.42821 171 | 3 0.700179 172 | 173 | 2 174 | 10 14 175 | 2 2 176 | 4 177 | 0 0.684168 178 | 1 1.46163 179 | 2 1.46163 180 | 3 0.684168 181 | 182 | 2 183 | 10 11 184 | 2 2 185 | 4 186 | 0 2.12998 187 | 1 0.469487 188 | 2 0.469487 189 | 3 2.12998 190 | 191 | 2 192 | 11 15 193 | 2 2 194 | 4 195 | 0 0.675744 196 | 1 1.47985 197 | 2 1.47985 198 | 3 0.675744 199 | 200 | 2 201 | 12 13 202 | 2 2 203 | 4 204 | 0 0.895744 205 | 1 1.11639 206 | 2 1.11639 207 | 3 0.895744 208 | 209 | 2 210 | 13 14 211 | 2 2 212 | 4 213 | 0 0.797362 214 | 1 1.25414 215 | 2 1.25414 216 | 3 0.797362 217 | 218 | 2 219 | 14 15 220 | 2 2 221 | 4 222 | 0 0.765242 223 | 1 1.30678 224 | 2 1.30678 225 | 3 0.765242 226 | 227 | 1 228 | 0 229 | 2 230 | 2 231 | 0 0.784958 232 | 1 1.27395 233 | 234 | 1 235 | 1 236 | 2 237 | 2 238 | 0 1.22582 239 | 1 0.815779 240 | 241 | 1 242 | 2 243 | 2 244 | 2 245 | 0 1.03047 246 | 1 0.970432 247 | 248 | 1 249 | 3 250 | 2 251 | 2 252 | 0 0.61121 253 | 1 1.6361 254 | 255 | 1 256 | 4 257 | 2 258 | 2 259 | 0 1.26126 260 | 1 0.792857 261 | 262 | 1 263 | 5 264 | 2 265 | 2 266 | 0 1.06453 267 | 1 0.939384 268 | 269 | 1 270 | 6 271 | 2 272 | 2 273 | 0 0.988982 274 | 1 1.01114 275 | 276 | 1 277 | 7 278 | 2 279 | 2 280 | 0 0.983169 281 | 1 1.01712 282 | 283 | 1 284 | 8 285 | 2 286 | 2 287 | 0 0.715963 288 | 1 1.39672 289 | 290 | 1 291 | 9 292 | 2 293 | 2 294 | 0 1.14095 295 | 1 0.876466 296 | 297 | 1 298 | 10 299 | 2 300 | 2 301 | 0 1.15512 302 | 1 0.865708 303 | 304 | 1 305 | 11 306 | 2 307 | 2 308 | 0 1.18486 309 | 1 0.843984 310 | 311 | 1 312 | 12 313 | 2 314 | 2 315 | 0 0.916541 316 | 1 1.09106 317 | 318 | 1 319 | 13 320 | 2 321 | 2 322 | 0 2.61467 323 | 1 0.382458 324 | 325 | 1 326 | 14 327 | 2 328 | 2 329 | 0 0.725142 330 | 1 1.37904 331 | 332 | 1 333 | 15 334 | 2 335 | 2 336 | 0 1.43262 337 | 1 0.698024 338 | -------------------------------------------------------------------------------- /tests/testregression: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TMPFILE1=`mktemp /var/tmp/testfast.XXXXXX` 3 | trap 'rm -f $TMP_FILE' 0 1 15 4 | 5 | ./testall testfast.fg > $TMPFILE1 6 | diff -s $TMPFILE1 testfast.out || exit 1 7 | 8 | rm -f $TMPFILE1 9 | -------------------------------------------------------------------------------- /tests/testregression.bat: -------------------------------------------------------------------------------- 1 | testall testfast.fg | sed "s/\(e[+-]\)0/\1/g" > testfast.out.tmp 2 | diff -s testfast.out.tmp testfast.out 3 | del testfast.out.tmp 4 | -------------------------------------------------------------------------------- /tests/twofactors.fg: -------------------------------------------------------------------------------- 1 | 2 2 | 3 | 2 4 | 0 1 5 | 2 2 6 | 4 7 | 0 0.570273 8 | 1 0.702232 9 | 2 0.774333 10 | 3 3.41627 11 | 12 | 2 13 | 2 3 14 | 2 2 15 | 4 16 | 0 1.51657 17 | 1 0.920425 18 | 2 0.254792 19 | 3 1.50469 20 | -------------------------------------------------------------------------------- /tests/unit/alldai_test.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | using namespace dai; 15 | 16 | 17 | const double tol = 1e-8; 18 | 19 | 20 | #define BOOST_TEST_MODULE DAIAlgTest 21 | 22 | 23 | #include 24 | 25 | 26 | BOOST_AUTO_TEST_CASE( newInfAlgTest ) { 27 | Var v0( 0, 2 ); 28 | Var v1( 1, 2 ); 29 | Var v2( 2, 2 ); 30 | Var v3( 3, 2 ); 31 | VarSet v01( v0, v1 ); 32 | VarSet v02( v0, v2 ); 33 | VarSet v03( v0, v3 ); 34 | VarSet v12( v1, v2 ); 35 | VarSet v13( v1, v3 ); 36 | VarSet v23( v2, v3 ); 37 | std::vector facs; 38 | facs.push_back( createFactorIsing( v0, v1, 1.0 ) ); 39 | facs.push_back( createFactorIsing( v1, v2, 1.0 ) ); 40 | facs.push_back( createFactorIsing( v2, v3, 1.0 ) ); 41 | facs.push_back( createFactorIsing( v3, v0, 1.0 ) ); 42 | facs.push_back( createFactorIsing( v0, -1.0 ) ); 43 | facs.push_back( createFactorIsing( v1, -1.0 ) ); 44 | facs.push_back( createFactorIsing( v2, -1.0 ) ); 45 | facs.push_back( createFactorIsing( v3, 1.0 ) ); 46 | Factor joint = facs[0] * facs[1] * facs[2] * facs[3] * facs[4] * facs[5] * facs[6] * facs[7]; 47 | FactorGraph fg( facs ); 48 | VarSet vs = v01; 49 | 50 | InfAlg* ia = newInfAlg( "EXACT", fg, PropertySet()("verbose",(size_t)0) ); 51 | ia->init(); 52 | ia->run(); 53 | BOOST_CHECK( dist( ia->belief( v01 ), joint.marginal( vs ), DISTTV ) < tol ); 54 | BOOST_CHECK( dist( calcMarginal( *ia, vs, true ), joint.marginal( vs ), DISTTV ) < tol ); 55 | delete ia; 56 | 57 | ia = newInfAlgFromString( "EXACT[verbose=0]", fg ); 58 | ia->init(); 59 | ia->run(); 60 | BOOST_CHECK( dist( ia->belief( v01 ), joint.marginal( vs ), DISTTV ) < tol ); 61 | BOOST_CHECK( dist( calcMarginal( *ia, vs, true ), joint.marginal( vs ), DISTTV ) < tol ); 62 | delete ia; 63 | 64 | std::map aliases; 65 | aliases["alias"] = "EXACT[verbose=1]"; 66 | ia = newInfAlgFromString( "alias[verbose=0]", fg, aliases ); 67 | ia->init(); 68 | ia->run(); 69 | BOOST_CHECK( dist( ia->belief( v01 ), joint.marginal( vs ), DISTTV ) < tol ); 70 | BOOST_CHECK( dist( calcMarginal( *ia, vs, true ), joint.marginal( vs ), DISTTV ) < tol ); 71 | delete ia; 72 | } 73 | 74 | 75 | BOOST_AUTO_TEST_CASE( parseTest ) { 76 | std::pair nameProps = parseNameProperties( "name" ); 77 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 78 | BOOST_CHECK_EQUAL( nameProps.second.size(), 0 ); 79 | 80 | nameProps = parseNameProperties( "name[]" ); 81 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 82 | BOOST_CHECK_EQUAL( nameProps.second.size(), 0 ); 83 | 84 | nameProps = parseNameProperties( "name[key1=value,key2=0.5]" ); 85 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 86 | BOOST_CHECK_EQUAL( nameProps.second.size(), 2 ); 87 | BOOST_CHECK( nameProps.second.hasKey( "key1" ) ); 88 | BOOST_CHECK( nameProps.second.hasKey( "key2" ) ); 89 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key1"), "value" ); 90 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key2"), "0.5" ); 91 | 92 | std::map aliases; 93 | aliases["alias"] = "name[key1=other]"; 94 | 95 | nameProps = parseNameProperties( "alias", aliases ); 96 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 97 | BOOST_CHECK_EQUAL( nameProps.second.size(), 1 ); 98 | BOOST_CHECK( nameProps.second.hasKey( "key1" ) ); 99 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key1"), "other" ); 100 | 101 | nameProps = parseNameProperties( "alias[]", aliases ); 102 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 103 | BOOST_CHECK_EQUAL( nameProps.second.size(), 1 ); 104 | BOOST_CHECK( nameProps.second.hasKey( "key1" ) ); 105 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key1"), "other" ); 106 | 107 | nameProps = parseNameProperties( "alias[key1=value,key2=0.5]", aliases ); 108 | BOOST_CHECK_EQUAL( nameProps.first, "name" ); 109 | BOOST_CHECK_EQUAL( nameProps.second.size(), 2 ); 110 | BOOST_CHECK( nameProps.second.hasKey( "key1" ) ); 111 | BOOST_CHECK( nameProps.second.hasKey( "key2" ) ); 112 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key1"), "value" ); 113 | BOOST_CHECK_EQUAL( nameProps.second.getAs("key2"), "0.5" ); 114 | } 115 | 116 | 117 | BOOST_AUTO_TEST_CASE( readAliasFileTest ) { 118 | std::ofstream outfile; 119 | std::string filename( "alldai_test.aliases" ); 120 | outfile.open( filename.c_str() ); 121 | if( outfile.is_open() ) { 122 | outfile << "alias:\tname[key1=other]" << std::endl; 123 | outfile.close(); 124 | } else 125 | DAI_THROWE(CANNOT_WRITE_FILE,"Cannot write to file " + std::string(filename)); 126 | 127 | std::map aliases; 128 | aliases["alias"] = "name[key1=other]"; 129 | 130 | std::map aliases2 = readAliasesFile( filename ); 131 | BOOST_CHECK( aliases == aliases2 ); 132 | } 133 | -------------------------------------------------------------------------------- /tests/unit/daialg_test.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | using namespace dai; 15 | 16 | 17 | const double tol = 1e-8; 18 | 19 | 20 | #define BOOST_TEST_MODULE DAIAlgTest 21 | 22 | 23 | #include 24 | 25 | 26 | BOOST_AUTO_TEST_CASE( calcMarginalTest ) { 27 | Var v0( 0, 2 ); 28 | Var v1( 1, 2 ); 29 | Var v2( 2, 2 ); 30 | Var v3( 3, 2 ); 31 | VarSet v01( v0, v1 ); 32 | VarSet v02( v0, v2 ); 33 | VarSet v03( v0, v3 ); 34 | VarSet v12( v1, v2 ); 35 | VarSet v13( v1, v3 ); 36 | VarSet v23( v2, v3 ); 37 | std::vector facs; 38 | facs.push_back( createFactorIsing( v0, v1, 1.0 ) ); 39 | facs.push_back( createFactorIsing( v1, v2, 1.0 ) ); 40 | facs.push_back( createFactorIsing( v2, v3, 1.0 ) ); 41 | facs.push_back( createFactorIsing( v3, v0, 1.0 ) ); 42 | facs.push_back( createFactorIsing( v0, -1.0 ) ); 43 | facs.push_back( createFactorIsing( v1, -1.0 ) ); 44 | facs.push_back( createFactorIsing( v2, -1.0 ) ); 45 | facs.push_back( createFactorIsing( v3, 1.0 ) ); 46 | Factor joint = facs[0] * facs[1] * facs[2] * facs[3] * facs[4] * facs[5] * facs[6] * facs[7]; 47 | FactorGraph fg( facs ); 48 | ExactInf ei( fg, PropertySet()("verbose",(size_t)0) ); 49 | ei.init(); 50 | ei.run(); 51 | VarSet vs; 52 | 53 | vs = v0; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 54 | vs = v1; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 55 | vs = v2; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 56 | vs = v3; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 57 | vs = v01; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 58 | vs = v02; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 59 | vs = v03; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 60 | vs = v12; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 61 | vs = v13; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 62 | vs = v23; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 63 | vs = v01 | v2; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 64 | vs = v01 | v3; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 65 | vs = v02 | v3; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 66 | vs = v12 | v3; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 67 | vs = v01 | v23; BOOST_CHECK( dist( calcMarginal( ei, vs, false ), joint.marginal( vs ), DISTTV ) < tol ); 68 | } 69 | 70 | 71 | BOOST_AUTO_TEST_CASE( calcPairBeliefsTest ) { 72 | Var v0( 0, 2 ); 73 | Var v1( 1, 2 ); 74 | Var v2( 2, 2 ); 75 | Var v3( 3, 2 ); 76 | VarSet v01( v0, v1 ); 77 | VarSet v02( v0, v2 ); 78 | VarSet v03( v0, v3 ); 79 | VarSet v12( v1, v2 ); 80 | VarSet v13( v1, v3 ); 81 | VarSet v23( v2, v3 ); 82 | std::vector facs; 83 | facs.push_back( createFactorIsing( v0, v1, 1.0 ) ); 84 | facs.push_back( createFactorIsing( v1, v2, 1.0 ) ); 85 | facs.push_back( createFactorIsing( v2, v3, 1.0 ) ); 86 | facs.push_back( createFactorIsing( v3, v0, 1.0 ) ); 87 | facs.push_back( createFactorIsing( v0, -1.0 ) ); 88 | facs.push_back( createFactorIsing( v1, -1.0 ) ); 89 | facs.push_back( createFactorIsing( v2, -1.0 ) ); 90 | facs.push_back( createFactorIsing( v3, 1.0 ) ); 91 | Factor joint = facs[0] * facs[1] * facs[2] * facs[3] * facs[4] * facs[5] * facs[6] * facs[7]; 92 | FactorGraph fg( facs ); 93 | ExactInf ei( fg, PropertySet()("verbose",(size_t)0) ); 94 | ei.init(); 95 | ei.run(); 96 | VarSet vs; 97 | 98 | std::vector pb = calcPairBeliefs( ei, v01 | v23, false, false ); 99 | BOOST_CHECK( dist( pb[0], joint.marginal( v01 ), DISTTV ) < tol ); 100 | BOOST_CHECK( dist( pb[1], joint.marginal( v02 ), DISTTV ) < tol ); 101 | BOOST_CHECK( dist( pb[2], joint.marginal( v03 ), DISTTV ) < tol ); 102 | BOOST_CHECK( dist( pb[3], joint.marginal( v12 ), DISTTV ) < tol ); 103 | BOOST_CHECK( dist( pb[4], joint.marginal( v13 ), DISTTV ) < tol ); 104 | BOOST_CHECK( dist( pb[5], joint.marginal( v23 ), DISTTV ) < tol ); 105 | 106 | pb = calcPairBeliefs( ei, v01 | v23, false, true ); 107 | BOOST_CHECK( dist( pb[0], joint.marginal( v01 ), DISTTV ) < tol ); 108 | BOOST_CHECK( dist( pb[1], joint.marginal( v02 ), DISTTV ) < tol ); 109 | BOOST_CHECK( dist( pb[2], joint.marginal( v03 ), DISTTV ) < tol ); 110 | BOOST_CHECK( dist( pb[3], joint.marginal( v12 ), DISTTV ) < tol ); 111 | BOOST_CHECK( dist( pb[4], joint.marginal( v13 ), DISTTV ) < tol ); 112 | BOOST_CHECK( dist( pb[5], joint.marginal( v23 ), DISTTV ) < tol ); 113 | } 114 | -------------------------------------------------------------------------------- /tests/unit/enum_test.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | using namespace dai; 16 | 17 | 18 | #define BOOST_TEST_MODULE EnumTest 19 | 20 | 21 | #include 22 | 23 | 24 | DAI_ENUM(colors,RED,GREEN,BLUE); 25 | 26 | 27 | BOOST_AUTO_TEST_CASE( ConstructorsTest ) { 28 | colors c; 29 | BOOST_CHECK( c == colors::RED ); 30 | BOOST_CHECK_EQUAL( static_cast(c), 0 ); 31 | BOOST_CHECK_EQUAL( strcmp( static_cast(c), "RED" ), 0 ); 32 | 33 | colors d(colors::GREEN); 34 | BOOST_CHECK( d == colors::GREEN ); 35 | BOOST_CHECK_EQUAL( static_cast(d), 1 ); 36 | BOOST_CHECK_EQUAL( strcmp( static_cast(d), "GREEN" ), 0 ); 37 | 38 | colors e("BLUE"); 39 | BOOST_CHECK( e == colors::BLUE ); 40 | BOOST_CHECK_EQUAL( static_cast(e), 2 ); 41 | BOOST_CHECK_EQUAL( strcmp( static_cast(e), "BLUE" ), 0 ); 42 | 43 | BOOST_CHECK_THROW( colors f("BLUEISH"), Exception ); 44 | 45 | colors f = e; 46 | colors g(f); 47 | BOOST_CHECK( f == colors::BLUE ); 48 | BOOST_CHECK( g == colors::BLUE ); 49 | BOOST_CHECK( static_cast(f) == static_cast(e) ); 50 | BOOST_CHECK( static_cast(e) == static_cast(g) ); 51 | BOOST_CHECK( static_cast(f) == static_cast(g) ); 52 | } 53 | 54 | 55 | BOOST_AUTO_TEST_CASE( StreamTest ) { 56 | std::stringstream ss1, ss2, ss3, ss4, ss5, ss6, ss7; 57 | std::string s; 58 | 59 | ss1 << colors(colors::RED); 60 | ss1 >> s; 61 | BOOST_CHECK_EQUAL( s, "RED" ); 62 | 63 | ss2 << colors(colors::GREEN); 64 | std::getline( ss2, s ); 65 | BOOST_CHECK_EQUAL( s, "GREEN" ); 66 | 67 | ss3 << colors(colors::BLUE); 68 | ss3 >> s; 69 | BOOST_CHECK_EQUAL( s, "BLUE" ); 70 | 71 | colors c; 72 | ss4 << colors(colors::RED); 73 | ss4 >> c; 74 | BOOST_CHECK_EQUAL( c, colors::RED ); 75 | ss5 << colors(colors::GREEN); 76 | ss5 >> c; 77 | BOOST_CHECK_EQUAL( c, colors::GREEN ); 78 | ss6 << colors(colors::BLUE); 79 | ss6 >> c; 80 | BOOST_CHECK_EQUAL( c, colors::BLUE ); 81 | 82 | ss7 << "BLUEISH"; 83 | BOOST_CHECK_THROW( ss7 >> c, Exception ); 84 | } 85 | -------------------------------------------------------------------------------- /tests/unit/exceptions_test.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | using namespace dai; 14 | 15 | 16 | #define BOOST_TEST_MODULE ExceptionsTest 17 | 18 | 19 | #include 20 | 21 | 22 | BOOST_AUTO_TEST_CASE( ExceptionsTest ) { 23 | BOOST_CHECK_THROW( DAI_THROW(NOT_IMPLEMENTED), Exception ); 24 | BOOST_CHECK_THROW( DAI_THROW(NOT_IMPLEMENTED), std::runtime_error ); 25 | BOOST_CHECK_THROW( DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message"), Exception ); 26 | BOOST_CHECK_THROW( DAI_THROWE(NOT_IMPLEMENTED,"Detailed error messgae"), std::runtime_error ); 27 | BOOST_CHECK_THROW( DAI_ASSERT( 0 ), Exception ); 28 | BOOST_CHECK_THROW( DAI_ASSERT( 0 == 1 ), std::runtime_error ); 29 | 30 | try { 31 | DAI_THROW(NOT_IMPLEMENTED); 32 | } catch( Exception& e ) { 33 | BOOST_CHECK_EQUAL( e.getCode(), Exception::NOT_IMPLEMENTED ); 34 | BOOST_CHECK_EQUAL( e.getMsg(), std::string("Feature not implemented") ); 35 | BOOST_CHECK_EQUAL( e.getDetailedMsg(), std::string("") ); 36 | BOOST_CHECK_EQUAL( e.getFilename(), std::string("tests/unit/exceptions_test.cpp") ); 37 | BOOST_CHECK_EQUAL( e.getFunction(), std::string("void ExceptionsTest::test_method()") ); 38 | BOOST_CHECK_EQUAL( e.getLine(), std::string("31") ); 39 | } 40 | 41 | try { 42 | DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message"); 43 | } catch( Exception& e ) { 44 | BOOST_CHECK_EQUAL( e.getCode(), Exception::NOT_IMPLEMENTED ); 45 | BOOST_CHECK_EQUAL( e.getMsg(), std::string("Feature not implemented") ); 46 | BOOST_CHECK_EQUAL( e.getDetailedMsg(), std::string("Detailed error message") ); 47 | BOOST_CHECK_EQUAL( e.getFilename(), std::string("tests/unit/exceptions_test.cpp") ); 48 | BOOST_CHECK_EQUAL( e.getFunction(), std::string("void ExceptionsTest::test_method()") ); 49 | BOOST_CHECK_EQUAL( e.getLine(), std::string("42") ); 50 | } 51 | 52 | try { 53 | DAI_THROW(NOT_IMPLEMENTED); 54 | } catch( std::runtime_error& e ) { 55 | BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented [File tests/unit/exceptions_test.cpp, line 53, function: void ExceptionsTest::test_method()]") ); 56 | } 57 | 58 | try { 59 | DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message"); 60 | } catch( std::runtime_error& e ) { 61 | BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented: Detailed error message [File tests/unit/exceptions_test.cpp, line 59, function: void ExceptionsTest::test_method()]") ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /tests/unit/var_test.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | 12 | 13 | using namespace dai; 14 | 15 | 16 | #define BOOST_TEST_MODULE VarTest 17 | 18 | 19 | #include 20 | 21 | 22 | BOOST_AUTO_TEST_CASE( ConstructorsTest ) { 23 | // check constructors 24 | Var x; 25 | BOOST_CHECK_EQUAL( x.label(), 0 ); 26 | BOOST_CHECK_EQUAL( x.states(), 0 ); 27 | 28 | x = Var( 0, 2 ); 29 | BOOST_CHECK_EQUAL( x.label(), 0 ); 30 | BOOST_CHECK_EQUAL( x.states(), 2 ); 31 | } 32 | 33 | BOOST_AUTO_TEST_CASE( AccMutTest ) { 34 | // check states and labels mutators 35 | Var x; 36 | x.states() = 3; 37 | BOOST_CHECK_EQUAL( x.states(), 3 ); 38 | 39 | x.label() = 5; 40 | BOOST_CHECK_EQUAL( x.label(), 5 ); 41 | } 42 | 43 | BOOST_AUTO_TEST_CASE( ComparisonTest ) { 44 | // check comparison operators 45 | Var x( 5, 3 ); 46 | Var y( 6, 3 ); 47 | Var z( 5, 3 ); 48 | BOOST_CHECK( x < y ); 49 | BOOST_CHECK( !(x < z) ); 50 | BOOST_CHECK( y > x ); 51 | BOOST_CHECK( !(z > x) ); 52 | BOOST_CHECK( x <= y ); 53 | BOOST_CHECK( x <= z ); 54 | BOOST_CHECK( !(x >= y) ); 55 | BOOST_CHECK( x >= z ); 56 | BOOST_CHECK( !(x == y) ); 57 | BOOST_CHECK( x == z ); 58 | BOOST_CHECK( x != y ); 59 | BOOST_CHECK( !(x != z) ); 60 | } 61 | 62 | BOOST_AUTO_TEST_CASE( StreamTest ) { 63 | // check stream output 64 | Var x( 5, 3 ); 65 | std::stringstream ss; 66 | ss << x; 67 | std::string s; 68 | ss >> s; 69 | BOOST_CHECK_EQUAL( s, "x5" ); 70 | } 71 | -------------------------------------------------------------------------------- /tests/zeroes1.fg: -------------------------------------------------------------------------------- 1 | # Factor graph that contains many zeroes (useful for testing purposes) 2 | 3 3 | 4 | 1 5 | 0 6 | 2 7 | 2 8 | 0 0 9 | 1 1 10 | 11 | 2 12 | 0 1 13 | 2 2 14 | 4 15 | 0 1 16 | 1 2 17 | 2 2 18 | 3 1 19 | 20 | 2 21 | 1 2 22 | 2 2 23 | 4 24 | 0 1 25 | 1 2 26 | 2 2 27 | 3 1 28 | -------------------------------------------------------------------------------- /utils/fg2dot.cpp: -------------------------------------------------------------------------------- 1 | /* This file is part of libDAI - http://www.libdai.org/ 2 | * 3 | * Copyright (c) 2006-2011, The libDAI authors. All rights reserved. 4 | * 5 | * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 6 | */ 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | using namespace dai; 17 | using namespace std; 18 | 19 | 20 | int main( int argc, char *argv[] ) { 21 | if( argc != 3 ) { 22 | // Display help message if number of command line arguments is incorrect 23 | cout << "This program is part of libDAI - http://www.libdai.org/" << endl << endl; 24 | cout << "Usage: ./fg2dot " << endl << endl; 25 | cout << "Converts a libDAI factor graph file to a GraphViz .dot file for visualization." << endl; 26 | cout << "The .dot file can be converted to .ps (PostScript) by" << endl; 27 | cout << "'neato -T ps out.dot > out.ps' or by 'dot -T ps out.dot > out.ps'" << endl << endl; 28 | return 1; 29 | } else { 30 | // Read factorgraph 31 | FactorGraph fg; 32 | char *infile = argv[1]; 33 | fg.ReadFromFile( infile ); 34 | 35 | // Open output file for writing (except if filename equals "-") 36 | ostream *os = &cout; 37 | ofstream outfile; 38 | if( string( argv[2] ) != "-" ) { 39 | outfile.open( argv[2] ); 40 | if( !outfile.is_open() ) { 41 | cerr << "Cannot open " << argv[2] << " for writing" << endl; 42 | return 1; 43 | } 44 | os = &outfile; 45 | } // else, write to cout 46 | 47 | // Write the .dot file 48 | fg.printDot( *os ); 49 | 50 | return 0; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /utils/viewfg: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./fg2dot $1 - | neato -T ps | gv - 3 | --------------------------------------------------------------------------------