Cleanups of matlab, BP; small improvement of utils/fginfo
authorJoris Mooij <jorism@osun.tuebingen.mpg.de>
Wed, 8 Oct 2008 09:02:18 +0000 (11:02 +0200)
committerJoris Mooij <jorism@osun.tuebingen.mpg.de>
Wed, 8 Oct 2008 09:02:18 +0000 (11:02 +0200)
17 files changed:
Makefile
Makefile.shared
Makefile.win
include/dai/matlab/matlab.h [new file with mode: 0644]
matlab/dai.cpp [deleted file]
matlab/dai_potstrength.cpp [deleted file]
matlab/dai_readfg.cpp [deleted file]
matlab/dai_writefg.cpp [deleted file]
matlab/matlab.cpp [deleted file]
matlab/matlab.h [deleted file]
src/bp.cpp
src/matlab/dai.cpp [new file with mode: 0644]
src/matlab/dai_potstrength.cpp [new file with mode: 0644]
src/matlab/dai_readfg.cpp [new file with mode: 0644]
src/matlab/dai_writefg.cpp [new file with mode: 0644]
src/matlab/matlab.cpp [new file with mode: 0644]
utils/fginfo.cpp

index 4adbaff..5c1fdd7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,7 @@ INC=include/dai
 SRC=src
 LIB=lib
 
-# Extensions (library, object, executable, MEX file extensions)
+# Extensions (library, object, executable, matlab compiled MEX file)
 LE=.a
 OE=.o
 EE=
@@ -59,7 +59,7 @@ CC=g++
 CCO=-o
 
 # Flags for the C++ compiler
-CCFLAGS=-Wno-deprecated -Wall -W -Wextra -fpic -I./include -Llib -O3 #-pg
+CCFLAGS=-O3 -Wno-deprecated -Wall -W -Wextra -fpic -Iinclude -Llib
 ifdef DEBUG
 CCFLAGS:=$(CCFLAGS) -g -DDAI_DEBUG
 endif
@@ -100,10 +100,9 @@ endif
 
 ifdef WITH_MATLAB
 # Replace the following by the directory where Matlab has been installed
-MATLABDIR=/opt/matlab/bin
-# Replace the following with the extension of compiled MEX files on this platform, e.g. .mexglx for x86
-MEX=$(MATLABDIR)/mex
-MEXFLAGS=-I.
+MATLABDIR=/agbs/share/sw/matlab
+MEX=$(MATLABDIR)/bin/mex
+MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#'-O3 -Wno-deprecated -Wall -W -Wextra -fpic'
 ifdef DEBUG
 MEXFLAGS:=$(MEXFLAGS) -g -DDAI_DEBUG
 endif
