improvements to GaussianConditional and GaussianBayesNet

release/4.3a0
Varun Agrawal 2024-08-20 15:57:36 -04:00
parent cea84b8c89
commit 7269d80b1c
6 changed files with 55 additions and 2 deletions

View File

@ -243,5 +243,25 @@ namespace gtsam {
} }
/* ************************************************************************* */ /* ************************************************************************* */
double GaussianBayesNet::logNormalizationConstant() const {
/*
normalization constant = 1.0 / sqrt((2*pi)^n*det(Sigma))
logConstant = -0.5 * n*log(2*pi) - 0.5 * log det(Sigma)
log det(Sigma)) = -2.0 * logDeterminant()
thus, logConstant = -0.5*n*log(2*pi) + logDeterminant()
BayesNet logConstant = sum(-0.5*n_i*log(2*pi) + logDeterminant_i())
= sum(-0.5*n_i*log(2*pi)) + sum(logDeterminant_i())
= sum(-0.5*n_i*log(2*pi)) + bn->logDeterminant()
*/
double logNormConst = 0.0;
for (const sharedConditional& cg : *this) {
logNormConst += cg->logNormalizationConstant();
}
return logNormConst;
}
/* ************************************************************************* */
} // namespace gtsam } // namespace gtsam

View File

@ -82,6 +82,12 @@ namespace gtsam {
/** Check equality */ /** Check equality */
bool equals(const This& bn, double tol = 1e-9) const; bool equals(const This& bn, double tol = 1e-9) const;
/// Check exact equality.
friend bool operator==(const GaussianBayesNet& lhs,
const GaussianBayesNet& rhs) {
return lhs.isEqual(rhs);
}
/// print graph /// print graph
void print( void print(
const std::string& s = "", const std::string& s = "",
@ -228,6 +234,14 @@ namespace gtsam {
* @return The determinant */ * @return The determinant */
double logDeterminant() const; double logDeterminant() const;
/**
* @brief Get the log of the normalization constant corresponding to the
* joint Gaussian density represented by this Bayes net.
*
* @return double
*/
double logNormalizationConstant() const;
/** /**
* Backsubstitute with a different RHS vector than the one stored in this BayesNet. * Backsubstitute with a different RHS vector than the one stored in this BayesNet.
* gy=inv(R*inv(Sigma))*gx * gy=inv(R*inv(Sigma))*gx

View File

@ -121,6 +121,7 @@ namespace gtsam {
const auto mean = solve({}); // solve for mean. const auto mean = solve({}); // solve for mean.
mean.print(" mean", formatter); mean.print(" mean", formatter);
} }
cout << " logNormalizationConstant: " << logNormalizationConstant() << std::endl;
if (model_) if (model_)
model_->print(" Noise model: "); model_->print(" Noise model: ");
else else
@ -184,7 +185,12 @@ namespace gtsam {
double GaussianConditional::logNormalizationConstant() const { double GaussianConditional::logNormalizationConstant() const {
constexpr double log2pi = 1.8378770664093454835606594728112; constexpr double log2pi = 1.8378770664093454835606594728112;
size_t n = d().size(); size_t n = d().size();
// log det(Sigma)) = - 2.0 * logDeterminant() // Sigma = (R'R)^{-1}, det(Sigma) = det((R'R)^{-1}) = det(R'R)^{-1}
// log det(Sigma) = -log(det(R'R)) = -2*log(det(R))
// Hence, log det(Sigma)) = -2.0 * logDeterminant()
// which gives log = -0.5*n*log(2*pi) - 0.5*(-2.0 * logDeterminant())
// = -0.5*n*log(2*pi) + (0.5*2.0 * logDeterminant())
// = -0.5*n*log(2*pi) + logDeterminant()
return -0.5 * n * log2pi + logDeterminant(); return -0.5 * n * log2pi + logDeterminant();
} }

View File

@ -263,6 +263,11 @@ namespace gtsam {
/** equals required by Testable for unit testing */ /** equals required by Testable for unit testing */
bool equals(const VectorValues& x, double tol = 1e-9) const; bool equals(const VectorValues& x, double tol = 1e-9) const;
/// Check exact equality.
friend bool operator==(const VectorValues& lhs, const VectorValues& rhs) {
return lhs.equals(rhs);
}
/// @{ /// @{
/// @name Advanced Interface /// @name Advanced Interface
/// @{ /// @{

View File

@ -510,12 +510,17 @@ virtual class GaussianConditional : gtsam::JacobianFactor {
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S, GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S,
size_t name2, gtsam::Matrix T, size_t name2, gtsam::Matrix T,
const gtsam::noiseModel::Diagonal* sigmas); const gtsam::noiseModel::Diagonal* sigmas);
GaussianConditional(const vector<std::pair<gtsam::Key, gtsam::Matrix>> terms,
size_t nrFrontals, gtsam::Vector d,
const gtsam::noiseModel::Diagonal* sigmas);
// Constructors with no noise model // Constructors with no noise model
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R); GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R);
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S); GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S);
GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S, GaussianConditional(size_t key, gtsam::Vector d, gtsam::Matrix R, size_t name1, gtsam::Matrix S,
size_t name2, gtsam::Matrix T); size_t name2, gtsam::Matrix T);
GaussianConditional(const gtsam::KeyVector& keys, size_t nrFrontals,
const gtsam::VerticalBlockMatrix& augmentedMatrix);
// Named constructors // Named constructors
static gtsam::GaussianConditional FromMeanAndStddev(gtsam::Key key, static gtsam::GaussianConditional FromMeanAndStddev(gtsam::Key key,

View File

@ -516,6 +516,7 @@ TEST(GaussianConditional, Print) {
" d = [ 20 40 ]\n" " d = [ 20 40 ]\n"
" mean: 1 elements\n" " mean: 1 elements\n"
" x0: 20 40\n" " x0: 20 40\n"
" logNormalizationConstant: -4.0351\n"
"isotropic dim=2 sigma=3\n"; "isotropic dim=2 sigma=3\n";
EXPECT(assert_print_equal(expected, conditional, "GaussianConditional")); EXPECT(assert_print_equal(expected, conditional, "GaussianConditional"));
@ -530,6 +531,7 @@ TEST(GaussianConditional, Print) {
" S[x1] = [ -1 -2 ]\n" " S[x1] = [ -1 -2 ]\n"
" [ -3 -4 ]\n" " [ -3 -4 ]\n"
" d = [ 20 40 ]\n" " d = [ 20 40 ]\n"
" logNormalizationConstant: -4.0351\n"
"isotropic dim=2 sigma=3\n"; "isotropic dim=2 sigma=3\n";
EXPECT(assert_print_equal(expected1, conditional1, "GaussianConditional")); EXPECT(assert_print_equal(expected1, conditional1, "GaussianConditional"));
@ -545,6 +547,7 @@ TEST(GaussianConditional, Print) {
" S[y1] = [ -5 -6 ]\n" " S[y1] = [ -5 -6 ]\n"
" [ -7 -8 ]\n" " [ -7 -8 ]\n"
" d = [ 20 40 ]\n" " d = [ 20 40 ]\n"
" logNormalizationConstant: -4.0351\n"
"isotropic dim=2 sigma=3\n"; "isotropic dim=2 sigma=3\n";
EXPECT(assert_print_equal(expected2, conditional2, "GaussianConditional")); EXPECT(assert_print_equal(expected2, conditional2, "GaussianConditional"));
} }