29
29
#include < gtsam/hybrid/HybridValues.h>
30
30
#include < gtsam/inference/Symbol.h>
31
31
#include < gtsam/linear/GaussianFactorGraph.h>
32
+ #include < gtsam/linear/VectorValues.h>
32
33
#include < gtsam/nonlinear/PriorFactor.h>
33
34
#include < gtsam/slam/BetweenFactor.h>
34
35
@@ -433,20 +434,20 @@ HybridBayesNet CreateBayesNet(
433
434
return hbn;
434
435
}
435
436
436
- // / Create importance sampling network p(x1| x0, m1) p (x0) P(m1),
437
- // / using Q (x0) = N(z0, sigma_Q) to sample from p(x0)
437
+ // / Create importance sampling network q(x0,x1,m) = p(x1|x0,m1) q (x0) P(m1),
438
+ // / using q (x0) = N(z0, sigma_Q) to sample x0.
438
439
HybridBayesNet CreateProposalNet (
439
- const GaussianMixture::shared_ptr& hybridMotionModel, double z0,
440
+ const GaussianMixture::shared_ptr& hybridMotionModel, const Vector1& z0,
440
441
double sigma_Q) {
441
442
HybridBayesNet hbn;
442
443
443
444
// Add hybrid motion model
444
445
hbn.push_back (hybridMotionModel);
445
446
446
- // Add proposal Q (x0) for x0
447
+ // Add proposal q (x0) for x0
447
448
auto measurement_model = noiseModel::Isotropic::Sigma (1 , sigma_Q);
448
449
hbn.emplace_shared <GaussianConditional>(
449
- GaussianConditional::FromMeanAndStddev (X (0 ), Vector1 (z0) , sigma_Q));
450
+ GaussianConditional::FromMeanAndStddev (X (0 ), z0 , sigma_Q));
450
451
451
452
// Discrete uniform prior.
452
453
hbn.emplace_shared <DiscreteConditional>(m1, " 0.5/0.5" );
@@ -466,7 +467,7 @@ void approximateDiscreteMarginal(const HybridBayesNet& hbn,
466
467
HybridValues sample = proposalNet.sample (&rng);
467
468
sample.insert (given);
468
469
double weight = hbn.evaluate (sample) / proposalNet.evaluate (sample);
469
- (sample.atDiscrete (m1. first ) == 0 ) ? w0 += weight : w1 += weight;
470
+ (sample.atDiscrete (M ( 1 ) ) == 0 ) ? w0 += weight : w1 += weight;
470
471
}
471
472
double sumWeights = w0 + w1;
472
473
double pm1 = w1 / sumWeights;
@@ -478,15 +479,14 @@ void approximateDiscreteMarginal(const HybridBayesNet& hbn,
478
479
479
480
/* ************************************************************************* */
480
481
/* *
481
- * Test a model P (z0|x0)P(x1 |x0,m1)P(z1|x1 )P(m1).
482
+ * Test a model p (z0|x0)p(z1|x1)p(x1 |x0,m1)P(m1).
482
483
*
483
- * P(f01|x1, x0,m1) has different means and same covariance.
484
+ * p(x1| x0,m1) has mode-dependent mean but same covariance.
484
485
*
485
- * Converting to a factor graph gives us
486
- * ϕ(x0)ϕ(x1,x0,m1)ϕ(x1)P(m1)
486
+ * Converting to a factor graph gives us ϕ(x0;z0)ϕ(x1;z1)ϕ(x1,x0,m1)P(m1)
487
487
*
488
- * If we only have a measurement on z0 , then
489
- * the probability of m1 should be 0.5/0.5.
488
+ * If we only have a measurement on x0 , then
489
+ * the posterior probability of m1 should be 0.5/0.5.
490
490
* Getting a measurement on z1 gives use more information.
491
491
*/
492
492
TEST (GaussianMixtureFactor, TwoStateModel) {
@@ -497,10 +497,10 @@ TEST(GaussianMixtureFactor, TwoStateModel) {
497
497
auto hybridMotionModel = CreateHybridMotionModel (mu0, mu1, sigma, sigma);
498
498
499
499
// Start with no measurement on x1, only on x0
500
- double z0 = 0.5 ;
500
+ const Vector1 z0 ( 0.5 ) ;
501
501
502
502
VectorValues given;
503
- given.insert (Z (0 ), Vector1 (z0) );
503
+ given.insert (Z (0 ), z0 );
504
504
505
505
// Create proposal network for importance sampling
506
506
auto proposalNet = CreateProposalNet (hybridMotionModel, z0, 3.0 );
@@ -522,10 +522,10 @@ TEST(GaussianMixtureFactor, TwoStateModel) {
522
522
// Now we add a measurement z1 on x1
523
523
HybridBayesNet hbn = CreateBayesNet (hybridMotionModel, true );
524
524
525
- // If we see z1=4.5 (>> 2.5 which is the halfway point),
526
- // discrete mode should say m1=1
527
- const double z1 = 4.5 ;
528
- given.insert (Z (1 ), Vector1 (z1) );
525
+ // If we set z1=4.5 (>> 2.5 which is the halfway point),
526
+ // probability of discrete mode should be leaning to m1==1.
527
+ const Vector1 z1 ( 4.5 ) ;
528
+ given.insert (Z (1 ), z1 );
529
529
530
530
HybridGaussianFactorGraph gfg = hbn.toFactorGraph (given);
531
531
HybridBayesNet::shared_ptr bn = gfg.eliminateSequential ();
@@ -534,7 +534,7 @@ TEST(GaussianMixtureFactor, TwoStateModel) {
534
534
// Values taken from an importance sampling run with 50k samples:
535
535
// approximateDiscreteMarginal(hbn, proposalNet, given);
536
536
DiscreteConditional expected (m1, " 0.446629/0.553371" );
537
- EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.01 ));
537
+ EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.002 ));
538
538
}
539
539
}
540
540
@@ -559,9 +559,9 @@ TEST(GaussianMixtureFactor, TwoStateModel2) {
559
559
auto hybridMotionModel = CreateHybridMotionModel (mu0, mu1, sigma0, sigma1);
560
560
561
561
// Start with no measurement on x1, only on x0
562
- double z0 = 0.5 ;
562
+ const Vector1 z0 ( 0.5 ) ;
563
563
VectorValues given;
564
- given.insert (Z (0 ), Vector1 (z0) );
564
+ given.insert (Z (0 ), z0 );
565
565
566
566
// Create proposal network for importance sampling
567
567
// uncomment this and the approximateDiscreteMarginal calls to run
@@ -571,19 +571,13 @@ TEST(GaussianMixtureFactor, TwoStateModel2) {
571
571
HybridBayesNet hbn = CreateBayesNet (hybridMotionModel);
572
572
HybridGaussianFactorGraph gfg = hbn.toFactorGraph (given);
573
573
574
- {
575
- VectorValues vv{
576
- {X (0 ), Vector1 (0.0 )}, {X (1 ), Vector1 (1.0 )}, {Z (0 ), Vector1 (z0)}};
577
- HybridValues hv0 (vv, DiscreteValues{{M (1 ), 0 }}),
578
- hv1 (vv, DiscreteValues{{M (1 ), 1 }});
579
- EXPECT_DOUBLES_EQUAL (gfg.error (hv0) / hbn.error (hv0),
580
- gfg.error (hv1) / hbn.error (hv1), 1e-9 );
581
- }
582
- {
583
- VectorValues vv{
584
- {X (0 ), Vector1 (0.5 )}, {X (1 ), Vector1 (3.0 )}, {Z (0 ), Vector1 (z0)}};
585
- HybridValues hv0 (vv, DiscreteValues{{M (1 ), 0 }}),
586
- hv1 (vv, DiscreteValues{{M (1 ), 1 }});
574
+ // Check that ratio of Bayes net and factor graph for different modes is
575
+ // equal for several values of {x0,x1}.
576
+ for (VectorValues vv :
577
+ {VectorValues{{X (0 ), Vector1 (0.0 )}, {X (1 ), Vector1 (1.0 )}},
578
+ VectorValues{{X (0 ), Vector1 (0.5 )}, {X (1 ), Vector1 (3.0 )}}}) {
579
+ vv.insert (given); // add measurements for HBN
580
+ HybridValues hv0 (vv, {{M (1 ), 0 }}), hv1 (vv, {{M (1 ), 1 }});
587
581
EXPECT_DOUBLES_EQUAL (gfg.error (hv0) / hbn.error (hv0),
588
582
gfg.error (hv1) / hbn.error (hv1), 1e-9 );
589
583
}
@@ -595,66 +589,54 @@ TEST(GaussianMixtureFactor, TwoStateModel2) {
595
589
596
590
// Since no measurement on x1, we a 50/50 probability
597
591
auto p_m = bn->at (2 )->asDiscrete ();
598
- EXPECT_DOUBLES_EQUAL (0.5 , p_m->operator ()(DiscreteValues{{m1.first , 0 }}),
599
- 1e-9 );
600
- EXPECT_DOUBLES_EQUAL (0.5 , p_m->operator ()(DiscreteValues{{m1.first , 1 }}),
601
- 1e-9 );
592
+ EXPECT_DOUBLES_EQUAL (0.5 , p_m->operator ()(DiscreteValues{{M (1 ), 0 }}), 1e-9 );
593
+ EXPECT_DOUBLES_EQUAL (0.5 , p_m->operator ()(DiscreteValues{{M (1 ), 1 }}), 1e-9 );
602
594
}
603
595
604
596
{
605
597
// Now we add a measurement z1 on x1
606
598
HybridBayesNet hbn = CreateBayesNet (hybridMotionModel, true );
607
599
608
- double z1 = 4.0 ; // favors m==1
609
- given.insert (Z (1 ), Vector1 (z1) );
600
+ const Vector1 z1 ( 4.0 ) ; // favors m==1
601
+ given.insert (Z (1 ), z1 );
610
602
611
603
HybridGaussianFactorGraph gfg = hbn.toFactorGraph (given);
612
604
613
- {
614
- VectorValues vv{{X (0 ), Vector1 (0.0 )},
615
- {X (1 ), Vector1 (1.0 )},
616
- {Z (0 ), Vector1 (z0)},
617
- {Z (1 ), Vector1 (z1)}};
618
- HybridValues hv0 (vv, DiscreteValues{{M (1 ), 0 }}),
619
- hv1 (vv, DiscreteValues{{M (1 ), 1 }});
620
- EXPECT_DOUBLES_EQUAL (gfg.error (hv0) / hbn.error (hv0),
621
- gfg.error (hv1) / hbn.error (hv1), 1e-9 );
622
- }
623
- {
624
- VectorValues vv{{X (0 ), Vector1 (0.5 )},
625
- {X (1 ), Vector1 (3.0 )},
626
- {Z (0 ), Vector1 (z0)},
627
- {Z (1 ), Vector1 (z1)}};
628
- HybridValues hv0 (vv, DiscreteValues{{M (1 ), 0 }}),
629
- hv1 (vv, DiscreteValues{{M (1 ), 1 }});
605
+ // Check that ratio of Bayes net and factor graph for different modes is
606
+ // equal for several values of {x0,x1}.
607
+ for (VectorValues vv :
608
+ {VectorValues{{X (0 ), Vector1 (0.0 )}, {X (1 ), Vector1 (1.0 )}},
609
+ VectorValues{{X (0 ), Vector1 (0.5 )}, {X (1 ), Vector1 (3.0 )}}}) {
610
+ vv.insert (given); // add measurements for HBN
611
+ HybridValues hv0 (vv, {{M (1 ), 0 }}), hv1 (vv, {{M (1 ), 1 }});
630
612
EXPECT_DOUBLES_EQUAL (gfg.error (hv0) / hbn.error (hv0),
631
613
gfg.error (hv1) / hbn.error (hv1), 1e-9 );
632
614
}
633
615
634
616
HybridBayesNet::shared_ptr bn = gfg.eliminateSequential ();
635
617
636
- // Since we have a measurement on z2 , we get a definite result
618
+ // Since we have a measurement z1 on x1 , we get a definite result
637
619
// Values taken from an importance sampling run with 50k samples:
638
620
// approximateDiscreteMarginal(hbn, proposalNet, given);
639
621
DiscreteConditional expected (m1, " 0.481793/0.518207" );
640
- EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.01 ));
622
+ EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.001 ));
641
623
}
642
624
643
625
{
644
- // Add a different measurement z1 on that favors m==0
626
+ // Add a different measurement z1 on x1 that favors m==0
645
627
HybridBayesNet hbn = CreateBayesNet (hybridMotionModel, true );
646
628
647
- double z1 = 1.1 ;
648
- given.insert_or_assign (Z (1 ), Vector1 (z1) );
629
+ const Vector1 z1 ( 1.1 ) ;
630
+ given.insert_or_assign (Z (1 ), z1 );
649
631
650
632
HybridGaussianFactorGraph gfg = hbn.toFactorGraph (given);
651
633
HybridBayesNet::shared_ptr bn = gfg.eliminateSequential ();
652
634
653
- // Since we have a measurement on z2 , we get a definite result
635
+ // Since we have a measurement z1 on x1 , we get a definite result
654
636
// Values taken from an importance sampling run with 50k samples:
655
637
// approximateDiscreteMarginal(hbn, proposalNet, given);
656
638
DiscreteConditional expected (m1, " 0.554485/0.445515" );
657
- EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.01 ));
639
+ EXPECT (assert_equal (expected, *(bn->at (2 )->asDiscrete ()), 0.001 ));
658
640
}
659
641
}
660
642
0 commit comments