Sampling from GaussianBayesNet
parent
f9e6282a2c
commit
539bf70829
|
|
@ -37,28 +37,40 @@ namespace gtsam {
|
||||||
return Base::equals(bn, tol);
|
return Base::equals(bn, tol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************ */
|
||||||
VectorValues GaussianBayesNet::optimize() const
|
VectorValues GaussianBayesNet::optimize() const {
|
||||||
{
|
VectorValues solution; // no missing variables -> create an empty vector
|
||||||
VectorValues soln; // no missing variables -> just create an empty vector
|
return optimize(solution);
|
||||||
return optimize(soln);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
VectorValues GaussianBayesNet::optimize(VectorValues solution) const {
|
||||||
VectorValues GaussianBayesNet::optimize(
|
|
||||||
const VectorValues& solutionForMissing) const {
|
|
||||||
VectorValues soln(solutionForMissing); // possibly empty
|
|
||||||
// (R*x)./sigmas = y by solving x=inv(R)*(y.*sigmas)
|
// (R*x)./sigmas = y by solving x=inv(R)*(y.*sigmas)
|
||||||
/** solve each node in turn in topological sort order (parents first)*/
|
// solve each node in reverse topological sort order (parents first)
|
||||||
for (auto cg: boost::adaptors::reverse(*this)) {
|
for (auto cg : boost::adaptors::reverse(*this)) {
|
||||||
// i^th part of R*x=y, x=inv(R)*y
|
// i^th part of R*x=y, x=inv(R)*y
|
||||||
// (Rii*xi + R_i*x(i+1:))./si = yi <-> xi = inv(Rii)*(yi.*si - R_i*x(i+1:))
|
// (Rii*xi + R_i*x(i+1:))./si = yi =>
|
||||||
soln.insert(cg->solve(soln));
|
// xi = inv(Rii)*(yi.*si - R_i*x(i+1:))
|
||||||
|
solution.insert(cg->solve(solution));
|
||||||
}
|
}
|
||||||
return soln;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************ */
|
||||||
|
VectorValues GaussianBayesNet::sample() const {
|
||||||
|
VectorValues result; // no missing variables -> create an empty vector
|
||||||
|
return sample(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
VectorValues GaussianBayesNet::sample(VectorValues result) const {
|
||||||
|
// sample each node in reverse topological sort order (parents first)
|
||||||
|
for (auto cg : boost::adaptors::reverse(*this)) {
|
||||||
|
const VectorValues sampled = cg->sample(result);
|
||||||
|
result.insert(sampled);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************ */
|
||||||
VectorValues GaussianBayesNet::optimizeGradientSearch() const
|
VectorValues GaussianBayesNet::optimizeGradientSearch() const
|
||||||
{
|
{
|
||||||
gttic(GaussianBayesTree_optimizeGradientSearch);
|
gttic(GaussianBayesTree_optimizeGradientSearch);
|
||||||
|
|
|
||||||
|
|
@ -88,11 +88,18 @@ namespace gtsam {
|
||||||
/// @name Standard Interface
|
/// @name Standard Interface
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// Solve the GaussianBayesNet, i.e. return \f$ x = R^{-1}*d \f$, by back-substitution
|
/// Solve the GaussianBayesNet, i.e. return \f$ x = R^{-1}*d \f$, by
|
||||||
|
/// back-substitution
|
||||||
VectorValues optimize() const;
|
VectorValues optimize() const;
|
||||||
|
|
||||||
/// Version of optimize for incomplete BayesNet, needs solution for missing variables
|
/// Version of optimize for incomplete BayesNet, given missing variables
|
||||||
VectorValues optimize(const VectorValues& solutionForMissing) const;
|
VectorValues optimize(const VectorValues given) const;
|
||||||
|
|
||||||
|
/// Sample using ancestral sampling
|
||||||
|
VectorValues sample() const;
|
||||||
|
|
||||||
|
/// Sample from an incomplete BayesNet, given missing variables
|
||||||
|
VectorValues sample(VectorValues given) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return ordering corresponding to a topological sort.
|
* Return ordering corresponding to a topological sort.
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gtsam/linear/GaussianBayesNet.h>
|
#include <gtsam/linear/GaussianBayesNet.h>
|
||||||
|
#include <gtsam/linear/GaussianDensity.h>
|
||||||
#include <gtsam/linear/JacobianFactor.h>
|
#include <gtsam/linear/JacobianFactor.h>
|
||||||
#include <gtsam/linear/GaussianFactorGraph.h>
|
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||||
#include <gtsam/base/Testable.h>
|
#include <gtsam/base/Testable.h>
|
||||||
#include <gtsam/base/numericalDerivative.h>
|
#include <gtsam/base/numericalDerivative.h>
|
||||||
|
#include <gtsam/inference/Symbol.h>
|
||||||
|
|
||||||
#include <CppUnitLite/TestHarness.h>
|
#include <CppUnitLite/TestHarness.h>
|
||||||
#include <boost/tuple/tuple.hpp>
|
#include <boost/tuple/tuple.hpp>
|
||||||
|
|
@ -35,6 +37,7 @@ using namespace boost::assign;
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace gtsam;
|
using namespace gtsam;
|
||||||
|
using symbol_shorthand::X;
|
||||||
|
|
||||||
static const Key _x_ = 11, _y_ = 22, _z_ = 33;
|
static const Key _x_ = 11, _y_ = 22, _z_ = 33;
|
||||||
|
|
||||||
|
|
@ -138,6 +141,22 @@ TEST( GaussianBayesNet, optimize3 )
|
||||||
EXPECT(assert_equal(expected, actual));
|
EXPECT(assert_equal(expected, actual));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************************************************* */
|
||||||
|
TEST(GaussianBayesNet, sample) {
|
||||||
|
GaussianBayesNet gbn;
|
||||||
|
Matrix A1 = (Matrix(2, 2) << 1., 2., 3., 4.).finished();
|
||||||
|
const Vector2 mean(20, 40), b(10, 10);
|
||||||
|
const double sigma = 0.01;
|
||||||
|
|
||||||
|
gbn.add(GaussianConditional::FromMeanAndStddev(X(0), A1, X(1), b, sigma));
|
||||||
|
gbn.add(GaussianDensity::FromMeanAndStddev(X(1), mean, sigma));
|
||||||
|
|
||||||
|
auto actual = gbn.sample();
|
||||||
|
EXPECT_LONGS_EQUAL(2, actual.size());
|
||||||
|
EXPECT(assert_equal(mean, actual[X(1)], 50 * sigma));
|
||||||
|
EXPECT(assert_equal(A1 * mean + b, actual[X(0)], 50 * sigma));
|
||||||
|
}
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
TEST(GaussianBayesNet, ordering)
|
TEST(GaussianBayesNet, ordering)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue