diff --git a/gtsam/linear/NoiseModel.cpp b/gtsam/linear/NoiseModel.cpp index 3b9c5d79c..2031a4b73 100644 --- a/gtsam/linear/NoiseModel.cpp +++ b/gtsam/linear/NoiseModel.cpp @@ -16,20 +16,19 @@ * @author Frank Dellaert */ -#include -#include -#include -#include +#include +#include #include #include #include #include -#include -#include +#include +#include +#include +#include -static double inf = std::numeric_limits::infinity(); using namespace std; namespace gtsam { @@ -290,42 +289,42 @@ void Diagonal::WhitenInPlace(Eigen::Block H) const { // Constrained /* ************************************************************************* */ +namespace internal { +// switch precisions and invsigmas to finite value +// TODO: why?? And, why not just ask s==0.0 below ? +static void fix(const Vector& sigmas, Vector& precisions, Vector& invsigmas) { + for (size_t i = 0; i < sigmas.size(); ++i) + if (!std::isfinite(1. / sigmas[i])) { + precisions[i] = 0.0; + invsigmas[i] = 0.0; + } +} +} + /* ************************************************************************* */ Constrained::Constrained(const Vector& sigmas) : Diagonal(sigmas), mu_(repeat(sigmas.size(), 1000.0)) { - for (int i=0; i H) const { - // selective scaling - // Scale row i of H by sigmas[i], basically multiplying H with diag(sigmas) - // Set inf_mask flag is true so that if invsigmas[i] is inf, i.e. sigmas[i] = 0, - // indicating a hard constraint, we leave H's row i in place. - const Vector& _invsigmas = invsigmas(); - for(DenseIndex row = 0; row < _invsigmas.size(); ++row) - if(isfinite(_invsigmas(row))) - H.row(row) *= _invsigmas(row); + for (DenseIndex i=0; i<(DenseIndex)dim_; ++i) + if (!constrained(i)) // if constrained, leave row of H as is + H.row(i) *= invsigmas_(i); } /* ************************************************************************* */ Constrained::shared_ptr Constrained::unit() const { Vector sigmas = ones(dim()); for (size_t i=0; isigmas_(i) == 0.0) + if (constrained(i)) sigmas(i) = 0.0; return MixedSigmas(mu_, sigmas); } @@ -472,7 +457,7 @@ SharedDiagonal Constrained::QR(Matrix& Ab) const { const size_t& j = t.get<0>(); const Vector& rd = t.get<1>(); precisions(i) = t.get<2>(); - if (precisions(i)==inf) mixed = true; + if (constrained(i)) mixed = true; for (size_t j2=0; j2 -#include - #include #include #include +#include +#include + namespace gtsam { /** @@ -216,16 +216,22 @@ protected: X value_; /// fixed value for variable GTSAM_CONCEPT_MANIFOLD_TYPE(X) - ;GTSAM_CONCEPT_TESTABLE_TYPE(X) - ; + + GTSAM_CONCEPT_TESTABLE_TYPE(X) public: typedef boost::shared_ptr > shared_ptr; - ///TODO: comment - NonlinearEquality1(const X& value, Key key1, double mu = 1000.0) : - Base(noiseModel::Constrained::All(value.dim(), fabs(mu)), key1), value_( + /** + * Constructor + * @param value feasible value that values(key) shouild be equal to + * @param key the key for the unknown variable to be constrained + * @param mu a parameter which really turns this into a strong prior + * + */ + NonlinearEquality1(const X& value, Key key, double mu = 1000.0) : + Base(noiseModel::Constrained::All(value.dim(), fabs(mu)), key), value_( value) { } @@ -285,7 +291,6 @@ protected: typedef NonlinearEquality2 This; GTSAM_CONCEPT_MANIFOLD_TYPE(X) - ; /** default constructor to allow for serialization */ NonlinearEquality2() { diff --git a/gtsam/nonlinear/NonlinearFactor.cpp b/gtsam/nonlinear/NonlinearFactor.cpp index e9b97d644..7c8337fc8 100644 --- a/gtsam/nonlinear/NonlinearFactor.cpp +++ b/gtsam/nonlinear/NonlinearFactor.cpp @@ -132,10 +132,11 @@ boost::shared_ptr NoiseModelFactor::linearize( } // TODO pass unwhitened + noise model to Gaussian factor - if (noiseModel_ && noiseModel_->is_constrained()) + using noiseModel::Constrained; + if (noiseModel_ && noiseModel_->isConstrained()) return GaussianFactor::shared_ptr( new JacobianFactor(terms, b, - boost::static_pointer_cast(noiseModel_)->unit())); + boost::static_pointer_cast(noiseModel_)->unit())); else return GaussianFactor::shared_ptr(new JacobianFactor(terms, b)); } diff --git a/gtsam_unstable/nonlinear/ExpressionFactor.h b/gtsam_unstable/nonlinear/ExpressionFactor.h index 181ac49b4..f763915e0 100644 --- a/gtsam_unstable/nonlinear/ExpressionFactor.h +++ b/gtsam_unstable/nonlinear/ExpressionFactor.h @@ -90,7 +90,7 @@ public: // Create a writeable JacobianFactor in advance // In case noise model is constrained, we need to provide a noise model - bool constrained = noiseModel_->is_constrained(); + bool constrained = noiseModel_->isConstrained(); boost::shared_ptr factor( constrained ? new JacobianFactor(keys_, dims_, Dim, boost::static_pointer_cast(noiseModel_)->unit()) : @@ -107,7 +107,6 @@ public: T value = expression_.value(x, jacobianMap); // <<< Reverse AD happens here ! // Evaluate error and set RHS vector b - // TODO(PTF) Is this a place for custom charts? DefaultChart chart; Ab(size()).col(0) = -chart.local(measurement_, value);