51 using namespace gtsam;
61 std::mt19937_64
kRng(42);
76 std::make_shared<GaussianConditional>(
77 X(0),
Z_3x1, I_3x3,
X(1), I_3x3),
78 std::make_shared<GaussianConditional>(
79 X(0), Vector3::Ones(), I_3x3,
X(1), I_3x3)));
109 ordering.push_back(
X(0));
129 M(1), std::make_shared<JacobianFactor>(
X(1), I_3x3,
Z_3x1),
130 std::make_shared<JacobianFactor>(
X(1), I_3x3, Vector3::Ones()));
135 auto dc =
result->
at(2)->asDiscrete();
154 std::vector<GaussianFactor::shared_ptr>
factors = {
155 std::make_shared<JacobianFactor>(
X(1), I_3x3,
Z_3x1),
156 std::make_shared<JacobianFactor>(
X(1), I_3x3, Vector3::Ones())};
181 {std::make_shared<JacobianFactor>(
X(1), I_3x3,
Z_3x1),
182 std::make_shared<JacobianFactor>(
X(1), I_3x3, Vector3::Ones())}));
210 M(1), std::make_shared<JacobianFactor>(
X(1), I_3x3,
Z_3x1),
211 std::make_shared<JacobianFactor>(
X(1), I_3x3, Vector3::Ones()));
241 {std::make_shared<JacobianFactor>(
X(0), I_3x3,
Z_3x1),
242 std::make_shared<JacobianFactor>(
X(0), I_3x3, Vector3::Ones())}));
245 M(1), std::make_shared<JacobianFactor>(
X(2), I_3x3,
Z_3x1),
246 std::make_shared<JacobianFactor>(
X(2), I_3x3, Vector3::Ones()));
258 M(3), std::make_shared<JacobianFactor>(
X(3), I_3x3,
Z_3x1),
259 std::make_shared<JacobianFactor>(
X(3), I_3x3, Vector3::Ones()));
264 M(2), std::make_shared<JacobianFactor>(
X(5), I_3x3,
Z_3x1),
265 std::make_shared<JacobianFactor>(
X(5), I_3x3, Vector3::Ones()));
271 Ordering::ColamdConstrainedLast(hfg, {
M(0),
M(1),
M(2),
M(3)});
322 std::vector<int> naturalX(
N);
323 std::iota(naturalX.begin(), naturalX.end(), 1);
324 std::vector<Key> ordX;
325 std::transform(naturalX.begin(), naturalX.end(), std::back_inserter(ordX),
326 [](
int x) {
return X(
x); });
329 std::copy(ndX.begin(), ndX.end(), std::back_inserter(ordering));
331 for (
auto &
l : lvls) {
336 std::vector<int> naturalC(
N - 1);
337 std::iota(naturalC.begin(), naturalC.end(), 1);
338 std::vector<Key> ordC;
339 std::transform(naturalC.begin(), naturalC.end(), std::back_inserter(ordC),
340 [](
int x) {
return M(
x); });
344 std::copy(ndC.begin(), ndC.end(), std::back_inserter(ordering));
346 auto ordering_full =
Ordering(ordering);
351 const auto [hbt, remaining] =
352 hfg->eliminatePartialMultifrontal(ordering_full);
379 std::vector<int> naturalX(
N);
380 std::iota(naturalX.begin(), naturalX.end(), 1);
381 std::vector<Key> ordX;
382 std::transform(naturalX.begin(), naturalX.end(), std::back_inserter(ordX),
383 [](
int x) {
return X(
x); });
386 std::copy(ndX.begin(), ndX.end(), std::back_inserter(ordering));
388 for (
auto &
l : lvls) {
393 std::vector<int> naturalC(
N - 1);
394 std::iota(naturalC.begin(), naturalC.end(), 1);
395 std::vector<Key> ordC;
396 std::transform(naturalC.begin(), naturalC.end(), std::back_inserter(ordC),
397 [](
int x) {
return M(
x); });
401 std::copy(ndC.begin(), ndC.end(), std::back_inserter(ordering));
403 auto ordering_full =
Ordering(ordering);
405 const auto [hbt, remaining] =
406 hfg->eliminatePartialMultifrontal(ordering_full);
413 factorGraph.
push_back(new_fg->at(new_fg->size() - 2));
414 factorGraph.
push_back(new_fg->at(new_fg->size() - 1));
427 for (
int t = 1;
t <=
N;
t++) {
434 std::iota(naturalX.begin(), naturalX.end(), 1);
436 for (
size_t i = 1;
i <=
N;
i++) {
437 ordX.emplace_back(
X(
i));
438 ordX.emplace_back(
Y(
i));
441 for (
size_t i = 1;
i <= N - 1;
i++) {
442 ordX.emplace_back(
M(
i));
444 for (
size_t i = 1;
i <= N - 1;
i++) {
445 ordX.emplace_back(
D(
i));
471 for (
size_t i = 1;
i <=
N;
i++) {
472 ordering_partial.emplace_back(
X(
i));
473 ordering_partial.emplace_back(
Y(
i));
475 const auto [hbn, remaining] =
476 hfg->eliminatePartialSequential(ordering_partial);
502 C(1), std::make_shared<JacobianFactor>(
X(1), I_3x3,
Z_3x1),
503 std::make_shared<JacobianFactor>(
X(1), I_3x3, Vector3::Ones()));
522 ordering.push_back(
X(0));
529 ordering.push_back(
X(1));
530 ordering.push_back(
X(2));
531 ordering.push_back(
M(0));
532 ordering.push_back(
M(1));
538 Values expected_continuous;
539 expected_continuous.
insert<
double>(
X(0), 0);
540 expected_continuous.
insert<
double>(
X(1), 1);
541 expected_continuous.
insert<
double>(
X(2), 2);
542 expected_continuous.
insert<
double>(
X(3), 4);
543 Values result_continuous =
548 expected_discrete[
M(0)] = 1;
549 expected_discrete[
M(1)] = 1;
584 std::vector<DiscreteKey> discrete_keys = {{
M(0), 2}, {
M(1), 2}};
585 std::vector<double> leaves = {0.9998558, 0.4902432, 0.5193694, 0.0097568};
592 std::vector<double> prob_leaves = {0.36793249, 0.61247742, 0.59489556,
604 const int num_measurements = 1;
610 auto actual = fg.assembleGraphTree();
621 using GF = GaussianFactor::shared_ptr;
622 const GF
prior = gf->asGaussian();
643 auto compute_ratio = [&](
HybridValues *sample) ->
double {
644 sample->update(measurements);
649 double expected_ratio = compute_ratio(&sample);
652 for (
size_t i = 0;
i < num_samples;
i++) {
654 if (
std::abs(expected_ratio - compute_ratio(&sample)) > 1
e-6)
return false;
664 auto compute_ratio = [&](
HybridValues *sample) ->
double {
665 sample->update(measurements);
670 double expected_ratio = compute_ratio(&sample);
673 for (
size_t i = 0;
i < num_samples;
i++) {
677 if (
std::abs(expected_ratio - compute_ratio(&sample)) > 1
e-6)
return false;
685 const int num_measurements = 1;
688 auto fg = bn.toFactorGraph(measurements);
699 const auto conditional0 = std::make_shared<GaussianConditional>(
700 X(0),
Vector1(14.1421), I_1x1 * 2.82843),
701 conditional1 = std::make_shared<GaussianConditional>(
702 X(0),
Vector1(10.1379), I_1x1 * 2.02759);
710 const auto posterior = fg.eliminateSequential();
729 {GaussianConditional::sharedMeanAndStddev(
Z(0), I_1x1,
X(0), Z_1x1, 3),
730 GaussianConditional::sharedMeanAndStddev(
Z(0), I_1x1,
X(0), Z_1x1,
735 GaussianConditional::sharedMeanAndStddev(
X(0),
Vector1(5.0), 0.5));
753 const auto conditional0 = std::make_shared<GaussianConditional>(
754 X(0),
Vector1(10.1379), I_1x1 * 2.02759),
755 conditional1 = std::make_shared<GaussianConditional>(
756 X(0),
Vector1(14.1421), I_1x1 * 2.82843);
764 const auto posterior = fg.eliminateSequential();
777 const int num_measurements = 2;
780 auto fg = bn.toFactorGraph(measurements);
789 const auto conditional0 = std::make_shared<GaussianConditional>(
790 X(0),
Vector1(17.3205), I_1x1 * 3.4641),
791 conditional1 = std::make_shared<GaussianConditional>(
792 X(0),
Vector1(10.274), I_1x1 * 2.0548);
793 expectedBayesNet.emplace_back(
800 const auto posterior = fg.eliminateSequential();
810 const int num_measurements = 2;
811 const bool manyModes =
true;
816 auto fg = bn.toFactorGraph(measurements);
822 const auto posterior = fg.eliminateSequential();
836 for (
size_t t : {0, 1, 2}) {
841 {GaussianConditional::sharedMeanAndStddev(
842 Z(
t), I_1x1,
X(
t), Z_1x1, 0.5),
843 GaussianConditional::sharedMeanAndStddev(
844 Z(
t), I_1x1,
X(
t), Z_1x1, 3.0)}));
851 for (
size_t t : {2, 1}) {
856 {GaussianConditional::sharedMeanAndStddev(
857 X(
t), I_1x1,
X(
t - 1), Z_1x1, 0.2),
858 GaussianConditional::sharedMeanAndStddev(
859 X(
t), I_1x1,
X(
t - 1), I_1x1, 0.2)}));
866 bn.
push_back(GaussianConditional::sharedMeanAndStddev(
X(0), Z_1x1, 0.1));
893 fg1->push_back(*bn1);
HybridGaussianFactorGraph::shared_ptr makeSwitchingChain(size_t n, std::function< Key(int)> keyFunc=X, std::function< Key(int)> dKeyFunc=M)
Create a switching system chain. A switching system is a continuous system which depends on a discret...
A set of GaussianFactors, indexed by a set of discrete keys.
Provides additional testing facilities for common data structures.
A hybrid conditional in the Conditional Linear Gaussian scheme.
Matrix< RealScalar, Dynamic, Dynamic > M
std::pair< KeyVector, std::vector< int > > makeBinaryOrdering(std::vector< Key > &input)
Return the ordering as a binary tree such that all parent nodes are above their children.
std::pair< std::shared_ptr< BayesTreeType >, std::shared_ptr< FactorGraphType > > eliminatePartialMultifrontal(const Ordering &ordering, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
static const Eigen::MatrixBase< Vector3 >::ConstantReturnType Z_3x1
IsDerived< DERIVEDFACTOR > emplace_shared(Args &&... args)
Emplace a shared pointer to factor of given type.
static int runAllTests(TestResult &result)
Eigen::Matrix< double, 1, 1 > Vector1
Point2 prior(const Point2 &x)
Prior on a single pose.
const ValueType at(Key j) const
TEST(HybridGaussianFactorGraph, Creation)
std::shared_ptr< This > shared_ptr
IsDerived< DERIVEDFACTOR > push_back(std::shared_ptr< DERIVEDFACTOR > factor)
Add a factor directly using a shared_ptr.
Implementation of a discrete conditional mixture factor. Implements a joint discrete-continuous facto...
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
std::pair< std::shared_ptr< BayesNetType >, std::shared_ptr< FactorGraphType > > eliminatePartialSequential(const Ordering &ordering, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
const Ordering HybridOrdering(const HybridGaussianFactorGraph &graph)
Return a Colamd constrained ordering where the discrete keys are eliminated after the continuous keys...
const GaussianFactorGraph factors
double evaluate(const HybridValues &values) const
Evaluate hybrid probability density for given HybridValues.
const VectorValues & continuous() const
Return the multi-dimensional vector values.
void update(const NonlinearFactorGraph &newFactors, const Values &initialValues)
NonlinearFactorGraph graph
static const KeyFormatter DefaultKeyFormatter
static enum @1107 ordering
#define EXPECT_DOUBLES_EQUAL(expected, actual, threshold)
IsDerived< DERIVEDFACTOR > add(std::shared_ptr< DERIVEDFACTOR > factor)
add is a synonym for push_back.
A Bayes net of Gaussian Conditionals indexed by discrete keys.
Values retract(const VectorValues &delta) const
EIGEN_DEVICE_FUNC const ExpReturnType exp() const
HybridGaussianFactorGraph linearizedFactorGraph
static const Line3 l(Rot3(), 1, 1)
A conditional of gaussian mixtures indexed by discrete variables, as part of a Bayes Network...
void dotPrint(const HybridGaussianFactorGraph::shared_ptr &hfg, const HybridBayesTree::shared_ptr &hbt, const Ordering &ordering)
Hybrid Bayes Tree, the result of eliminating a HybridJunctionTree.
AlgebraicDecisionTree< Key > error(const VectorValues &continuousValues) const
Compute error for each discrete assignment, and return as a tree.
#define EXPECT(condition)
std::shared_ptr< BayesNetType > eliminateSequential(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
Array< double, 1, 3 > e(1./3., 0.5, 2.)
NonlinearISAM isam(relinearizeInterval)
std::shared_ptr< This > shared_ptr
shared_ptr to This
void push_back(std::shared_ptr< HybridConditional > conditional)
Add a hybrid conditional using a shared_ptr.
EIGEN_DONT_INLINE void transform(const Transformation &t, Data &data)
AlgebraicDecisionTree< Key > probPrime(const VectorValues &continuousValues) const
Compute unnormalized probability for each discrete assignment, and return as a tree.
Linearized Hybrid factor graph that uses type erasure.
void emplace_back(Conditional *conditional)
Matrix< Scalar, Dynamic, Dynamic > C
DotWriter is a helper class for writing graphviz .dot files.
specialized key for discrete variables
bool ratioTest(const HybridBayesNet &bn, const VectorValues &measurements, const HybridGaussianFactorGraph &fg, size_t num_samples=100)
Values linearizationPoint
#define EXPECT_LONGS_EQUAL(expected, actual)
const sharedFactor at(size_t i) const
int optimize(const SfmData &db, const NonlinearFactorGraph &graph, const Values &initial, bool separateCalibration=false)
const DiscreteValues & discrete() const
Return the discrete values.
std::pair< Key, size_t > DiscreteKey
std::shared_ptr< BayesTreeType > eliminateMultifrontal(OptionalOrderingType orderingType={}, const Eliminate &function=EliminationTraitsType::DefaultEliminate, OptionalVariableIndex variableIndex={}) const
HybridBayesNet createHybridBayesNet(size_t num_measurements=1, bool manyModes=false)
void insert(Key j, const Value &val)
static const DiscreteKey mode(modeKey, 2)
HybridValues sample(const HybridValues &given, std::mt19937_64 *rng) const
Sample from an incomplete BayesNet, given missing variables.
FastVector< Key > KeyVector
Define collection type once and for all - also used in wrappers.
const GaussianMixture mixture({Z(0)}, {X(0)}, {mode}, conditionals)
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy x
size_t & atDiscrete(Key j)
std::shared_ptr< HybridBayesNet > shared_ptr
HybridGaussianFactorGraph toFactorGraph(const VectorValues &measurements) const
static HybridGaussianFactorGraph::shared_ptr createHybridGaussianFactorGraph()
DiscreteKeys is a set of keys that can be assembled using the & operator.
std::map< char, double > positionHints