Skip to content

Commit 5471192

Browse files
authored
Merge pull request #1801 from borglab/gaussian-bayes-net-improvements
2 parents 231d1ad + 910300b commit 5471192

8 files changed

+67
-2
lines changed

gtsam/hybrid/tests/testHybridNonlinearFactorGraph.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -680,12 +680,14 @@ conditional 0: Hybrid P( x0 | x1 m0)
680680
R = [ 10.0499 ]
681681
S[x1] = [ -0.0995037 ]
682682
d = [ -9.85087 ]
683+
logNormalizationConstant: 1.38862
683684
No noise model
684685
685686
1 Leaf p(x0 | x1)
686687
R = [ 10.0499 ]
687688
S[x1] = [ -0.0995037 ]
688689
d = [ -9.95037 ]
690+
logNormalizationConstant: 1.38862
689691
No noise model
690692
691693
conditional 1: Hybrid P( x1 | x2 m0 m1)
@@ -696,25 +698,29 @@ conditional 1: Hybrid P( x1 | x2 m0 m1)
696698
R = [ 10.099 ]
697699
S[x2] = [ -0.0990196 ]
698700
d = [ -9.99901 ]
701+
logNormalizationConstant: 1.3935
699702
No noise model
700703
701704
0 1 Leaf p(x1 | x2)
702705
R = [ 10.099 ]
703706
S[x2] = [ -0.0990196 ]
704707
d = [ -9.90098 ]
708+
logNormalizationConstant: 1.3935
705709
No noise model
706710
707711
1 Choice(m0)
708712
1 0 Leaf p(x1 | x2)
709713
R = [ 10.099 ]
710714
S[x2] = [ -0.0990196 ]
711715
d = [ -10.098 ]
716+
logNormalizationConstant: 1.3935
712717
No noise model
713718
714719
1 1 Leaf p(x1 | x2)
715720
R = [ 10.099 ]
716721
S[x2] = [ -0.0990196 ]
717722
d = [ -10 ]
723+
logNormalizationConstant: 1.3935
718724
No noise model
719725
720726
conditional 2: Hybrid P( x2 | m0 m1)
@@ -726,13 +732,15 @@ conditional 2: Hybrid P( x2 | m0 m1)
726732
d = [ -10.1489 ]
727733
mean: 1 elements
728734
x2: -1.0099
735+
logNormalizationConstant: 1.38857
729736
No noise model
730737
731738
0 1 Leaf p(x2)
732739
R = [ 10.0494 ]
733740
d = [ -10.1479 ]
734741
mean: 1 elements
735742
x2: -1.0098
743+
logNormalizationConstant: 1.38857
736744
No noise model
737745
738746
1 Choice(m0)
@@ -741,13 +749,15 @@ conditional 2: Hybrid P( x2 | m0 m1)
741749
d = [ -10.0504 ]
742750
mean: 1 elements
743751
x2: -1.0001
752+
logNormalizationConstant: 1.38857
744753
No noise model
745754
746755
1 1 Leaf p(x2)
747756
R = [ 10.0494 ]
748757
d = [ -10.0494 ]
749758
mean: 1 elements
750759
x2: -1
760+
logNormalizationConstant: 1.38857
751761
No noise model
752762
753763
)";

gtsam/linear/GaussianBayesNet.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -243,5 +243,25 @@ namespace gtsam {
243243
}
244244

245245
/* ************************************************************************* */
246+
double GaussianBayesNet::logNormalizationConstant() const {
247+
/*
248+
normalization constant = 1.0 / sqrt((2*pi)^n*det(Sigma))
249+
logConstant = -0.5 * n*log(2*pi) - 0.5 * log det(Sigma)
250+
251+
log det(Sigma)) = -2.0 * logDeterminant()
252+
thus, logConstant = -0.5*n*log(2*pi) + logDeterminant()
253+
254+
BayesNet logConstant = sum(-0.5*n_i*log(2*pi) + logDeterminant_i())
255+
= sum(-0.5*n_i*log(2*pi)) + sum(logDeterminant_i())
256+
= sum(-0.5*n_i*log(2*pi)) + bn->logDeterminant()
257+
*/
258+
double logNormConst = 0.0;
259+
for (const sharedConditional& cg : *this) {
260+
logNormConst += cg->logNormalizationConstant();
261+
}
262+
return logNormConst;
263+
}
264+
265+
/* ************************************************************************* */
246266

247267
} // namespace gtsam

gtsam/linear/GaussianBayesNet.h