@@ -143,8 +142,8 @@ doc : $(INC)/*.h $(SRC)/*.cpp doxygen.conf
 
 .PHONY : clean
 clean :
-       -rm *$(OE) 
-       -rm matlab/*$(ME) matlab/*$(OE) 
+       -rm *$(OE)
+       -rm matlab/*$(ME)
        -rm example$(EE) tests/testdai$(EE) utils/fg2dot$(EE) utils/createfg$(EE) utils/fginfo$(EE)
        -rm -R doc
        -rm -R lib
index 581a07b..b9a1d94 100644 (file)
@@ -91,20 +91,20 @@ tests/testdai$(EE) : tests/testdai.cpp $(HEADERS) $(LIB)/libdai$(LE)
 # MATLAB INTERFACE
 ###################
 
-matlab/dai.$(ME) : matlab/dai.cpp $(HEADERS) matlab/matlab$(OE) $(LIB)/libdai$(LE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai matlab/dai.cpp matlab/matlab$(OE) $(LIB)/libdai$(LE)
+matlab/dai$(ME) : $(SRC)/matlab/dai.cpp $(HEADERS) matlab$(OE) $(LIB)/libdai$(LE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai $(SRC)/matlab/dai.cpp matlab$(OE) $(LIB)/libdai$(LE)
 
-matlab/dai_readfg.$(ME) : matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg matlab/dai_readfg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
+matlab/dai_readfg$(ME) : $(SRC)/matlab/dai_readfg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_readfg $(SRC)/matlab/dai_readfg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
 
-matlab/dai_writefg.$(ME) : matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg matlab/dai_writefg.cpp factorgraph$(OE) matlab/matlab$(OE) exceptions$(OE)
+matlab/dai_writefg$(ME) : $(SRC)/matlab/dai_writefg.cpp $(HEADERS) factorgraph$(OE) matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_writefg $(SRC)/matlab/dai_writefg.cpp factorgraph$(OE) matlab$(OE) exceptions$(OE)
 
-matlab/dai_potstrength.$(ME) : matlab/dai_potstrength.cpp $(HEADERS) matlab/matlab$(OE) exceptions$(OE)
-       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength matlab/dai_potstrength.cpp matlab/matlab$(OE) exceptions$(OE)
+matlab/dai_potstrength$(ME) : $(SRC)/matlab/dai_potstrength.cpp $(HEADERS) matlab$(OE) exceptions$(OE)
+       $(MEX) $(MEXFLAGS) -o matlab/dai_potstrength $(SRC)/matlab/dai_potstrength.cpp matlab$(OE) exceptions$(OE)
 
-matlab/matlab$(OE) : matlab/matlab.cpp matlab/matlab.h $(HEADERS)
-       $(MEX) $(MEXFLAGS) -outdir matlab -c matlab/matlab.cpp
+matlab$(OE) : $(SRC)/matlab/matlab.cpp $(INC)/matlab/matlab.h $(HEADERS)
+       $(MEX) $(MEXFLAGS) -c $(SRC)/matlab/matlab.cpp
 
 
 # UTILS
index ec700eb..2a3dfa7 100755 (executable)
@@ -41,7 +41,7 @@ INC=include/dai
 SRC=src\r
 LIB=lib\r
 \r
-# Extensions (library, object, executable, MEX file extensions)\r
+# Extensions (library, object, executable, matlab compiled MEX file)\r
 LE=.lib\r
 OE=.obj\r
 EE=.exe\r
@@ -59,7 +59,7 @@ CC=cl
 CCO=/Fe\r
 \r
 # Flags for the C++ compiler\r
-CCFLAGS=/I./include /IC:\boost_1_36_0 /EHsc /Ox\r
+CCFLAGS=/Iinclude /IC:\boost_1_36_0 /EHsc /Ox\r
 !IFDEF DEBUG\r
 CCFLAGS=$(CCFLAGS) /Zi /DDAI_DEBUG\r
 !ENDIF\r
@@ -100,10 +100,9 @@ OBJECTS=$(OBJECTS) mr$(OE)
 \r
 !IFDEF WITH_MATLAB\r
 # Replace the following by the directory where Matlab has been installed\r
-MATLABDIR=/opt/matlab/bin\r
-# Replace the following with the extension of compiled MEX files on this platform, e.g. .mexglx for x86\r
-MEX=$(MATLABDIR)/mex\r
-MEXFLAGS=-I.\r
+MATLABDIR=c:\matlab\r
+MEX=$(MATLABDIR)\bin\mex\r
+MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#"/EHsc /Ox"\r
 !IFDEF DEBUG\r
 MEXFLAGS=$(MEXFLAGS) -g /DDAI_DEBUG\r
 !ENDIF\r
@@ -141,6 +140,6 @@ doc : $(INC)/*.h $(SRC)/*.cpp doxygen.conf
        doxygen doxygen.conf\r
 \r
 clean :\r
-       del *$(OE) *.ilk *.pdb *$(EE) matlab\*$(ME) matlab\*$(OE) tests\testdai$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE)\r
+       del *$(OE) *.ilk *.pdb *$(EE) matlab\*$(ME) tests\testdai$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE)\r
 \r
 !INCLUDE Makefile.shared\r
diff --git a/include/dai/matlab/matlab.h b/include/dai/matlab/matlab.h
new file mode 100644 (file)
index 0000000..6d6dc84
--- /dev/null
@@ -0,0 +1,53 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#ifndef __defined_libdai_matlab_h
+#define __defined_libdai_matlab_h
+
+
+#include "mex.h"
+#include <dai/factor.h>
+
+
+namespace dai {
+
+
+#ifdef SMALLMEM
+    typedef int mwSize;
+    typedef int mwIndex;
+#endif
+
+
+/// Convert vector<Factor> structure to a cell vector of CPTAB-like structs
+mxArray *Factors2mx(const std::vector<Factor> &Ps);
+
+/// Convert cell vector of CPTAB-like structs to vector<Factor>
+std::vector<Factor> mx2Factors(const mxArray *psi, long verbose);
+
+/// Convert CPTAB-like struct to Factor
+Factor mx2Factor(const mxArray *psi);
+
+
+} // end of namespace dai
+
+
+#endif
diff --git a/matlab/dai.cpp b/matlab/dai.cpp
deleted file mode 100644 (file)
index c6f26dd..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-/*=================================================================*
- *                                                                 * 
- * This is a MEX-file for MATLAB.                                  *
- *                                                                 * 
- *   [logZ,q,md] = dai(psi,method,opts);                           *
- *                                                                 * 
- *=================================================================*/
-
-
-#include <iostream>
-#include <dai/matlab/matlab.h>
-#include "mex.h"
-#include <dai/alldai.h>
-
-
-using namespace std;
-using namespace dai;
-
-
-/* Input Arguments */
-
-#define PSI_IN          prhs[0]
-#define METHOD_IN       prhs[1]
-#define OPTS_IN         prhs[2]
-#define NR_IN           3
-
-
-/* Output Arguments */
-
-#define LOGZ_OUT        plhs[0]
-#define Q_OUT           plhs[1]
-#define MD_OUT          plhs[2]
-#define NR_OUT          3
-
-
-void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
-{ 
-    size_t buflen;
-    
-    /* Check for proper number of arguments */
-    if( (nrhs != NR_IN) || (nlhs != NR_OUT) ) { 
-        mexErrMsgTxt("Usage: [logZ,q,md] = dai(psi,method,opts)\n\n"
-        "\n"
-        "INPUT:  psi        = linear cell array containing the factors \n"
-        "                     psi{i} should be a structure with a Member field\n"
-        "                     and a P field, like a CPTAB).\n"
-        "        method     = name of the method (see README)\n"
-        "        opts       = string of options (see README)\n"
-        "\n"
-        "OUTPUT: logZ       = approximation of the logarithm of the partition sum.\n"
-        "        q          = linear cell array containing all final beliefs.\n"
-        "        md         = maxdiff (final linf-dist between new and old single node beliefs).\n");
-    } 
-    
-    char *method;
-    char *opts;
-
-
-    // Get psi and construct factorgraph
-    vector<Factor> factors = mx2Factors(PSI_IN, 0);
-    FactorGraph fg(factors);
-    long nr_v = fg.nrVars();
-
-    // Get method
-    buflen = mxGetN( METHOD_IN ) + 1;
-    method = (char *)mxCalloc( buflen, sizeof(char) );
-    mxGetString( METHOD_IN, method, buflen );
-
-    // Get options string
-    buflen = mxGetN( OPTS_IN ) + 1;
-    opts = (char *)mxCalloc( buflen, sizeof(char) );
-    mxGetString( OPTS_IN, opts, buflen );
-    // Convert to options object props
-    stringstream ss;
-    ss << opts;
-    Properties props;
-    ss >> props;
-    
-    // Construct InfAlg object, init and run
-    InfAlg *obj = newInfAlg( method, fg, props );
-    obj->init();
-    obj->run();
-
-
-    // Save logZ
-    double logZ = obj->logZ();
-
-    // Save maxdiff
-    double maxdiff = obj->MaxDiff();
-
-
-    // Hand over results to MATLAB
-    LOGZ_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
-    *(mxGetPr(LOGZ_OUT)) = logZ;
-    
-    Q_OUT = Factors2mx(obj->beliefs());
-    
-    MD_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
-    *(mxGetPr(MD_OUT)) = maxdiff;
-
-    
-    return;
-}
diff --git a/matlab/dai_potstrength.cpp b/matlab/dai_potstrength.cpp
deleted file mode 100644 (file)
index af2d2f0..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-/*=================================================================*
- *                                                                 * 
- * This is a MEX-file for MATLAB.                                  *
- *                                                                 * 
- *   N = dai_potstrength(psi,i,j);                                 *
- *                                                                 * 
- *=================================================================*/
-
-
-#include <iostream>
-#include "mex.h"
-#include <dai/matlab/matlab.h>
-#include <dai/factor.h>
-
-
-using namespace std;
-using namespace dai;
-
-
-/* Input Arguments */
-
-#define PSI_IN          prhs[0]
-#define I_IN            prhs[1]
-#define J_IN            prhs[2]
-#define NR_IN           3
-
-
-/* Output Arguments */
-
-#define N_OUT           plhs[0]
-#define NR_OUT          1
-
-
-void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
-{ 
-    long ilabel, jlabel;
-
-    // Check for proper number of arguments
-    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
-        mexErrMsgTxt("Usage: N = dai_potstrength(psi,i,j);\n\n"
-        "\n"
-        "INPUT:  psi        = structure with a Member field and a P field, like a CPTAB.\n"
-        "        i          = label of a variable in psi.\n"
-        "        j          = label of another variable in psi.\n"
-        "\n"
-        "OUTPUT: N          = strength of psi in direction i->j.\n");
-    } 
-    
-    // Get input parameters
-    Factor psi = mx2Factor(PSI_IN);
-    ilabel = (long)*mxGetPr(I_IN);
-    jlabel = (long)*mxGetPr(J_IN);
-
-    // Find variable in psi with label ilabel
-    Var i;
-    for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ )
-        if( n->label() == ilabel ) {
-            i = *n;
-            break;
-        }
-    assert( i.label() == ilabel );
-
-    // Find variable in psi with label jlabel
-    Var j;
-    for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ )
-        if( n->label() == jlabel ) {
-            j = *n;
-            break;
-        }
-    assert( j.label() == jlabel );
-
-    // Calculate N(psi,i,j);
-    double N = psi.strength( i, j );
-    
-    // Hand over result to MATLAB
-    N_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
-    *(mxGetPr(N_OUT)) = N;
-    
-    return;
-}
diff --git a/matlab/dai_readfg.cpp b/matlab/dai_readfg.cpp
deleted file mode 100644 (file)
index 7fcc411..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-/*=================================================================*
- *                                                                 * 
- * This is a MEX-file for MATLAB.                                  *
- *                                                                 * 
- *   [psi] = dai_readfg(filename);                                 *
- *                                                                 * 
- *=================================================================*/
-
-
-#include <iostream>
-#include "mex.h"
-#include <dai/matlab/matlab.h>
-#include <dai/factorgraph.h>
-
-
-using namespace std;
-using namespace dai;
-
-
-/* Input Arguments */
-
-#define FILENAME_IN     prhs[0]
-#define NR_IN           1
-
-
-/* Output Arguments */
-
-#define PSI_OUT         plhs[0]
-#define NR_OUT          1
-
-
-void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
-{ 
-    char *filename;
-
-    
-    // Check for proper number of arguments
-    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
-        mexErrMsgTxt("Usage: [psi] = dai_readfg(filename);\n\n"
-        "\n"
-        "INPUT:  filename   = filename of a .fg file\n"
-        "\n"
-        "OUTPUT: psi        = linear cell array containing the factors\n"
-        "                     (psi{i} is a structure with a Member field\n"
-        "                     and a P field, like a CPTAB).\n");
-    } 
-    
-    // Get input parameters
-    size_t buflen;
-    buflen = mxGetN( FILENAME_IN ) + 1;
-    filename = (char *)mxCalloc( buflen, sizeof(char) );
-    mxGetString( FILENAME_IN, filename, buflen );
-    
-
-    // Read factorgraph
-    FactorGraph fg;
-    try {
-        fg.ReadFromFile( filename );
-    } catch( std::exception &e ) {
-        mexErrMsgTxt( e.what() );
-    }
-
-
-    // Save factors
-    vector<Factor> psi;
-    for( size_t I = 0; I < fg.nrFactors(); I++ )
-        psi.push_back(fg.factor(I));
-    
-
-    // Hand over results to MATLAB
-    PSI_OUT = Factors2mx(psi);
-
-    
-    return;
-}
diff --git a/matlab/dai_writefg.cpp b/matlab/dai_writefg.cpp
deleted file mode 100644 (file)
index bbe1761..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-/*=================================================================*
- *                                                                 * 
- * This is a MEX-file for MATLAB.                                  *
- *                                                                 * 
- *   dai_writefg(psi, filename);                                   *
- *                                                                 * 
- *=================================================================*/
-
-
-#include <iostream>
-#include "mex.h"
-#include <dai/matlab/matlab.h>
-#include <dai/factorgraph.h>
-
-
-using namespace std;
-using namespace dai;
-
-
-/* Input Arguments */
-
-#define PSI_IN          prhs[0]
-#define FILENAME_IN     prhs[1]
-#define NR_IN           2
-
-
-/* Output Arguments */
-
-#define NR_OUT          0
-
-
-void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
-{ 
-    char *filename;
-
-    
-    // Check for proper number of arguments
-    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
-        mexErrMsgTxt("Usage: dai_writefg(psi,filename);\n\n"
-        "\n"
-        "INPUT:  psi        = linear cell array containing the factors\n"
-        "                     (psi{i} should be a structure with a Member field\n"
-        "                     and a P field, like a CPTAB).\n"
-        "        filename   = filename of a .fg file\n");
-    } 
-    
-    // Get input parameters
-    vector<Factor> factors = mx2Factors(PSI_IN,0);
-    
-    size_t buflen;
-    buflen = mxGetN( FILENAME_IN ) + 1;
-    filename = (char *)mxCalloc( buflen, sizeof(char) );
-    mxGetString( FILENAME_IN, filename, buflen );
-    
-    // Construct factorgraph
-    FactorGraph fg(factors);
-    long nr_v = fg.nrVars();
-    long nr_f = fg.nrFactors();
-
-    try {
-        fg.WriteToFile( filename );
-    } catch( std::exception &e ) {
-        mexErrMsgTxt( e.what() );
-    }
-
-    return;
-}
diff --git a/matlab/matlab.cpp b/matlab/matlab.cpp
deleted file mode 100644 (file)
index a2b053e..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-#include <iostream>
-#include <dai/matlab/matlab.h>
-
-
-namespace dai {
-
-
-using namespace std;
-
-
-/* Convert vector<Factor> structure to a cell vector of CPTAB-like structs */
-mxArray *Factors2mx(const vector<Factor> &Ps) {
-    size_t nr = Ps.size();
-
-    mxArray *psi = mxCreateCellMatrix(nr,1);
-    
-    const char *fieldnames[2];
-    fieldnames[0] = "Member";
-    fieldnames[1] = "P";
-    
-    size_t I_ind = 0;
-    for( vector<Factor>::const_iterator I = Ps.begin(); I != Ps.end(); I++, I_ind++ ) {
-        mxArray *Bi = mxCreateStructMatrix(1,1,2,fieldnames);
-
-        mxArray *BiMember = mxCreateDoubleMatrix(1,I->vars().size(),mxREAL);
-        double *BiMember_data = mxGetPr(BiMember);
-        size_t i = 0;
-        vector<mwSize> dims;
-        for( VarSet::const_iterator j = I->vars().begin(); j != I->vars().end(); j++,i++ ) {
-            BiMember_data[i] = j->label();
-            dims.push_back( j->states() );
-        }
-
-        mxArray *BiP = mxCreateNumericArray(I->vars().size(), &(*(dims.begin())), mxDOUBLE_CLASS, mxREAL);
-        double *BiP_data = mxGetPr(BiP);
-        for( size_t j = 0; j < I->states(); j++ )
-            BiP_data[j] = (*I)[j];
-
-        mxSetField(Bi,0,"Member",BiMember);
-        mxSetField(Bi,0,"P",BiP);
-        
-        mxSetCell(psi, I_ind, Bi);
-    }
-    return( psi );
-}
-
-
-/* Convert cell vector of CPTAB-like structs to vector<Factor> */
-vector<Factor> mx2Factors(const mxArray *psi, long verbose) {
-    set<Var> vars;
-    vector<Factor> factors;
-
-    int n1 = mxGetM(psi);
-    int n2 = mxGetN(psi);
-    if( n2 != 1 && n1 != 1 ) 
-        mexErrMsgTxt("psi should be a Nx1 or 1xN cell matrix."); 
-    size_t nr_f = n1;
-    if( n1 == 1 )
-        nr_f = n2;
-
-    // interpret psi, linear cell array of cptabs
-    for( size_t cellind = 0; cellind < nr_f; cellind++ ) {
-        if( verbose >= 3 )
-            cout << "reading factor " << cellind << ": " << endl;
-        mxArray *cell = mxGetCell(psi, cellind);
-        mxArray *mx_member = mxGetField(cell, 0, "Member"); 
-        size_t nr_mem = mxGetN(mx_member);
-        double *members = mxGetPr(mx_member);
-        const mwSize *dims = mxGetDimensions(mxGetField(cell,0,"P"));
-        double *factordata = mxGetPr(mxGetField(cell, 0, "P"));
-
-        // add variables
-        VarSet factorvars;
-        vector<long> labels(nr_mem,0);
-        if( verbose >= 3 )
-            cout << "  vars: ";
-        for( size_t mi = 0; mi < nr_mem; mi++ ) {
-            labels[mi] = (long)members[mi];
-            if( verbose >= 3 )
-                cout << labels[mi] << "(" << dims[mi] << ") ";
-            vars.insert( Var(labels[mi], dims[mi]) );
-            factorvars |= Var(labels[mi], dims[mi]);
-        }
-        factors.push_back(Factor(factorvars));
-
-        // calculate permutation matrix
-        vector<size_t> perm(nr_mem,0);
-        VarSet::iterator j = factorvars.begin();
-        for( size_t mi = 0; mi < nr_mem; mi++,j++ ) {
-            long gezocht = j->label();
-            vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht);
-            perm[mi] = piet - labels.begin();
-        }
-
-        if( verbose >= 3 ) {
-            cout << endl << "  perm: ";
-            for( vector<size_t>::iterator r=perm.begin(); r!=perm.end(); r++ )
-                cout << *r << " ";
-            cout << endl;
-        }
-
-        // read Factor
-        vector<size_t> di(nr_mem,0);
-        size_t prod = 1;
-        for( size_t k = 0; k < nr_mem; k++ ) {
-            di[k] = dims[k];
-            prod *= dims[k];
-        }
-        Permute permindex( di, perm );
-        for( size_t li = 0; li < prod; li++ )
-            factors.back()[permindex.convert_linear_index(li)] = factordata[li];
-    }
-
-    if( verbose >= 3 ) {
-        for(vector<Factor>::const_iterator I=factors.begin(); I!=factors.end(); I++ )
-            cout << *I << endl;
-    }
-
-    return( factors );
-}
-
-
-/* Convert CPTAB-like struct to Factor */
-Factor mx2Factor(const mxArray *psi) {
-    mxArray *mx_member = mxGetField(psi, 0, "Member");  
-    size_t nr_mem = mxGetN(mx_member);
-    double *members = mxGetPr(mx_member);
-    const mwSize *dims = mxGetDimensions(mxGetField(psi,0,"P"));
-    double *factordata = mxGetPr(mxGetField(psi, 0, "P"));
-
-    // add variables
-    VarSet vars;
-    vector<long> labels(nr_mem,0);
-    for( size_t mi = 0; mi < nr_mem; mi++ ) {
-        labels[mi] = (long)members[mi];
-        vars |= Var(labels[mi], dims[mi]);
-    }
-    Factor factor(vars);
-
-    // calculate permutation matrix
-    vector<size_t> perm(nr_mem,0);
-    VarSet::iterator j = vars.begin();
-    for( size_t mi = 0; mi < nr_mem; mi++,j++ ) {
-        long gezocht = j->label();
-        vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht);
-        perm[mi] = piet - labels.begin();
-    }
-
-    // read Factor
-    vector<size_t> di(nr_mem,0);
-    size_t prod = 1;
-    for( size_t k = 0; k < nr_mem; k++ ) {
-        di[k] = dims[k];
-        prod *= dims[k];
-    }
-    Permute permindex( di, perm );
-    for( size_t li = 0; li < prod; li++ )
-        factor[permindex.convert_linear_index(li)] = factordata[li];
-
-    return( factor );
-}
-
-
-}
diff --git a/matlab/matlab.h b/matlab/matlab.h
deleted file mode 100644 (file)
index 6d6dc84..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
-    Radboud University Nijmegen, The Netherlands /
-    Max Planck Institute for Biological Cybernetics, Germany
-
-    This file is part of libDAI.
-
-    libDAI is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    libDAI is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with libDAI; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
-
-
-#ifndef __defined_libdai_matlab_h
-#define __defined_libdai_matlab_h
-
-
-#include "mex.h"
-#include <dai/factor.h>
-
-
-namespace dai {
-
-
-#ifdef SMALLMEM
-    typedef int mwSize;
-    typedef int mwIndex;
-#endif
-
-
-/// Convert vector<Factor> structure to a cell vector of CPTAB-like structs
-mxArray *Factors2mx(const std::vector<Factor> &Ps);
-
-/// Convert cell vector of CPTAB-like structs to vector<Factor>
-std::vector<Factor> mx2Factors(const mxArray *psi, long verbose);
-
-/// Convert CPTAB-like struct to Factor
-Factor mx2Factor(const mxArray *psi);
-
-
-} // end of namespace dai
-
-
-#endif
index 7c8d81a..8e9f7f4 100644 (file)
@@ -39,6 +39,9 @@ using namespace std;
 const char *BP::Name = "BP";
 
 
