diff --git a/gtsam/discrete/DiscreteConditional.cpp b/gtsam/discrete/DiscreteConditional.cpp index 3e74cebb4..3f0c9f511 100644 --- a/gtsam/discrete/DiscreteConditional.cpp +++ b/gtsam/discrete/DiscreteConditional.cpp @@ -467,7 +467,7 @@ double DiscreteConditional::evaluate(const HybridValues& x) const { } /* ************************************************************************* */ -double DiscreteConditional::errorConstant() const { +double DiscreteConditional::negLogConstant() const { return 0.0; } diff --git a/gtsam/discrete/DiscreteConditional.h b/gtsam/discrete/DiscreteConditional.h index 53331a0be..e16100d0a 100644 --- a/gtsam/discrete/DiscreteConditional.h +++ b/gtsam/discrete/DiscreteConditional.h @@ -264,12 +264,12 @@ class GTSAM_EXPORT DiscreteConditional } /** - * errorConstant is just zero, such that - * logProbability(x) = log(evaluate(x)) = - error(x) - * and hence error(x) = - log(evaluate(x)) > 0 for all x. + * negLogConstant is just zero, such that + * -logProbability(x) = -log(evaluate(x)) = error(x) + * and hence error(x) > 0 for all x. * Thus -log(K) for the normalization constant k is 0. */ - double errorConstant() const override; + double negLogConstant() const override; /// @} diff --git a/gtsam/discrete/discrete.i b/gtsam/discrete/discrete.i index 753c3527a..ab3ff75ca 100644 --- a/gtsam/discrete/discrete.i +++ b/gtsam/discrete/discrete.i @@ -112,7 +112,7 @@ virtual class DiscreteConditional : gtsam::DecisionTreeFactor { const std::vector& table); // Standard interface - double errorConstant() const; + double negLogConstant() const; double logNormalizationConstant() const; double logProbability(const gtsam::DiscreteValues& values) const; double evaluate(const gtsam::DiscreteValues& values) const; diff --git a/gtsam/hybrid/HybridConditional.cpp b/gtsam/hybrid/HybridConditional.cpp index 57d8bba39..cac2adcf8 100644 --- a/gtsam/hybrid/HybridConditional.cpp +++ b/gtsam/hybrid/HybridConditional.cpp @@ -161,18 +161,18 @@ double HybridConditional::logProbability(const HybridValues &values) const { } /* ************************************************************************ */ -double HybridConditional::errorConstant() const { +double HybridConditional::negLogConstant() const { if (auto gc = asGaussian()) { - return gc->errorConstant(); + return gc->negLogConstant(); } if (auto gm = asHybrid()) { - return gm->errorConstant(); // 0.0! + return gm->negLogConstant(); // 0.0! } if (auto dc = asDiscrete()) { - return dc->errorConstant(); // 0.0! + return dc->negLogConstant(); // 0.0! } throw std::runtime_error( - "HybridConditional::errorConstant: conditional type not handled"); + "HybridConditional::negLogConstant: conditional type not handled"); } /* ************************************************************************ */ diff --git a/gtsam/hybrid/HybridConditional.h b/gtsam/hybrid/HybridConditional.h index 92118385c..588c44e0b 100644 --- a/gtsam/hybrid/HybridConditional.h +++ b/gtsam/hybrid/HybridConditional.h @@ -194,11 +194,11 @@ class GTSAM_EXPORT HybridConditional /** * Return the negative log of the normalization constant. - * This shows up in the error as -(error(x) + errorConstant) + * This shows up in the error as -(error(x) + negLogConstant) * Note this is 0.0 for discrete and hybrid conditionals, but depends * on the continuous parameters for Gaussian conditionals. */ - double errorConstant() const override; + double negLogConstant() const override; /// Return the probability (or density) of the underlying conditional. double evaluate(const HybridValues& values) const override; diff --git a/gtsam/hybrid/HybridGaussianConditional.cpp b/gtsam/hybrid/HybridGaussianConditional.cpp index f6cd3e5f7..f1220505d 100644 --- a/gtsam/hybrid/HybridGaussianConditional.cpp +++ b/gtsam/hybrid/HybridGaussianConditional.cpp @@ -36,7 +36,7 @@ HybridGaussianFactor::FactorValuePairs GetFactorValuePairs( // Check if conditional is pruned if (conditional) { // Assign log(\sqrt(|2πΣ|)) = -log(1 / sqrt(|2πΣ|)) - value = conditional->errorConstant(); + value = conditional->negLogConstant(); } return {std::dynamic_pointer_cast(conditional), value}; }; @@ -58,7 +58,7 @@ HybridGaussianConditional::HybridGaussianConditional( [this](const GaussianConditional::shared_ptr &conditional) { if (conditional) { this->logConstant_ = - std::min(this->logConstant_, conditional->errorConstant()); + std::min(this->logConstant_, conditional->negLogConstant()); } }); } @@ -84,7 +84,7 @@ GaussianFactorGraphTree HybridGaussianConditional::asGaussianFactorGraphTree() auto wrap = [this](const GaussianConditional::shared_ptr &gc) { // First check if conditional has not been pruned if (gc) { - const double Cgm_Kgcm = gc->errorConstant() - this->logConstant_; + const double Cgm_Kgcm = gc->negLogConstant() - this->logConstant_; // If there is a difference in the covariances, we need to account for // that since the error is dependent on the mode. if (Cgm_Kgcm > 0.0) { @@ -214,7 +214,7 @@ std::shared_ptr HybridGaussianConditional::likelihood( [&](const GaussianConditional::shared_ptr &conditional) -> GaussianFactorValuePair { const auto likelihood_m = conditional->likelihood(given); - const double Cgm_Kgcm = conditional->errorConstant() - logConstant_; + const double Cgm_Kgcm = conditional->negLogConstant() - logConstant_; if (Cgm_Kgcm == 0.0) { return {likelihood_m, 0.0}; } else { diff --git a/gtsam/hybrid/HybridGaussianConditional.h b/gtsam/hybrid/HybridGaussianConditional.h index 8851c7741..8566d47ef 100644 --- a/gtsam/hybrid/HybridGaussianConditional.h +++ b/gtsam/hybrid/HybridGaussianConditional.h @@ -158,7 +158,7 @@ class GTSAM_EXPORT HybridGaussianConditional * * @return double */ - inline double errorConstant() const override { return logConstant_; } + inline double negLogConstant() const override { return logConstant_; } /** * Create a likelihood factor for a hybrid Gaussian conditional, diff --git a/gtsam/hybrid/HybridGaussianFactorGraph.cpp b/gtsam/hybrid/HybridGaussianFactorGraph.cpp index a6c15d1fd..603b29fb5 100644 --- a/gtsam/hybrid/HybridGaussianFactorGraph.cpp +++ b/gtsam/hybrid/HybridGaussianFactorGraph.cpp @@ -329,9 +329,9 @@ static std::shared_ptr createDiscreteFactor( // Logspace version of: // exp(-factor->error(kEmpty)) / conditional->normalizationConstant(); - // errorConstant gives `-log(k)` + // negLogConstant gives `-log(k)` // which is `-log(k) = log(1/k) = log(\sqrt{|2πΣ|})`. - return -factor->error(kEmpty) + conditional->errorConstant(); + return -factor->error(kEmpty) + conditional->negLogConstant(); }; AlgebraicDecisionTree logProbabilities( @@ -357,7 +357,7 @@ static std::shared_ptr createHybridGaussianFactor( // Add 2.0 term since the constant term will be premultiplied by 0.5 // as per the Hessian definition, // and negative since we want log(k) - hf->constantTerm() += -2.0 * conditional->errorConstant(); + hf->constantTerm() += -2.0 * conditional->negLogConstant(); } return {factor, 0.0}; }; diff --git a/gtsam/hybrid/hybrid.i b/gtsam/hybrid/hybrid.i index 81cca3c46..cdeb35046 100644 --- a/gtsam/hybrid/hybrid.i +++ b/gtsam/hybrid/hybrid.i @@ -61,7 +61,7 @@ virtual class HybridConditional { size_t nrParents() const; // Standard interface: - double errorConstant() const; + double negLogConstant() const; double logNormalizationConstant() const; double logProbability(const gtsam::HybridValues& values) const; double evaluate(const gtsam::HybridValues& values) const; diff --git a/gtsam/hybrid/tests/testHybridGaussianConditional.cpp b/gtsam/hybrid/tests/testHybridGaussianConditional.cpp index 6c1037e1d..74f57a740 100644 --- a/gtsam/hybrid/tests/testHybridGaussianConditional.cpp +++ b/gtsam/hybrid/tests/testHybridGaussianConditional.cpp @@ -180,16 +180,16 @@ TEST(HybridGaussianConditional, Error2) { // Check result. DiscreteKeys discrete_keys{mode}; - double errorConstant0 = conditionals[0]->errorConstant(); - double errorConstant1 = conditionals[1]->errorConstant(); - double minErrorConstant = std::min(errorConstant0, errorConstant1); + double negLogConstant0 = conditionals[0]->negLogConstant(); + double negLogConstant1 = conditionals[1]->negLogConstant(); + double minErrorConstant = std::min(negLogConstant0, negLogConstant1); // Expected error is e(X) + log(sqrt(|2πΣ|)). - // We normalize log(sqrt(|2πΣ|)) with min(errorConstant) + // We normalize log(sqrt(|2πΣ|)) with min(negLogConstant) // so it is non-negative. std::vector leaves = { - conditionals[0]->error(vv) + errorConstant0 - minErrorConstant, - conditionals[1]->error(vv) + errorConstant1 - minErrorConstant}; + conditionals[0]->error(vv) + negLogConstant0 - minErrorConstant, + conditionals[1]->error(vv) + negLogConstant1 - minErrorConstant}; AlgebraicDecisionTree expected(discrete_keys, leaves); EXPECT(assert_equal(expected, actual, 1e-6)); @@ -198,7 +198,7 @@ TEST(HybridGaussianConditional, Error2) { for (size_t mode : {0, 1}) { const HybridValues hv{vv, {{M(0), mode}}}; EXPECT_DOUBLES_EQUAL(conditionals[mode]->error(vv) + - conditionals[mode]->errorConstant() - + conditionals[mode]->negLogConstant() - minErrorConstant, hybrid_conditional.error(hv), 1e-8); } diff --git a/gtsam/hybrid/tests/testHybridGaussianFactor.cpp b/gtsam/hybrid/tests/testHybridGaussianFactor.cpp index d84948c75..4b664b8b4 100644 --- a/gtsam/hybrid/tests/testHybridGaussianFactor.cpp +++ b/gtsam/hybrid/tests/testHybridGaussianFactor.cpp @@ -780,8 +780,8 @@ static HybridGaussianFactorGraph CreateFactorGraph( // Create HybridGaussianFactor // We take negative since we want // the underlying scalar to be log(\sqrt(|2πΣ|)) - std::vector factors{{f0, model0->errorConstant()}, - {f1, model1->errorConstant()}}; + std::vector factors{{f0, model0->negLogConstant()}, + {f1, model1->negLogConstant()}}; HybridGaussianFactor motionFactor({X(0), X(1)}, m1, factors); HybridGaussianFactorGraph hfg; diff --git a/gtsam/hybrid/tests/testHybridNonlinearFactorGraph.cpp b/gtsam/hybrid/tests/testHybridNonlinearFactorGraph.cpp index 5f1108ace..495444c79 100644 --- a/gtsam/hybrid/tests/testHybridNonlinearFactorGraph.cpp +++ b/gtsam/hybrid/tests/testHybridNonlinearFactorGraph.cpp @@ -902,8 +902,8 @@ static HybridNonlinearFactorGraph CreateFactorGraph( // Create HybridNonlinearFactor // We take negative since we want // the underlying scalar to be log(\sqrt(|2πΣ|)) - std::vector factors{{f0, model0->errorConstant()}, - {f1, model1->errorConstant()}}; + std::vector factors{{f0, model0->negLogConstant()}, + {f1, model1->negLogConstant()}}; HybridNonlinearFactor mixtureFactor({X(0), X(1)}, m1, factors); diff --git a/gtsam/inference/Conditional-inst.h b/gtsam/inference/Conditional-inst.h index ba42a9a24..32fae188b 100644 --- a/gtsam/inference/Conditional-inst.h +++ b/gtsam/inference/Conditional-inst.h @@ -59,17 +59,17 @@ double Conditional::evaluate( /* ************************************************************************* */ template -double Conditional::errorConstant() +double Conditional::negLogConstant() const { throw std::runtime_error( - "Conditional::errorConstant is not implemented"); + "Conditional::negLogConstant is not implemented"); } /* ************************************************************************* */ template double Conditional::logNormalizationConstant() const { - return -errorConstant(); + return -negLogConstant(); } /* ************************************************************************* */ @@ -96,7 +96,7 @@ bool Conditional::CheckInvariants( // normalization constant const double error = conditional.error(values); if (error < 0.0) return false; // prob_or_density is negative. - const double expected = -(conditional.errorConstant() + error); + const double expected = -(conditional.negLogConstant() + error); if (std::abs(logProb - expected) > 1e-9) return false; // logProb is not consistent with error return true; diff --git a/gtsam/inference/Conditional.h b/gtsam/inference/Conditional.h index d09341489..c44ed239e 100644 --- a/gtsam/inference/Conditional.h +++ b/gtsam/inference/Conditional.h @@ -169,7 +169,7 @@ namespace gtsam { * * @return double */ - virtual double errorConstant() const; + virtual double negLogConstant() const; /** * All conditional types need to implement a log normalization constant to diff --git a/gtsam/linear/GaussianConditional.cpp b/gtsam/linear/GaussianConditional.cpp index ca4a1ed33..7508524c3 100644 --- a/gtsam/linear/GaussianConditional.cpp +++ b/gtsam/linear/GaussianConditional.cpp @@ -182,7 +182,7 @@ namespace gtsam { /* ************************************************************************* */ // normalization constant = 1.0 / sqrt((2*pi)^n*det(Sigma)) // neg-log = 0.5 * n*log(2*pi) + 0.5 * log det(Sigma) - double GaussianConditional::errorConstant() const { + double GaussianConditional::negLogConstant() const { constexpr double log2pi = 1.8378770664093454835606594728112; size_t n = d().size(); // Sigma = (R'R)^{-1}, det(Sigma) = det((R'R)^{-1}) = det(R'R)^{-1} diff --git a/gtsam/linear/GaussianConditional.h b/gtsam/linear/GaussianConditional.h index 31f3797d5..27270fece 100644 --- a/gtsam/linear/GaussianConditional.h +++ b/gtsam/linear/GaussianConditional.h @@ -140,7 +140,7 @@ namespace gtsam { * * @return double */ - double errorConstant() const override; + double negLogConstant() const override; /** * Calculate log-probability log(evaluate(x)) for given values `x`: diff --git a/gtsam/linear/NoiseModel.cpp b/gtsam/linear/NoiseModel.cpp index 39901584b..68c2ffda7 100644 --- a/gtsam/linear/NoiseModel.cpp +++ b/gtsam/linear/NoiseModel.cpp @@ -255,7 +255,7 @@ double Gaussian::logDeterminant() const { } /* *******************************************************************************/ -double Gaussian::errorConstant() const { +double Gaussian::negLogConstant() const { // log(det(Sigma)) = -2.0 * logDetR // which gives neg-log = 0.5*n*log(2*pi) + 0.5*(-2.0 * logDetR()) // = 0.5*n*log(2*pi) - (0.5*2.0 * logDetR()) @@ -268,7 +268,7 @@ double Gaussian::errorConstant() const { /* *******************************************************************************/ double Gaussian::logNormalizationConstant() const { - return -errorConstant(); + return -negLogConstant(); } /* ************************************************************************* */ diff --git a/gtsam/linear/NoiseModel.h b/gtsam/linear/NoiseModel.h index 851dc3c1f..5ad48cade 100644 --- a/gtsam/linear/NoiseModel.h +++ b/gtsam/linear/NoiseModel.h @@ -277,7 +277,7 @@ namespace gtsam { * * @return double */ - double errorConstant() const; + double negLogConstant() const; /** * @brief Method to compute the normalization constant diff --git a/gtsam/linear/linear.i b/gtsam/linear/linear.i index 71eb94dd5..23b6fb3f6 100644 --- a/gtsam/linear/linear.i +++ b/gtsam/linear/linear.i @@ -548,7 +548,7 @@ virtual class GaussianConditional : gtsam::JacobianFactor { bool equals(const gtsam::GaussianConditional& cg, double tol) const; // Standard Interface - double errorConstant() const; + double negLogConstant() const; double logNormalizationConstant() const; double logProbability(const gtsam::VectorValues& x) const; double evaluate(const gtsam::VectorValues& x) const; diff --git a/gtsam/linear/tests/testGaussianDensity.cpp b/gtsam/linear/tests/testGaussianDensity.cpp index e88fd8cc4..b2861e833 100644 --- a/gtsam/linear/tests/testGaussianDensity.cpp +++ b/gtsam/linear/tests/testGaussianDensity.cpp @@ -55,7 +55,7 @@ TEST(GaussianDensity, FromMeanAndStddev) { double expected1 = 0.5 * e.dot(e); EXPECT_DOUBLES_EQUAL(expected1, density.error(values), 1e-9); - double expected2 = -(density.errorConstant() + 0.5 * e.dot(e)); + double expected2 = -(density.negLogConstant() + 0.5 * e.dot(e)); EXPECT_DOUBLES_EQUAL(expected2, density.logProbability(values), 1e-9); } diff --git a/python/gtsam/tests/test_HybridBayesNet.py b/python/gtsam/tests/test_HybridBayesNet.py index a72e34062..bf2b6a033 100644 --- a/python/gtsam/tests/test_HybridBayesNet.py +++ b/python/gtsam/tests/test_HybridBayesNet.py @@ -90,7 +90,7 @@ class TestHybridBayesNet(GtsamTestCase): self.assertTrue(probability >= 0.0) logProb = conditional.logProbability(values) self.assertAlmostEqual(probability, np.exp(logProb)) - expected = -(conditional.errorConstant() + conditional.error(values)) + expected = -(conditional.negLogConstant() + conditional.error(values)) self.assertAlmostEqual(logProb, expected)