/* * @file LinearApproxFactor.h * @brief A dummy factor that allows a linear factor to act as a nonlinear factor * @author Alex Cunningham */ #pragma once #include #include #include namespace gtsam { /* ************************************************************************* */ template LinearApproxFactor::LinearApproxFactor(GaussianFactor::shared_ptr lin_factor, const Values& lin_points) : Base(noiseModel::Unit::Create(lin_factor->get_model()->dim())), lin_factor_(lin_factor), lin_points_(lin_points) { // create the keys and store them BOOST_FOREACH(Symbol key, lin_factor->keys()) { nonlinearKeys_.push_back(Key(key.index())); this->keys_.push_back(key); } } /* ************************************************************************* */ template Vector LinearApproxFactor::unwhitenedError(const Values& c) const { // extract the points in the new config VectorValues delta; BOOST_FOREACH(const Key& key, nonlinearKeys_) { X newPt = c[key], linPt = lin_points_[key]; Vector d = linPt.logmap(newPt); delta.insert(key, d); } return lin_factor_->unweighted_error(delta); } /* ************************************************************************* */ template boost::shared_ptr LinearApproxFactor::linearize(const Values& c) const { Vector b = lin_factor_->getb(); SharedDiagonal model = lin_factor_->get_model(); std::vector > terms; BOOST_FOREACH(Symbol key, lin_factor_->keys()) { terms.push_back(std::make_pair(key, lin_factor_->get_A(key))); } return boost::shared_ptr( new GaussianFactor(terms, b, model)); } /* ************************************************************************* */ template void LinearApproxFactor::print(const std::string& s) const { LinearApproxFactor::Base::print(s); lin_factor_->print(); } } // \namespace gtsam