+#define DAI_BP_FAST 1
+
+
 void BP::setProperties( const PropertySet &opts ) {
     assert( opts.hasKey("tol") );
     assert( opts.hasKey("maxiter") );
@@ -104,9 +107,11 @@ void BP::construct() {
             newEP.message = Prob( var(i).states() );
             newEP.newMessage = Prob( var(i).states() );
 
-            newEP.index.reserve( factor(I).states() );
-            for( IndexFor k( var(i), factor(I).vars() ); k >= 0; ++k )
-                newEP.index.push_back( k );
+            if( DAI_BP_FAST ) {
+                newEP.index.reserve( factor(I).states() );
+                for( IndexFor k( var(i), factor(I).vars() ); k >= 0; ++k )
+                    newEP.index.push_back( k );
+            }
 
             newEP.residual = 0.0;
             _edges[i].push_back( newEP );
@@ -144,7 +149,7 @@ void BP::calcNewMessage( size_t i, size_t _I ) {
     // calculate updated message I->i
     size_t I = nbV(i,_I);
 
-    if( 0 == 1 ) {
+    if( !DAI_BP_FAST ) {
         /* UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION */
         Factor prod( factor( I ) );
         foreach( const Neighbor &j, nbF(I) )
@@ -370,7 +375,7 @@ Factor BP::belief( const VarSet &ns ) const {
 
 
 Factor BP::beliefF (size_t I) const {
-    if( 0 == 1 ) {
+    if( !DAI_BP_FAST ) {
         /*  UNOPTIMIZED (SIMPLE TO READ, BUT SLOW) VERSION */
 
         Factor prod( factor(I) );
diff --git a/src/matlab/dai.cpp b/src/matlab/dai.cpp
new file mode 100644 (file)
index 0000000..149d7b0
--- /dev/null
@@ -0,0 +1,124 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+/*=================================================================*
+ *                                                                 * 
+ * This is a MEX-file for MATLAB.                                  *
+ *                                                                 * 
+ *   [logZ,q,md] = dai(psi,method,opts);                           *
+ *                                                                 * 
+ *=================================================================*/
+
+
+#include <iostream>
+#include <dai/matlab/matlab.h>
+#include "mex.h"
+#include <dai/alldai.h>
+
+
+using namespace std;
+using namespace dai;
+
+
+/* Input Arguments */
+
+#define PSI_IN          prhs[0]
+#define METHOD_IN       prhs[1]
+#define OPTS_IN         prhs[2]
+#define NR_IN           3
+
+
+/* Output Arguments */
+
+#define LOGZ_OUT        plhs[0]
+#define Q_OUT           plhs[1]
+#define MD_OUT          plhs[2]
+#define NR_OUT          3
+
+
+void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
+{ 
+    size_t buflen;
+    
+    /* Check for proper number of arguments */
+    if( (nrhs != NR_IN) || (nlhs != NR_OUT) ) { 
+        mexErrMsgTxt("Usage: [logZ,q,md] = dai(psi,method,opts)\n\n"
+        "\n"
+        "INPUT:  psi        = linear cell array containing the factors \n"
+        "                     psi{i} should be a structure with a Member field\n"
+        "                     and a P field, like a CPTAB).\n"
+        "        method     = name of the method (see README)\n"
+        "        opts       = string of options (see README)\n"
+        "\n"
+        "OUTPUT: logZ       = approximation of the logarithm of the partition sum.\n"
+        "        q          = linear cell array containing all final beliefs.\n"
+        "        md         = maxdiff (final linf-dist between new and old single node beliefs).\n");
+    } 
+    
+    char *method;
+    char *opts;
+
+
+    // Get psi and construct factorgraph
+    vector<Factor> factors = mx2Factors(PSI_IN, 0);
+    FactorGraph fg(factors);
+
+    // Get method
+    buflen = mxGetN( METHOD_IN ) + 1;
+    method = (char *)mxCalloc( buflen, sizeof(char) );
+    mxGetString( METHOD_IN, method, buflen );
+
+    // Get options string
+    buflen = mxGetN( OPTS_IN ) + 1;
+    opts = (char *)mxCalloc( buflen, sizeof(char) );
+    mxGetString( OPTS_IN, opts, buflen );
+    // Convert to options object props
+    stringstream ss;
+    ss << opts;
+    PropertySet props;
+    ss >> props;
+    
+    // Construct InfAlg object, init and run
+    InfAlg *obj = newInfAlg( method, fg, props );
+    obj->init();
+    obj->run();
+
+
+    // Save logZ
+    double logZ = obj->logZ();
+
+    // Save maxdiff
+    double maxdiff = obj->maxDiff();
+
+
+    // Hand over results to MATLAB
+    LOGZ_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
+    *(mxGetPr(LOGZ_OUT)) = logZ;
+    
+    Q_OUT = Factors2mx(obj->beliefs());
+    
+    MD_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
+    *(mxGetPr(MD_OUT)) = maxdiff;
+
+    
+    return;
+}
diff --git a/src/matlab/dai_potstrength.cpp b/src/matlab/dai_potstrength.cpp
new file mode 100644 (file)
index 0000000..af2d2f0
--- /dev/null
@@ -0,0 +1,102 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+/*=================================================================*
+ *                                                                 * 
+ * This is a MEX-file for MATLAB.                                  *
+ *                                                                 * 
+ *   N = dai_potstrength(psi,i,j);                                 *
+ *                                                                 * 
+ *=================================================================*/
+
+
+#include <iostream>
+#include "mex.h"
+#include <dai/matlab/matlab.h>
+#include <dai/factor.h>
+
+
+using namespace std;
+using namespace dai;
+
+
+/* Input Arguments */
+
+#define PSI_IN          prhs[0]
+#define I_IN            prhs[1]
+#define J_IN            prhs[2]
+#define NR_IN           3
+
+
+/* Output Arguments */
+
+#define N_OUT           plhs[0]
+#define NR_OUT          1
+
+
+void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
+{ 
+    long ilabel, jlabel;
+
+    // Check for proper number of arguments
+    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
+        mexErrMsgTxt("Usage: N = dai_potstrength(psi,i,j);\n\n"
+        "\n"
+        "INPUT:  psi        = structure with a Member field and a P field, like a CPTAB.\n"
+        "        i          = label of a variable in psi.\n"
+        "        j          = label of another variable in psi.\n"
+        "\n"
+        "OUTPUT: N          = strength of psi in direction i->j.\n");
+    } 
+    
+    // Get input parameters
+    Factor psi = mx2Factor(PSI_IN);
+    ilabel = (long)*mxGetPr(I_IN);
+    jlabel = (long)*mxGetPr(J_IN);
+
+    // Find variable in psi with label ilabel
+    Var i;
+    for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ )
+        if( n->label() == ilabel ) {
+            i = *n;
+            break;
+        }
+    assert( i.label() == ilabel );
+
+    // Find variable in psi with label jlabel
+    Var j;
+    for( VarSet::const_iterator n = psi.vars().begin(); n != psi.vars().end(); n++ )
+        if( n->label() == jlabel ) {
+            j = *n;
+            break;
+        }
+    assert( j.label() == jlabel );
+
+    // Calculate N(psi,i,j);
+    double N = psi.strength( i, j );
+    
+    // Hand over result to MATLAB
+    N_OUT = mxCreateDoubleMatrix(1,1,mxREAL);
+    *(mxGetPr(N_OUT)) = N;
+    
+    return;
+}
diff --git a/src/matlab/dai_readfg.cpp b/src/matlab/dai_readfg.cpp
new file mode 100644 (file)
index 0000000..7fcc411
--- /dev/null
@@ -0,0 +1,97 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+/*=================================================================*
+ *                                                                 * 
+ * This is a MEX-file for MATLAB.                                  *
+ *                                                                 * 
+ *   [psi] = dai_readfg(filename);                                 *
+ *                                                                 * 
+ *=================================================================*/
+
+
+#include <iostream>
+#include "mex.h"
+#include <dai/matlab/matlab.h>
+#include <dai/factorgraph.h>
+
+
+using namespace std;
+using namespace dai;
+
+
+/* Input Arguments */
+
+#define FILENAME_IN     prhs[0]
+#define NR_IN           1
+
+
+/* Output Arguments */
+
+#define PSI_OUT         plhs[0]
+#define NR_OUT          1
+
+
+void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
+{ 
+    char *filename;
+
+    
+    // Check for proper number of arguments
+    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
+        mexErrMsgTxt("Usage: [psi] = dai_readfg(filename);\n\n"
+        "\n"
+        "INPUT:  filename   = filename of a .fg file\n"
+        "\n"
+        "OUTPUT: psi        = linear cell array containing the factors\n"
+        "                     (psi{i} is a structure with a Member field\n"
+        "                     and a P field, like a CPTAB).\n");
+    } 
+    
+    // Get input parameters
+    size_t buflen;
+    buflen = mxGetN( FILENAME_IN ) + 1;
+    filename = (char *)mxCalloc( buflen, sizeof(char) );
+    mxGetString( FILENAME_IN, filename, buflen );
+    
+
+    // Read factorgraph
+    FactorGraph fg;
+    try {
+        fg.ReadFromFile( filename );
+    } catch( std::exception &e ) {
+        mexErrMsgTxt( e.what() );
+    }
+
+
+    // Save factors
+    vector<Factor> psi;
+    for( size_t I = 0; I < fg.nrFactors(); I++ )
+        psi.push_back(fg.factor(I));
+    
+
+    // Hand over results to MATLAB
+    PSI_OUT = Factors2mx(psi);
+
+    
+    return;
+}
diff --git a/src/matlab/dai_writefg.cpp b/src/matlab/dai_writefg.cpp
new file mode 100644 (file)
index 0000000..5fbbbc0
--- /dev/null
@@ -0,0 +1,87 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+/*=================================================================*
+ *                                                                 * 
+ * This is a MEX-file for MATLAB.                                  *
+ *                                                                 * 
+ *   dai_writefg(psi, filename);                                   *
+ *                                                                 * 
+ *=================================================================*/
+
+
+#include <iostream>
+#include "mex.h"
+#include <dai/matlab/matlab.h>
+#include <dai/factorgraph.h>
+
+
+using namespace std;
+using namespace dai;
+
+
+/* Input Arguments */
+
+#define PSI_IN          prhs[0]
+#define FILENAME_IN     prhs[1]
+#define NR_IN           2
+
+
+/* Output Arguments */
+
+#define NR_OUT          0
+
+
+void mexFunction( int nlhs, mxArray * /*plhs*/[], int nrhs, const mxArray*prhs[] )
+{ 
+    char *filename;
+
+    
+    // Check for proper number of arguments
+    if ((nrhs != NR_IN) || (nlhs != NR_OUT)) { 
+        mexErrMsgTxt("Usage: dai_writefg(psi,filename);\n\n"
+        "\n"
+        "INPUT:  psi        = linear cell array containing the factors\n"
+        "                     (psi{i} should be a structure with a Member field\n"
+        "                     and a P field, like a CPTAB).\n"
+        "        filename   = filename of a .fg file\n");
+    } 
+    
+    // Get input parameters
+    vector<Factor> factors = mx2Factors(PSI_IN,0);
+    
+    size_t buflen;
+    buflen = mxGetN( FILENAME_IN ) + 1;
+    filename = (char *)mxCalloc( buflen, sizeof(char) );
+    mxGetString( FILENAME_IN, filename, buflen );
+    
+    // Construct factorgraph
+    FactorGraph fg(factors);
+
+    try {
+        fg.WriteToFile( filename );
+    } catch( std::exception &e ) {
+        mexErrMsgTxt( e.what() );
+    }
+
+    return;
+}
diff --git a/src/matlab/matlab.cpp b/src/matlab/matlab.cpp
new file mode 100644 (file)
index 0000000..a2b053e
--- /dev/null
@@ -0,0 +1,186 @@
+/*  Copyright (C) 2006-2008  Joris Mooij  [joris dot mooij at tuebingen dot mpg dot de]
+    Radboud University Nijmegen, The Netherlands /
+    Max Planck Institute for Biological Cybernetics, Germany
+
+    This file is part of libDAI.
+
+    libDAI is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    libDAI is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with libDAI; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include <iostream>
+#include <dai/matlab/matlab.h>
+
+
+namespace dai {
+
+
+using namespace std;
+
+
+/* Convert vector<Factor> structure to a cell vector of CPTAB-like structs */
+mxArray *Factors2mx(const vector<Factor> &Ps) {
+    size_t nr = Ps.size();
+
+    mxArray *psi = mxCreateCellMatrix(nr,1);
+    
+    const char *fieldnames[2];
+    fieldnames[0] = "Member";
+    fieldnames[1] = "P";
+    
+    size_t I_ind = 0;
+    for( vector<Factor>::const_iterator I = Ps.begin(); I != Ps.end(); I++, I_ind++ ) {
+        mxArray *Bi = mxCreateStructMatrix(1,1,2,fieldnames);
+
+        mxArray *BiMember = mxCreateDoubleMatrix(1,I->vars().size(),mxREAL);
+        double *BiMember_data = mxGetPr(BiMember);
+        size_t i = 0;
+        vector<mwSize> dims;
+        for( VarSet::const_iterator j = I->vars().begin(); j != I->vars().end(); j++,i++ ) {
+            BiMember_data[i] = j->label();
+            dims.push_back( j->states() );
+        }
+
+        mxArray *BiP = mxCreateNumericArray(I->vars().size(), &(*(dims.begin())), mxDOUBLE_CLASS, mxREAL);
+        double *BiP_data = mxGetPr(BiP);
+        for( size_t j = 0; j < I->states(); j++ )
+            BiP_data[j] = (*I)[j];
+
+        mxSetField(Bi,0,"Member",BiMember);
+        mxSetField(Bi,0,"P",BiP);
+        
+        mxSetCell(psi, I_ind, Bi);
+    }
+    return( psi );
+}
+
+
+/* Convert cell vector of CPTAB-like structs to vector<Factor> */
+vector<Factor> mx2Factors(const mxArray *psi, long verbose) {
+    set<Var> vars;
+    vector<Factor> factors;
+
+    int n1 = mxGetM(psi);
+    int n2 = mxGetN(psi);
+    if( n2 != 1 && n1 != 1 ) 
+        mexErrMsgTxt("psi should be a Nx1 or 1xN cell matrix."); 
+    size_t nr_f = n1;
+    if( n1 == 1 )
+        nr_f = n2;
+
+    // interpret psi, linear cell array of cptabs
+    for( size_t cellind = 0; cellind < nr_f; cellind++ ) {
+        if( verbose >= 3 )
+            cout << "reading factor " << cellind << ": " << endl;
+        mxArray *cell = mxGetCell(psi, cellind);
+        mxArray *mx_member = mxGetField(cell, 0, "Member"); 
+        size_t nr_mem = mxGetN(mx_member);
+        double *members = mxGetPr(mx_member);
+        const mwSize *dims = mxGetDimensions(mxGetField(cell,0,"P"));
+        double *factordata = mxGetPr(mxGetField(cell, 0, "P"));
+
+        // add variables
+        VarSet factorvars;
+        vector<long> labels(nr_mem,0);
+        if( verbose >= 3 )
+            cout << "  vars: ";
+        for( size_t mi = 0; mi < nr_mem; mi++ ) {
+            labels[mi] = (long)members[mi];
+            if( verbose >= 3 )
+                cout << labels[mi] << "(" << dims[mi] << ") ";
+            vars.insert( Var(labels[mi], dims[mi]) );
+            factorvars |= Var(labels[mi], dims[mi]);
+        }
+        factors.push_back(Factor(factorvars));
+
+        // calculate permutation matrix
+        vector<size_t> perm(nr_mem,0);
+        VarSet::iterator j = factorvars.begin();
+        for( size_t mi = 0; mi < nr_mem; mi++,j++ ) {
+            long gezocht = j->label();
+            vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht);
+            perm[mi] = piet - labels.begin();
+        }
+
+        if( verbose >= 3 ) {
+            cout << endl << "  perm: ";
+            for( vector<size_t>::iterator r=perm.begin(); r!=perm.end(); r++ )
+                cout << *r << " ";
+            cout << endl;
+        }
+
+        // read Factor
+        vector<size_t> di(nr_mem,0);
+        size_t prod = 1;
+        for( size_t k = 0; k < nr_mem; k++ ) {
+            di[k] = dims[k];
+            prod *= dims[k];
+        }
+        Permute permindex( di, perm );
+        for( size_t li = 0; li < prod; li++ )
+            factors.back()[permindex.convert_linear_index(li)] = factordata[li];
+    }
+
+    if( verbose >= 3 ) {
+        for(vector<Factor>::const_iterator I=factors.begin(); I!=factors.end(); I++ )
+            cout << *I << endl;
+    }
+
+    return( factors );
+}
+
+
+/* Convert CPTAB-like struct to Factor */
+Factor mx2Factor(const mxArray *psi) {
+    mxArray *mx_member = mxGetField(psi, 0, "Member");  
+    size_t nr_mem = mxGetN(mx_member);
+    double *members = mxGetPr(mx_member);
+    const mwSize *dims = mxGetDimensions(mxGetField(psi,0,"P"));
+    double *factordata = mxGetPr(mxGetField(psi, 0, "P"));
+
+    // add variables
+    VarSet vars;
+    vector<long> labels(nr_mem,0);
+    for( size_t mi = 0; mi < nr_mem; mi++ ) {
+        labels[mi] = (long)members[mi];
+        vars |= Var(labels[mi], dims[mi]);
+    }
+    Factor factor(vars);
+
+    // calculate permutation matrix
+    vector<size_t> perm(nr_mem,0);
+    VarSet::iterator j = vars.begin();
+    for( size_t mi = 0; mi < nr_mem; mi++,j++ ) {
+        long gezocht = j->label();
+        vector<long>::iterator piet = find(labels.begin(),labels.end(),gezocht);
+        perm[mi] = piet - labels.begin();
+    }
+
+    // read Factor
+    vector<size_t> di(nr_mem,0);
+    size_t prod = 1;
+    for( size_t k = 0; k < nr_mem; k++ ) {
+        di[k] = dims[k];
+        prod *= dims[k];
+    }
+    Permute permindex( di, perm );
+    for( size_t li = 0; li < prod; li++ )
+        factor[permindex.convert_linear_index(li)] = factordata[li];
+
+    return( factor );
+}
+
+
+}
index f31e633..c114d8b 100644 (file)
@@ -155,6 +155,19 @@ int main( int argc, char *argv[] ) {
                 cout << "Girth: infinity" << endl;
         }
 
+        map<size_t,size_t> facsizes;
+        for( size_t I = 0; I < fg.nrFactors(); I++ ) {
+            size_t Isize = fg.factor(I).vars().size();
+            if( facsizes.count( Isize ) )
+                facsizes[Isize]++;
+            else
+                facsizes[Isize] = 1;
+        }
+        cout << "Factor sizes: ";
+        for( map<size_t,size_t>::const_iterator it = facsizes.begin(); it != facsizes.end(); it++ ) 
+            cout << it->first << "(" << it->second << ") ";
+        cout << endl;
+
         return 0;
     }
 }