+14
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ namespace gtsam {
8282
/** Check equality */
8383
bool equals(const This& bn, double tol = 1e-9) const;
8484

85+
/// Check exact equality.
86+
friend bool operator==(const GaussianBayesNet& lhs,
87+
const GaussianBayesNet& rhs) {
88+
return lhs.isEqual(rhs);
89+
}
90+
8591
/// print graph
8692
void print(
8793
const std::string& s = "",
@@ -228,6 +234,14 @@ namespace gtsam {
228234
* @return The determinant */
229235
double logDeterminant() const;
230236

237+
/**
238+
* @brief Get the log of the normalization constant corresponding to the
239+
* joint Gaussian density represented by this Bayes net.
240+
*
241+
* @return double
242+
*/
243+
double logNormalizationConstant() const;
244+
231245
/**
232246
* Backsubstitute with a different RHS vector than the one stored in this BayesNet.
233247
* gy=inv(R*inv(Sigma))*gx

gtsam/linear/GaussianConditional.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ namespace gtsam {
121121
const auto mean = solve({}); // solve for mean.
122122
mean.print(" mean", formatter);
123123
}
124+
cout << " logNormalizationConstant: " << logNormalizationConstant() << std::endl;
124125
if (model_)
125126
model_->print(" Noise model: ");
126127
else
@@ -184,8 +185,13 @@ namespace gtsam {
184185
double GaussianConditional::logNormalizationConstant() const {
185186
constexpr double log2pi = 1.8378770664093454835606594728112;
186187
size_t n = d().size();
187-
// log det(Sigma)) = - 2.0 * logDeterminant()
188-
return - 0.5 * n * log2pi + logDeterminant();
188+
// Sigma = (R'R)^{-1}, det(Sigma) = det((R'R)^{-1}) = det(R'R)^{-1}
189+
// log det(Sigma) = -log(det(R'R)) = -2*log(det(R))
190+
// Hence, log det(Sigma)) = -2.0 * logDeterminant()
191+
// which gives log = -0.5*n*log(2*pi) - 0.5*(-2.0 * logDeterminant())
192+
// = -0.5*n*log(2*pi) + (0.5*2.0 * logDeterminant())
193+
// = -0.5*n*log(2*pi) + logDeterminant()
194+
return -0.5 * n * log2pi + logDeterminant();
189195
}
190196

191197
/* ************************************************************************* */

gtsam/linear/VectorValues.h

+5
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,11 @@ namespace gtsam {
263263
/** equals required by Testable for unit testing */
264264
bool equals(const VectorValues& x, double tol = 1e-9) const;
265265

266+
/// Check equality.
267+
friend bool operator==(const VectorValues& lhs, const VectorValues& rhs) {
268+
return lhs.equals(rhs);
269+
}
270+
266271
/// @{
267272
/// @name Advanced Interface
268273
/// @{

gtsam/linear/linear.i

+5
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,17 @@ virtual class GaussianConditional : gtsam::JacobianFactor {
510510
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S,
511511
size_t name2, gtsam::Matrix T,
512512
const gtsam::noiseModel::Diagonal* sigmas);
513+
GaussianConditional(const vector<std::pair<gtsam::Key, gtsam::Matrix>> terms,
514+
size_t nrFrontals, gtsam::Vector d,
515+
const gtsam::noiseModel::Diagonal* sigmas);
513516

514517
// Constructors with no noise model
515518
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R);
516519
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S);
517520
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S,
518521
size_t name2, gtsam::Matrix T);
522+
GaussianConditional(const gtsam::KeyVector& keys, size_t nrFrontals,
523+
const gtsam::VerticalBlockMatrix& augmentedMatrix);
519524

520525
// Named constructors
521526
static gtsam::GaussianConditional FromMeanAndStddev(gtsam::Key key,

gtsam/linear/tests/testGaussianBayesNet.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ TEST(GaussianBayesNet, Evaluate1) {
8080
smallBayesNet.at(0)->logNormalizationConstant() +
8181
smallBayesNet.at(1)->logNormalizationConstant(),
8282
1e-9);
83+
EXPECT_DOUBLES_EQUAL(log(constant), smallBayesNet.logNormalizationConstant(),
84+
1e-9);
8385
const double actual = smallBayesNet.evaluate(mean);
8486
EXPECT_DOUBLES_EQUAL(constant, actual, 1e-9);
8587
}

gtsam/linear/tests/testGaussianConditional.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ TEST(GaussianConditional, Print) {
516516
" d = [ 20 40 ]\n"
517517
" mean: 1 elements\n"
518518
" x0: 20 40\n"
519+
" logNormalizationConstant: -4.0351\n"
519520
"isotropic dim=2 sigma=3\n";
520521
EXPECT(assert_print_equal(expected, conditional, "GaussianConditional"));
521522

@@ -530,6 +531,7 @@ TEST(GaussianConditional, Print) {
530531
" S[x1] = [ -1 -2 ]\n"
531532
" [ -3 -4 ]\n"
532533
" d = [ 20 40 ]\n"
534+
" logNormalizationConstant: -4.0351\n"
533535
"isotropic dim=2 sigma=3\n";
534536
EXPECT(assert_print_equal(expected1, conditional1, "GaussianConditional"));
535537

@@ -545,6 +547,7 @@ TEST(GaussianConditional, Print) {
545547
" S[y1] = [ -5 -6 ]\n"
546548
" [ -7 -8 ]\n"
547549
" d = [ 20 40 ]\n"
550+
" logNormalizationConstant: -4.0351\n"
548551
"isotropic dim=2 sigma=3\n";
549552
EXPECT(assert_print_equal(expected2, conditional2, "GaussianConditional"));
550553
}

0 commit comments

Comments
 (0)