/* * @file JacobianFactorSVD.h * @date Oct 27, 2013 * @uthor Frank Dellaert */ #pragma once #include "gtsam_unstable/slam/JacobianSchurFactor.h" namespace gtsam { /** * JacobianFactor for Schur complement that uses Q noise model */ template class JacobianFactorSVD: public JacobianSchurFactor { public: typedef Eigen::Matrix Matrix2D; typedef std::pair KeyMatrix2D; typedef std::pair KeyMatrix; /// Default constructor JacobianFactorSVD() {} /// Empty constructor with keys JacobianFactorSVD(const FastVector& keys, const SharedDiagonal& model = SharedDiagonal()) : JacobianSchurFactor() { Matrix zeroMatrix = Matrix::Zero(0,D); Vector zeroVector = Vector::Zero(0); std::vector QF; QF.reserve(keys.size()); BOOST_FOREACH(const Key& key, keys) QF.push_back(KeyMatrix(key, zeroMatrix)); JacobianFactor::fillTerms(QF, zeroVector, model); } /// Constructor JacobianFactorSVD(const std::vector& Fblocks, const Matrix& Enull, const Vector& b, const SharedDiagonal& model = SharedDiagonal()) : JacobianSchurFactor() { size_t numKeys = Enull.rows() / 2; size_t j = 0, m2 = 2*numKeys-3; // PLAIN NULL SPACE TRICK // Matrix Q = Enull * Enull.transpose(); // BOOST_FOREACH(const KeyMatrix2D& it, Fblocks) // QF.push_back(KeyMatrix(it.first, Q.block(0, 2 * j++, m2, 2) * it.second)); // JacobianFactor factor(QF, Q * b); std::vector QF; QF.reserve(numKeys); BOOST_FOREACH(const KeyMatrix2D& it, Fblocks) QF.push_back(KeyMatrix(it.first, (Enull.transpose()).block(0, 2 * j++, m2, 2) * it.second)); JacobianFactor::fillTerms(QF, Enull.transpose() * b, model); } }; }