46 using namespace gtsam;
52 std::vector<double>
measurements = {0, 1, 2, 2, 2, 2, 3, 4, 5, 6, 6,
53 7, 8, 9, 9, 9, 10, 11, 11, 11, 11};
55 std::vector<size_t>
discrete_seq = {1, 1, 0, 0, 0, 1, 1, 1, 1, 0,
56 1, 1, 1, 0, 0, 1, 1, 0, 0, 0};
59 const size_t K,
const double between_sigma,
const double measurement_sigma,
61 const std::string& transitionProbabilityTable,
64 transitionProbabilityTable);
78 TEST(HybridEstimation, Full) {
89 for (
size_t k = 0; k <
K; k++) {
90 hybridOrdering.push_back(
X(k));
92 for (
size_t k = 0; k <
K - 1; k++) {
93 hybridOrdering.push_back(
M(k));
106 for (
size_t k = 0; k <
K - 1; k++) {
111 Values expected_continuous;
112 for (
size_t k = 0; k <
K; k++) {
135 const size_t maxNrLeaves = 3;
136 for (
size_t k = 1; k <
K; k++) {
155 for (
size_t k = 0; k <
K - 1; k++) {
160 Values expected_continuous;
161 for (
size_t k = 0; k <
K; k++) {
180 const auto [
bayesNet, remainingGraph] =
181 graph.eliminatePartialSequential(continuous);
184 DiscreteKeys discrete_keys = last_conditional->discreteKeys();
186 const std::vector<DiscreteValues> assignments =
187 DiscreteValues::CartesianProduct(discrete_keys);
189 std::reverse(discrete_keys.begin(), discrete_keys.end());
191 vector<VectorValues::shared_ptr> vector_values;
200 std::vector<double> probPrimes;
206 if (
delta.size() == 0) {
207 probPrimes.push_back(0.0);
215 return probPrimeTree;
222 TEST(HybridEstimation, Probability) {
225 constexpr
size_t K = 4;
226 double between_sigma = 1.0, measurement_sigma = 0.1;
237 graph.eliminatePartialSequential(continuous_ordering);
241 auto discreteBayesNet = discreteGraph->eliminateSequential(discrete_ordering);
244 for (
auto discrete_conditional : *discreteBayesNet) {
261 TEST(HybridEstimation, ProbabilityMultifrontal) {
264 constexpr
size_t K = 4;
266 double between_sigma = 1.0, measurement_sigma = 0.1;
280 graph.eliminatePartialMultifrontal(continuous_ordering);
283 Key last_continuous_key =
284 continuous_ordering.at(continuous_ordering.size() - 1);
285 auto last_conditional = (*bayesTree)[last_continuous_key]->conditional();
286 DiscreteKeys discrete_keys = last_conditional->discreteKeys();
289 auto discreteBayesTree = discreteGraph->eliminateMultifrontal(discrete);
293 auto discrete_clique = (*discreteBayesTree)[discrete.at(0)];
295 std::set<HybridBayesTreeClique::shared_ptr> clique_set;
297 clique_set.insert(node.second);
301 for (
auto clique : clique_set) {
302 if (clique->conditional()->parents() ==
303 discrete_clique->conditional()->frontals()) {
304 discreteBayesTree->addClique(clique, discrete_clique);
309 auto clique_it = std::find(clique->parent()->children.begin(),
310 clique->parent()->children.end(), clique);
311 clique->parent()->children.erase(clique_it);
312 discreteBayesTree->addClique(clique, clique->parent());
316 HybridValues hybrid_values = discreteBayesTree->optimize();
329 constexpr
double sigma = 0.5;
338 const auto zero_motion =
339 std::make_shared<BetweenFactor<double>>(
X(0),
X(1), 0,
noise_model);
340 const auto one_motion =
341 std::make_shared<BetweenFactor<double>>(
X(0),
X(1), 1,
noise_model);
342 std::vector<NoiseModelFactor::shared_ptr>
components = {zero_motion,
356 double z0 = 0.0,
z1 = 1.0;
365 TEST(HybridEstimation, EliminateSequentialRegression) {
400 TEST(HybridEstimation, CorrectnessViaSampling) {
408 std::mt19937_64
rng(11);
411 auto compute_ratio = [&](
const HybridValues& sample) ->
double {
412 return bn->evaluate(sample) / fg->probPrime(sample);
418 double expected_ratio = compute_ratio(sample);
421 constexpr
int num_samples = 10;
422 for (
size_t i = 0;
i < num_samples;
i++) {
432 TEST(HybridEstimation, ModeSelection) {
436 auto measurement_model = noiseModel::Isotropic::Sigma(1, 0.1);
437 auto motion_model = noiseModel::Isotropic::Sigma(1, 1.0);
444 double noise_tight = 0.5, noise_loose = 5.0;
446 auto model0 = std::make_shared<MotionModel>(
447 X(0),
X(1), 0.0, noiseModel::Isotropic::Sigma(
d, noise_loose)),
448 model1 = std::make_shared<MotionModel>(
449 X(0),
X(1), 0.0, noiseModel::Isotropic::Sigma(
d, noise_tight));
472 GaussianConditional::sharedMeanAndStddev(
Z(0), -I_1x1,
X(0), Z_1x1, 0.1));
474 GaussianConditional::sharedMeanAndStddev(
Z(0), -I_1x1,
X(1), Z_1x1, 0.1));
476 std::vector<std::pair<Vector, double>>
parameters{{Z_1x1, noise_loose},
477 {Z_1x1, noise_tight}};
491 TEST(HybridEstimation, ModeSelection2) {
496 double noise_tight = 0.5, noise_loose = 5.0;
502 GaussianConditional::sharedMeanAndStddev(
Z(0), -I_3x3,
X(0),
Z_3x1, 0.1));
504 GaussianConditional::sharedMeanAndStddev(
Z(0), -I_3x3,
X(1),
Z_3x1, 0.1));
506 std::vector<std::pair<Vector, double>>
parameters{{
Z_3x1, noise_loose},
507 {
Z_3x1, noise_tight}};
523 auto measurement_model = noiseModel::Isotropic::Sigma(
d, 0.1);
524 auto motion_model = noiseModel::Isotropic::Sigma(
d, 1.0);
529 auto model0 = std::make_shared<BetweenFactor<Vector3>>(
530 X(0),
X(1),
Z_3x1, noiseModel::Isotropic::Sigma(
d, noise_loose)),
532 X(0),
X(1),
Z_3x1, noiseModel::Isotropic::Sigma(
d, noise_tight));