testGaussianMixtureFactor.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
26 #include <gtsam/inference/Symbol.h>
28 
29 // Include for test suite
31 
32 using namespace std;
33 using namespace gtsam;
37 
38 /* ************************************************************************* */
39 // Check iterators of empty mixture.
40 TEST(GaussianMixtureFactor, Constructor) {
41  GaussianMixtureFactor factor;
42  GaussianMixtureFactor::const_iterator const_it = factor.begin();
43  CHECK(const_it == factor.end());
44  GaussianMixtureFactor::iterator it = factor.begin();
45  CHECK(it == factor.end());
46 }
47 
48 /* ************************************************************************* */
49 // "Add" two mixture factors together.
51  DiscreteKey m1(1, 2), m2(2, 3);
52 
53  auto A1 = Matrix::Zero(2, 1);
54  auto A2 = Matrix::Zero(2, 2);
55  auto A3 = Matrix::Zero(2, 3);
56  auto b = Matrix::Zero(2, 1);
58  sigmas << 1, 2;
59  auto model = noiseModel::Diagonal::Sigmas(sigmas, true);
60 
61  auto f10 = std::make_shared<JacobianFactor>(X(1), A1, X(2), A2, b);
62  auto f11 = std::make_shared<JacobianFactor>(X(1), A1, X(2), A2, b);
63  auto f20 = std::make_shared<JacobianFactor>(X(1), A1, X(3), A3, b);
64  auto f21 = std::make_shared<JacobianFactor>(X(1), A1, X(3), A3, b);
65  auto f22 = std::make_shared<JacobianFactor>(X(1), A1, X(3), A3, b);
66  std::vector<GaussianFactor::shared_ptr> factorsA{f10, f11};
67  std::vector<GaussianFactor::shared_ptr> factorsB{f20, f21, f22};
68 
69  // TODO(Frank): why specify keys at all? And: keys in factor should be *all*
70  // keys, deviating from Kevin's scheme. Should we index DT on DiscreteKey?
71  // Design review!
72  GaussianMixtureFactor mixtureFactorA({X(1), X(2)}, {m1}, factorsA);
73  GaussianMixtureFactor mixtureFactorB({X(1), X(3)}, {m2}, factorsB);
74 
75  // Check that number of keys is 3
76  EXPECT_LONGS_EQUAL(3, mixtureFactorA.keys().size());
77 
78  // Check that number of discrete keys is 1
79  EXPECT_LONGS_EQUAL(1, mixtureFactorA.discreteKeys().size());
80 
81  // Create sum of two mixture factors: it will be a decision tree now on both
82  // discrete variables m1 and m2:
84  sum += mixtureFactorA;
85  sum += mixtureFactorB;
86 
87  // Let's check that this worked:
89  mode[m1.first] = 1;
90  mode[m2.first] = 2;
91  auto actual = sum(mode);
92  EXPECT(actual.at(0) == f11);
93  EXPECT(actual.at(1) == f22);
94 }
95 
96 /* ************************************************************************* */
98  DiscreteKey m1(1, 2);
99  auto A1 = Matrix::Zero(2, 1);
100  auto A2 = Matrix::Zero(2, 2);
101  auto b = Matrix::Zero(2, 1);
102  auto f10 = std::make_shared<JacobianFactor>(X(1), A1, X(2), A2, b);
103  auto f11 = std::make_shared<JacobianFactor>(X(1), A1, X(2), A2, b);
104  std::vector<GaussianFactor::shared_ptr> factors{f10, f11};
105 
106  GaussianMixtureFactor mixtureFactor({X(1), X(2)}, {m1}, factors);
107 
108  std::string expected =
109  R"(Hybrid [x1 x2; 1]{
110  Choice(1)
111  0 Leaf :
112  A[x1] = [
113  0;
114  0
115 ]
116  A[x2] = [
117  0, 0;
118  0, 0
119 ]
120  b = [ 0 0 ]
121  No noise model
122 
123  1 Leaf :
124  A[x1] = [
125  0;
126  0
127 ]
128  A[x2] = [
129  0, 0;
130  0, 0
131 ]
132  b = [ 0 0 ]
133  No noise model
134 
135 }
136 )";
137  EXPECT(assert_print_equal(expected, mixtureFactor));
138 }
139 
140 /* ************************************************************************* */
142  KeyVector keys;
143  keys.push_back(X(0));
144  keys.push_back(X(1));
145 
146  DiscreteKeys dKeys;
147  dKeys.emplace_back(M(0), 2);
148  dKeys.emplace_back(M(1), 2);
149 
150  auto gaussians = std::make_shared<GaussianConditional>();
152  GaussianMixture gm({}, keys, dKeys, conditionals);
153 
154  EXPECT_LONGS_EQUAL(2, gm.discreteKeys().size());
155 }
156 
157 /* ************************************************************************* */
158 // Test the error of the GaussianMixtureFactor
160  DiscreteKey m1(1, 2);
161 
162  auto A01 = Matrix2::Identity();
163  auto A02 = Matrix2::Identity();
164 
165  auto A11 = Matrix2::Identity();
166  auto A12 = Matrix2::Identity() * 2;
167 
168  auto b = Vector2::Zero();
169 
170  auto f0 = std::make_shared<JacobianFactor>(X(1), A01, X(2), A02, b);
171  auto f1 = std::make_shared<JacobianFactor>(X(1), A11, X(2), A12, b);
172  std::vector<GaussianFactor::shared_ptr> factors{f0, f1};
173 
174  GaussianMixtureFactor mixtureFactor({X(1), X(2)}, {m1}, factors);
175 
176  VectorValues continuousValues;
177  continuousValues.insert(X(1), Vector2(0, 0));
178  continuousValues.insert(X(2), Vector2(1, 1));
179 
180  // error should return a tree of errors, with nodes for each discrete value.
181  AlgebraicDecisionTree<Key> error_tree = mixtureFactor.error(continuousValues);
182 
183  std::vector<DiscreteKey> discrete_keys = {m1};
184  // Error values for regression test
185  std::vector<double> errors = {1, 4};
186  AlgebraicDecisionTree<Key> expected_error(discrete_keys, errors);
187 
188  EXPECT(assert_equal(expected_error, error_tree));
189 
190  // Test for single leaf given discrete assignment P(X|M,Z).
191  DiscreteValues discreteValues;
192  discreteValues[m1.first] = 1;
194  4.0, mixtureFactor.error({continuousValues, discreteValues}),
195  1e-9);
196 }
197 
198 /* ************************************************************************* */
199 int main() {
200  TestResult tr;
201  return TestRegistry::runAllTests(tr);
202 }
203 /* ************************************************************************* */
static Matrix A1
A set of GaussianFactors, indexed by a set of discrete keys.
Provides additional testing facilities for common data structures.
#define CHECK(condition)
Definition: Test.h:108
A hybrid conditional in the Conditional Linear Gaussian scheme.
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:51
Scalar * b
Definition: benchVecAdd.cpp:17
static int runAllTests(TestResult &result)
bool assert_print_equal(const std::string &expected, const V &actual, const std::string &s="")
noiseModel::Diagonal::shared_ptr model
Matrix expected
Definition: testMatrix.cpp:971
MatrixType m2(n_dims)
Implementation of a discrete conditional mixture factor. Implements a joint discrete-continuous facto...
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
Definition: Matrix.cpp:40
const GaussianFactorGraph factors
Definition: BFloat16.h:88
iterator insert(const std::pair< Key, Vector > &key_value)
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
Definition: Test.h:161
const_iterator end() const
Definition: Factor.h:148
A conditional of gaussian mixtures indexed by discrete variables, as part of a Bayes Network...
Matrix3d m1
Definition: IOFormat.cpp:2
#define EXPECT(condition)
Definition: Test.h:150
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Linear Factor Graph where all factors are Gaussians.
TEST(GaussianMixtureFactor, Constructor)
traits
Definition: chartTesting.h:28
Eigen::Vector2d Vector2
Definition: Vector.h:42
#define EXPECT_LONGS_EQUAL(expected, actual)
Definition: Test.h:154
Point2 f1(const Point3 &p, OptionalJacobian< 2, 3 > H)
std::pair< Key, size_t > DiscreteKey
Definition: DiscreteKey.h:38
const std::vector< GaussianConditional::shared_ptr > conditionals
static const DiscreteKey mode(modeKey, 2)
const KeyVector keys
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
Definition: Key.h:86
const_iterator begin() const
Definition: Factor.h:145
#define X
Definition: icosphere.cpp:20
DiscreteKeys is a set of keys that can be assembled using the & operator.
Definition: DiscreteKey.h:41


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:38:12