From 84d6b5be6ad73662cdd8648356c7fa1bd32d282d Mon Sep 17 00:00:00 2001 From: Richard Roberts Date: Sun, 10 Oct 2010 00:51:57 +0000 Subject: [PATCH] Re-enabled computing marginals of a set of variables (Inference::Marginal(...)) --- .cproject | 406 ++++++++++++++++++++------------------ .project | 2 +- inference/BayesNet.h | 8 +- inference/inference-inl.h | 35 ++++ inference/inference.h | 11 ++ myconfigure | 2 +- myconfigure.profiling | 2 +- myconfigure.timing | 2 +- slam/smallExample.cpp | 4 +- tests/Makefile.am | 2 +- tests/testInference.cpp | 23 ++- 11 files changed, 286 insertions(+), 211 deletions(-) diff --git a/.cproject b/.cproject index 8c01c6610..318dedccb 100644 --- a/.cproject +++ b/.cproject @@ -21,7 +21,7 @@ - + @@ -322,6 +322,14 @@ true true + + make + -j2 + testGaussianFactor.run + true + true + true + make -j2 @@ -348,7 +356,6 @@ make - tests/testBayesTree.run true false @@ -356,7 +363,6 @@ make - testBinaryBayesNet.run true false @@ -404,7 +410,6 @@ make - testSymbolicBayesNet.run true false @@ -412,7 +417,6 @@ make - tests/testSymbolicFactor.run true false @@ -420,7 +424,6 @@ make - testSymbolicFactorGraph.run true false @@ -436,20 +439,11 @@ make - tests/testBayesTree true false true - - make - -j2 - testGaussianFactor.run - true - true - true - make -j2 @@ -484,6 +478,7 @@ make + testGraph.run true false @@ -579,6 +574,7 @@ make + testInference.run true false @@ -586,6 +582,7 @@ make + testGaussianBayesNet.run true false @@ -593,6 +590,7 @@ make + testGaussianFactor.run true false @@ -600,6 +598,7 @@ make + testJunctionTree.run true false @@ -607,6 +606,7 @@ make + testSymbolicBayesNet.run true false @@ -614,6 +614,7 @@ make + testSymbolicFactorGraph.run true false @@ -811,6 +812,14 @@ true true + + make + -j2 + testInference.run + true + true + true + make -j2 @@ -909,7 +918,6 @@ make - testErrors.run true false @@ -1245,6 +1253,7 @@ make + testSimulated2DOriented.run true false @@ -1284,6 +1293,7 @@ make + testSimulated2D.run true false @@ -1291,6 +1301,7 @@ make + testSimulated3D.run true false @@ -1338,6 +1349,7 @@ make + tests/testGaussianISAM2 true false @@ -1359,86 +1371,6 @@ true true - - make - -j2 - install - true - true - true - - - make - -j2 - clean - true - true - true - - - make - -j2 - check - true - true - true - - - make - -j2 - all - true - true - true - - - make - -j2 - dist - true - true - true - - - make - -j2 - inference/tests/testEliminationTree - true - true - true - - - make - -j2 - slam/tests/testGaussianISAM2 - true - true - true - - - make - -j2 - inference/tests/testVariableIndex - true - true - true - - - make - -j2 - inference/tests/testJunctionTree - true - true - true - - - make - -j2 - linear/tests/testGaussianJunctionTree - true - true - true - make -j2 @@ -1535,6 +1467,86 @@ true true + + make + -j2 + install + true + true + true + + + make + -j2 + clean + true + true + true + + + make + -j2 + check + true + true + true + + + make + -j2 + all + true + true + true + + + make + -j2 + dist + true + true + true + + + make + -j2 + inference/tests/testEliminationTree + true + true + true + + + make + -j2 + slam/tests/testGaussianISAM2 + true + true + true + + + make + -j2 + inference/tests/testVariableIndex + true + true + true + + + make + -j2 + inference/tests/testJunctionTree + true + true + true + + + make + -j2 + linear/tests/testGaussianJunctionTree + true + true + true + make -j2 @@ -1889,6 +1901,14 @@ true true + + make + -j2 + testGaussianFactor.run + true + true + true + make -j2 @@ -1915,7 +1935,6 @@ make - tests/testBayesTree.run true false @@ -1923,7 +1942,6 @@ make - testBinaryBayesNet.run true false @@ -1971,7 +1989,6 @@ make - testSymbolicBayesNet.run true false @@ -1979,7 +1996,6 @@ make - tests/testSymbolicFactor.run true false @@ -1987,7 +2003,6 @@ make - testSymbolicFactorGraph.run true false @@ -2003,20 +2018,11 @@ make - tests/testBayesTree true false true - - make - -j2 - testGaussianFactor.run - true - true - true - make -j2 @@ -2051,6 +2057,7 @@ make + testGraph.run true false @@ -2146,6 +2153,7 @@ make + testInference.run true false @@ -2153,6 +2161,7 @@ make + testGaussianBayesNet.run true false @@ -2160,6 +2169,7 @@ make + testGaussianFactor.run true false @@ -2167,6 +2177,7 @@ make + testJunctionTree.run true false @@ -2174,6 +2185,7 @@ make + testSymbolicBayesNet.run true false @@ -2181,6 +2193,7 @@ make + testSymbolicFactorGraph.run true false @@ -2378,6 +2391,14 @@ true true + + make + -j2 + testInference.run + true + true + true + make -j2 @@ -2476,7 +2497,6 @@ make - testErrors.run true false @@ -2812,6 +2832,7 @@ make + testSimulated2DOriented.run true false @@ -2851,6 +2872,7 @@ make + testSimulated2D.run true false @@ -2858,6 +2880,7 @@ make + testSimulated3D.run true false @@ -2905,6 +2928,7 @@ make + tests/testGaussianISAM2 true false @@ -2926,86 +2950,6 @@ true true - - make - -j2 - install - true - true - true - - - make - -j2 - clean - true - true - true - - - make - -j2 - check - true - true - true - - - make - -j2 - all - true - true - true - - - make - -j2 - dist - true - true - true - - - make - -j2 - inference/tests/testEliminationTree - true - true - true - - - make - -j2 - slam/tests/testGaussianISAM2 - true - true - true - - - make - -j2 - inference/tests/testVariableIndex - true - true - true - - - make - -j2 - inference/tests/testJunctionTree - true - true - true - - - make - -j2 - linear/tests/testGaussianJunctionTree - true - true - true - make -j2 @@ -3102,6 +3046,86 @@ true true + + make + -j2 + install + true + true + true + + + make + -j2 + clean + true + true + true + + + make + -j2 + check + true + true + true + + + make + -j2 + all + true + true + true + + + make + -j2 + dist + true + true + true + + + make + -j2 + inference/tests/testEliminationTree + true + true + true + + + make + -j2 + slam/tests/testGaussianISAM2 + true + true + true + + + make + -j2 + inference/tests/testVariableIndex + true + true + true + + + make + -j2 + inference/tests/testJunctionTree + true + true + true + + + make + -j2 + linear/tests/testGaussianJunctionTree + true + true + true + make -j2 diff --git a/.project b/.project index d20fd358e..475695351 100644 --- a/.project +++ b/.project @@ -23,7 +23,7 @@ org.eclipse.cdt.make.core.buildArguments - -j2 + org.eclipse.cdt.make.core.buildCommand diff --git a/inference/BayesNet.h b/inference/BayesNet.h index 7ab6e35d8..4747b455d 100644 --- a/inference/BayesNet.h +++ b/inference/BayesNet.h @@ -102,8 +102,14 @@ namespace gtsam { /** SLOW O(n) random access to Conditional by key */ sharedConditional operator[](varid_t key) const; + /** return last node in ordering */ + sharedConditional& front() { return conditionals_.front(); } + + /** return last node in ordering */ + boost::shared_ptr front() const { return conditionals_.front(); } + /** return last node in ordering */ - inline sharedConditional& back() { return conditionals_.back(); } + sharedConditional& back() { return conditionals_.back(); } /** return last node in ordering */ boost::shared_ptr back() const { return conditionals_.back(); } diff --git a/inference/inference-inl.h b/inference/inference-inl.h index 2e39b235a..55cd5847a 100644 --- a/inference/inference-inl.h +++ b/inference/inference-inl.h @@ -276,6 +276,41 @@ Inference::EliminateOne(FactorGraph& factorGraph, typename FactorGraph::variable } } +/* ************************************************************************* */ +template +typename FactorGraph::bayesnet_type::shared_ptr Inference::Marginal(const FactorGraph& factorGraph, const VarContainer& variables) { + + // Compute a COLAMD permutation with the marginal variables constrained to the end + typename FactorGraph::variableindex_type varIndex(factorGraph); + Permutation::shared_ptr permutation(Inference::PermutationCOLAMD(varIndex, variables)); + Permutation::shared_ptr permutationInverse(permutation->inverse()); + + // Copy and permute the factors + varIndex.permute(*permutation); + FactorGraph eliminationGraph; eliminationGraph.reserve(factorGraph.size()); + BOOST_FOREACH(const typename FactorGraph::sharedFactor& factor, factorGraph) { + typename FactorGraph::sharedFactor permFactor(new typename FactorGraph::factor_type(*factor)); + permFactor->permuteWithInverse(*permutationInverse); + eliminationGraph.push_back(permFactor); + } + + // Eliminate all variables + typename FactorGraph::bayesnet_type::shared_ptr bn(Inference::Eliminate(eliminationGraph, varIndex)); + + // The last conditionals in the eliminated BayesNet contain the marginal for + // the variables we want. + typename FactorGraph::bayesnet_type::shared_ptr marginal(new typename FactorGraph::bayesnet_type()); + typename FactorGraph::bayesnet_type::const_reverse_iterator conditional = bn->rbegin(); + for(varid_t j=0; jpush_front(*conditional); + assert(std::find(variables.begin(), variables.end(), (*permutation)[(*conditional)->key()]) != variables.end()); + } + + // Undo the permutation + marginal->permuteWithInverse(*permutation); + return marginal; +} + /* ************************************************************************* */ template Permutation::shared_ptr Inference::PermutationCOLAMD(const VariableIndexType& variableIndex, const ConstraintContainer& constrainLast) { diff --git a/inference/inference.h b/inference/inference.h index 8c999d0ad..db3a2fc83 100644 --- a/inference/inference.h +++ b/inference/inference.h @@ -85,6 +85,17 @@ class Conditional; static boost::shared_ptr EliminateOneSymbolic(FactorGraph& factorGraph, VariableIndex<>& variableIndex, varid_t var); + /** + * Eliminate all variables except the specified ones. Internally this + * permutes these variables to the end of the ordering, eliminates all + * other variables, and then undoes the permutation. This is + * inefficient if multiple marginals are needed - in that case use the + * BayesTree which supports efficiently computing marginals for multiple + * variables. + */ + template + static typename FactorGraph::bayesnet_type::shared_ptr Marginal(const FactorGraph& factorGraph, const VarContainer& variables); + /** * Compute a permutation (variable ordering) using colamd */ diff --git a/myconfigure b/myconfigure index 7fcfcbda4..40484a80b 100755 --- a/myconfigure +++ b/myconfigure @@ -1,4 +1,4 @@ -../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/usr/local/bin/gfilt" CXXFLAGS="-fno-inline -g -Wall -D_GLIBCXX_DEBUG" CFLAGS="-fno-inline -g -Wall -D_GLIBCXX_DEBUG" LDFLAGS="-fno-inline -g -Wall" --disable-static --enable-blas --enable-lapack --disable-fast-install +../configure --prefix=$HOME/borg --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/usr/local/bin/gfilt" CPPFLAGS="-fno-inline -g -Wall -D_GLIBCXX_DEBUG" LDFLAGS="-fno-inline -g -Wall" --disable-static --enable-blas --enable-lapack --disable-fast-install #../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/usr/local/bin/gfilt" CXXFLAGS="-fno-inline -g -Wall -D_GLIBCXX_DEBUG -DNDEBUG" CFLAGS="-fno-inline -g -Wall -D_GLIBCXX_DEBUG -DNDEBUG" LDFLAGS="-fno-inline -g -Wall" --disable-static --enable-blas --enable-lapack --disable-fast-install #cd build && ../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CXXFLAGS="-fno-inline -g -DNDEBUG -O3" CFLAGS="-fno-inline -g -DNDEBUG -O3" LDFLAGS="-fno-inline -g -DNDEBUG -O3" --disable-static --enable-blas --enable-lapack #cd build && ../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CXXFLAGS="-DNDEBUG -O3" CFLAGS="-g -DNDEBUG -O3" LDFLAGS="-DNDEBUG -O3" --disable-static --enable-blas --enable-lapack diff --git a/myconfigure.profiling b/myconfigure.profiling index 7aa814e03..cf57da28f 100755 --- a/myconfigure.profiling +++ b/myconfigure.profiling @@ -1,3 +1,3 @@ #../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CXXFLAGS="-fno-inline -g -DNDEBUG -O3" CFLAGS="-fno-inline -g -DNDEBUG -O3" LDFLAGS="-fno-inline -g -DNDEBUG -O3" --disable-static --enable-blas --enable-lapack #../configure --disable-fast-install --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CXXFLAGS="-fno-inline -g -D_GLIBCXX_DEBUG -DNDEBUG" CFLAGS="-fno-inline -g -D_GLIBCXX_DEBUG -DNDEBUG" LDFLAGS="-fno-inline -g " --disable-static --enable-blas --enable-lapack -../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CXXFLAGS="-g -DNDEBUG -O3" CFLAGS="-g -DNDEBUG -O3" LDFLAGS="-g -DNDEBUG -O3" --disable-static --enable-blas --enable-lapack +../configure --prefix=$HOME/borg --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPPFLAGS="-g -DNDEBUG -O3" LDFLAGS="-g -DNDEBUG -O3" --disable-static --enable-blas --enable-lapack diff --git a/myconfigure.timing b/myconfigure.timing index 8e514a64f..68c701104 100755 --- a/myconfigure.timing +++ b/myconfigure.timing @@ -1,2 +1,2 @@ -../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/opt/local/bin/g++-mp-4.5" CPPFLAGS="-DENABLE_TIMING -DNDEBUG -O3" LDFLAGS="-DNDEBUG -O3" --disable-static --enable-blas --enable-lapack +../configure --prefix=$HOME/borg --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/opt/local/bin/g++-mp-4.5" CPPFLAGS="-DENABLE_TIMING -DNDEBUG -O3" LDFLAGS="-DNDEBUG -O3" --disable-static --enable-blas --enable-lapack #../configure --prefix=$HOME/borg-simplelinear --with-toolbox=$HOME/toolbox/ --with-boost=/opt/local/include/ CPP="/opt/local/bin/cpp-mp-4.5" CC="/opt/local/bin/gcc-mp-4.5" CXX="/opt/local/bin/g++-mp-4.5" CXXFLAGS="-DNDEBUG -g" CFLAGS="-DNDEBUG -g" LDFLAGS="-DNDEBUG -g" --disable-static --enable-blas --enable-lapack diff --git a/slam/smallExample.cpp b/slam/smallExample.cpp index 7e22e51eb..ffeef61bc 100644 --- a/slam/smallExample.cpp +++ b/slam/smallExample.cpp @@ -171,8 +171,8 @@ namespace example { tau(0) = 1.0; // define nodes and specify in reverse topological sort (i.e. parents last) - GaussianConditional::shared_ptr Px_y(new GaussianConditional(_x_, d1, R11, - _y_, S12, tau)), Py(new GaussianConditional(_y_, d2, R22, tau)); + GaussianConditional::shared_ptr Px_y(new GaussianConditional(_x_, d1, R11, _y_, S12, tau)); + GaussianConditional::shared_ptr Py(new GaussianConditional(_y_, d2, R22, tau)); GaussianBayesNet cbn; cbn.push_back(Px_y); cbn.push_back(Py); diff --git a/tests/Makefile.am b/tests/Makefile.am index e7b19922a..a004cc6db 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -12,7 +12,7 @@ check_PROGRAMS = check_PROGRAMS += testGaussianBayesNet testGaussianFactor testGaussianFactorGraph check_PROGRAMS += testGaussianISAM check_PROGRAMS += testGraph -#check_PROGRAMS += testInference +check_PROGRAMS += testInference #check_PROGRAMS += testIterative check_PROGRAMS += testGaussianJunctionTree check_PROGRAMS += testNonlinearEquality testNonlinearFactor testNonlinearFactorGraph diff --git a/tests/testInference.cpp b/tests/testInference.cpp index 0060210bf..99e07e295 100644 --- a/tests/testInference.cpp +++ b/tests/testInference.cpp @@ -23,15 +23,17 @@ using namespace example; /* ************************************************************************* */ TEST(GaussianFactorGraph, createSmoother) { - GaussianFactorGraph fg2 = createSmoother(3); + GaussianFactorGraph fg2; + Ordering ordering; + boost::tie(fg2,ordering) = createSmoother(3); LONGS_EQUAL(5,fg2.size()); // eliminate - Ordering ordering; - GaussianBayesNet bayesNet = fg2.eliminate(ordering); - FactorGraph p_x3 = marginalize(bayesNet, Ordering("x3")); - FactorGraph p_x1 = marginalize(bayesNet, Ordering("x1")); - CHECK(assert_equal(p_x1,p_x3)); // should be the same because of symmetry + list x3var; x3var.push_back(ordering["x3"]); + list x1var; x1var.push_back(ordering["x1"]); + GaussianBayesNet p_x3 = *Inference::Marginal(fg2, x3var); + GaussianBayesNet p_x1 = *Inference::Marginal(fg2, x1var); + CHECK(assert_equal(*p_x1.back(),*p_x3.front())); // should be the same because of symmetry } /* ************************************************************************* */ @@ -39,14 +41,11 @@ TEST( Inference, marginals ) { // create and marginalize a small Bayes net on "x" GaussianBayesNet cbn = createSmallGaussianBayesNet(); - Ordering keys("x"); - FactorGraph fg = marginalize(cbn,keys); - - // turn into Bayes net to test easily - BayesNet actual = eliminate(fg,keys); + list xvar; xvar.push_back(0); + GaussianBayesNet actual = *Inference::Marginal(GaussianFactorGraph(cbn), xvar); // expected is just scalar Gaussian on x - GaussianBayesNet expected = scalarGaussian("x", 4, sqrt(2)); + GaussianBayesNet expected = scalarGaussian(0, 4, sqrt(2)); CHECK(assert_equal(expected,actual)); }