/* * @file NonlinearConstraint-inl.h * @brief Implementation for NonlinearConstraints * @author Alex Cunningham */ #pragma once #include #include #include "NonlinearConstraint.h" #define INSTANTIATE_NONLINEAR_CONSTRAINT(C) \ INSTANTIATE_FACTOR_GRAPH(NonlinearConstraint); \ template class NonlinearConstraint; namespace gtsam { /* ************************************************************************* */ // Implementations of base class /* ************************************************************************* */ /* ************************************************************************* */ template NonlinearConstraint::NonlinearConstraint(size_t dim, double mu) : NonlinearFactor(noiseModel::Constrained::All(dim)), mu_(fabs(mu)) { } /* ************************************************************************* */ template double NonlinearConstraint::error(const Config& c) const { const Vector error_vector = unwhitenedError(c); return mu_ * inner_prod(error_vector, error_vector); } /* ************************************************************************* */ // Implementations of unary nonlinear constraints /* ************************************************************************* */ template NonlinearConstraint1::NonlinearConstraint1( Vector (*g)(const Config& config), const Key& key, Matrix (*gradG)(const Config& config), size_t dim, double mu) : NonlinearConstraint(dim, mu), G_(boost::bind(gradG, _1)), g_(boost::bind(g, _1)), key_(key) { this->keys_.push_back(key); } /* ************************************************************************* */ template NonlinearConstraint1::NonlinearConstraint1( boost::function g, const Key& key, boost::function gradG, size_t dim, double mu) : NonlinearConstraint(dim, mu), G_(gradG), g_(g), key_(key) { this->keys_.push_back(key); } /* ************************************************************************* */ template void NonlinearConstraint1::print(const std::string& s) const { std::cout << "NonlinearConstraint1 [" << s << "]: Dim: " << this->dim() << " mu: " << this->mu_ << "\n" << " Key : " << (std::string) this->key_ << "\n"; } /* ************************************************************************* */ template bool NonlinearConstraint1::equals(const Factor& f, double tol) const { const NonlinearConstraint1* p = dynamic_cast*> (&f); if (p == NULL) return false; if (!(key_ == p->key_)) return false; if (fabs(this->mu_ - p->mu_ ) > tol) return false; return this->dim() == p->dim(); } /* ************************************************************************* */ template GaussianFactor::shared_ptr NonlinearConstraint1::linearize(const Config& config) const { Vector g = -1.0 * g_(config); Matrix grad = G_(config); SharedDiagonal model = noiseModel::Constrained::All(this->dim()); GaussianFactor::shared_ptr factor(new GaussianFactor(this->key_, grad, g, model)); return factor; } /* ************************************************************************* */ // Implementations of binary nonlinear constraints /* ************************************************************************* */ /* ************************************************************************* */ template NonlinearConstraint2::NonlinearConstraint2( Vector (*g)(const Config& config), const Key1& key1, Matrix (*G1)(const Config& config), const Key2& key2, Matrix (*G2)(const Config& config), size_t dim, double mu) : NonlinearConstraint(dim, mu), G1_(boost::bind(G1, _1)), G2_(boost::bind(G2, _1)), g_(boost::bind(g, _1)), key1_(key1), key2_(key2) { this->keys_.push_back(key1); this->keys_.push_back(key2); } /* ************************************************************************* */ template NonlinearConstraint2::NonlinearConstraint2( boost::function g, const Key1& key1, boost::function G1, const Key2& key2, boost::function G2, size_t dim, double mu) : NonlinearConstraint(dim, mu), G1_(G1), G2_(G2), g_(g), key1_(key1), key2_(key2) { this->keys_.push_back(key1); this->keys_.push_back(key2); } /* ************************************************************************* */ template void NonlinearConstraint2::print(const std::string& s) const { std::cout << "NonlinearConstraint2 [" << s << "]: Dim: " << this->dim() << " mu: " << this->mu_ << "\n" << " Key1 : " << (std::string) this->key1_ << "\n" << " Key2 : " << (std::string) this->key2_ << "\n"; } /* ************************************************************************* */ template bool NonlinearConstraint2::equals(const Factor& f, double tol) const { const NonlinearConstraint2* p = dynamic_cast*> (&f); if (p == NULL) return false; if (!(key1_ == p->key1_)) return false; if (!(key2_ == p->key2_)) return false; if (fabs(this->mu_ - p->mu_ ) > tol) return false; return this->dim() == p->dim(); } /* ************************************************************************* */ template GaussianFactor::shared_ptr NonlinearConstraint2::linearize(const Config& config) const { Vector g = -1.0 * g_(config); Matrix grad1 = G1_(config); Matrix grad2 = G2_(config); SharedDiagonal model = noiseModel::Constrained::All(this->dim()); GaussianFactor::shared_ptr factor(new GaussianFactor(this->key1_, grad1, this->key2_, grad2, g, model)); return factor; } }