From: Joris Mooij Date: Wed, 8 Oct 2008 09:02:18 +0000 (+0200) Subject: Cleanups of matlab, BP; small improvement of utils/fginfo X-Git-Tag: v0.2.3~118 X-Git-Url: http://git.tuebingen.mpg.de/?p=libdai.git;a=commitdiff_plain;h=4d761b7c6897f4379d2484b2faa689787b2198be Cleanups of matlab, BP; small improvement of utils/fginfo --- diff --git a/Makefile b/Makefile index 4adbaff..5c1fdd7 100644 --- 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 diff --git a/Makefile.shared b/Makefile.shared index 581a07b..b9a1d94 100644 --- a/Makefile.shared +++ b/Makefile.shared @@ -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 diff --git a/Makefile.win b/Makefile.win index ec700eb..2a3dfa7 100755 --- a/Makefile.win +++ b/Makefile.win @@ -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=.lib OE=.obj EE=.exe @@ -59,7 +59,7 @@ CC=cl CCO=/Fe # Flags for the C++ compiler -CCFLAGS=/I./include /IC:\boost_1_36_0 /EHsc /Ox +CCFLAGS=/Iinclude /IC:\boost_1_36_0 /EHsc /Ox !IFDEF DEBUG CCFLAGS=$(CCFLAGS) /Zi /DDAI_DEBUG !ENDIF @@ -100,10 +100,9 @@ OBJECTS=$(OBJECTS) mr$(OE) !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=c:\matlab +MEX=$(MATLABDIR)\bin\mex +MEXFLAGS=-Iinclude CXX\#$(CC) CXXFLAGS\#"/EHsc /Ox" !IFDEF DEBUG MEXFLAGS=$(MEXFLAGS) -g /DDAI_DEBUG !ENDIF @@ -141,6 +140,6 @@ doc : $(INC)/*.h $(SRC)/*.cpp doxygen.conf doxygen doxygen.conf clean : - 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) + del *$(OE) *.ilk *.pdb *$(EE) matlab\*$(ME) tests\testdai$(EE) tests\*.pdb tests\*.ilk utils\*$(EE) utils\*.pdb utils\*.ilk $(LIB)\libdai$(LE) !INCLUDE Makefile.shared diff --git a/include/dai/matlab/matlab.h b/include/dai/matlab/matlab.h new file mode 100644 index 0000000..6d6dc84 --- /dev/null +++ b/include/dai/matlab/matlab.h @@ -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 + + +namespace dai { + + +#ifdef SMALLMEM + typedef int mwSize; + typedef int mwIndex; +#endif + + +/// Convert vector structure to a cell vector of CPTAB-like structs +mxArray *Factors2mx(const std::vector &Ps); + +/// Convert cell vector of CPTAB-like structs to vector +std::vector 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 index c6f26dd..0000000 --- a/matlab/dai.cpp +++ /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 -#include -#include "mex.h" -#include - - -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 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 index af2d2f0..0000000 --- a/matlab/dai_potstrength.cpp +++ /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 -#include "mex.h" -#include -#include - - -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 index 7fcc411..0000000 --- a/matlab/dai_readfg.cpp +++ /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 -#include "mex.h" -#include -#include - - -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 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 index bbe1761..0000000 --- a/matlab/dai_writefg.cpp +++ /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 -#include "mex.h" -#include -#include - - -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 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 index a2b053e..0000000 --- a/matlab/matlab.cpp +++ /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 -#include - - -namespace dai { - - -using namespace std; - - -/* Convert vector structure to a cell vector of CPTAB-like structs */ -mxArray *Factors2mx(const vector &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::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 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 */ -vector mx2Factors(const mxArray *psi, long verbose) { - set vars; - vector 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 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 perm(nr_mem,0); - VarSet::iterator j = factorvars.begin(); - for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { - long gezocht = j->label(); - vector::iterator piet = find(labels.begin(),labels.end(),gezocht); - perm[mi] = piet - labels.begin(); - } - - if( verbose >= 3 ) { - cout << endl << " perm: "; - for( vector::iterator r=perm.begin(); r!=perm.end(); r++ ) - cout << *r << " "; - cout << endl; - } - - // read Factor - vector 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::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 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 perm(nr_mem,0); - VarSet::iterator j = vars.begin(); - for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { - long gezocht = j->label(); - vector::iterator piet = find(labels.begin(),labels.end(),gezocht); - perm[mi] = piet - labels.begin(); - } - - // read Factor - vector 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 index 6d6dc84..0000000 --- a/matlab/matlab.h +++ /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 - - -namespace dai { - - -#ifdef SMALLMEM - typedef int mwSize; - typedef int mwIndex; -#endif - - -/// Convert vector structure to a cell vector of CPTAB-like structs -mxArray *Factors2mx(const std::vector &Ps); - -/// Convert cell vector of CPTAB-like structs to vector -std::vector 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/src/bp.cpp b/src/bp.cpp index 7c8d81a..8e9f7f4 100644 --- a/src/bp.cpp +++ b/src/bp.cpp @@ -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 index 0000000..149d7b0 --- /dev/null +++ b/src/matlab/dai.cpp @@ -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 +#include +#include "mex.h" +#include + + +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 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 index 0000000..af2d2f0 --- /dev/null +++ b/src/matlab/dai_potstrength.cpp @@ -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 +#include "mex.h" +#include +#include + + +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 index 0000000..7fcc411 --- /dev/null +++ b/src/matlab/dai_readfg.cpp @@ -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 +#include "mex.h" +#include +#include + + +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 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 index 0000000..5fbbbc0 --- /dev/null +++ b/src/matlab/dai_writefg.cpp @@ -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 +#include "mex.h" +#include +#include + + +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 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 index 0000000..a2b053e --- /dev/null +++ b/src/matlab/matlab.cpp @@ -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 +#include + + +namespace dai { + + +using namespace std; + + +/* Convert vector structure to a cell vector of CPTAB-like structs */ +mxArray *Factors2mx(const vector &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::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 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 */ +vector mx2Factors(const mxArray *psi, long verbose) { + set vars; + vector 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 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 perm(nr_mem,0); + VarSet::iterator j = factorvars.begin(); + for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { + long gezocht = j->label(); + vector::iterator piet = find(labels.begin(),labels.end(),gezocht); + perm[mi] = piet - labels.begin(); + } + + if( verbose >= 3 ) { + cout << endl << " perm: "; + for( vector::iterator r=perm.begin(); r!=perm.end(); r++ ) + cout << *r << " "; + cout << endl; + } + + // read Factor + vector 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::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 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 perm(nr_mem,0); + VarSet::iterator j = vars.begin(); + for( size_t mi = 0; mi < nr_mem; mi++,j++ ) { + long gezocht = j->label(); + vector::iterator piet = find(labels.begin(),labels.end(),gezocht); + perm[mi] = piet - labels.begin(); + } + + // read Factor + vector 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/utils/fginfo.cpp b/utils/fginfo.cpp index f31e633..c114d8b 100644 --- a/utils/fginfo.cpp +++ b/utils/fginfo.cpp @@ -155,6 +155,19 @@ int main( int argc, char *argv[] ) { cout << "Girth: infinity" << endl; } + map 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::const_iterator it = facsizes.begin(); it != facsizes.end(); it++ ) + cout << it->first << "(" << it->second << ") "; + cout << endl; + return 0; } }