Fastest linearize so far. Putting 'unsafe' constructor in JacobianFactor itself makes a *huge* difference.

release/4.3a0
dellaert 2014-11-02 11:40:48 +01:00
parent 7aaf4dae8c
commit cb69f2cb82
3 changed files with 24 additions and 54 deletions

View File

@ -140,6 +140,25 @@ namespace gtsam {
JacobianFactor(
const KEYS& keys, const VerticalBlockMatrix& augmentedMatrix, const SharedDiagonal& sigmas = SharedDiagonal());
/**
* Constructor
* @param keys in some order
* @param diemnsions of the variables in same order
* @param m output dimension
* @param model noise model (default NULL)
*/
template<class KEYS, class DIMENSIONS>
JacobianFactor(const KEYS& keys, const DIMENSIONS& dims, DenseIndex m,
const SharedDiagonal& model = SharedDiagonal()) :
Base(keys), Ab_(dims.begin(), dims.end(), m, true), model_(model) {
Ab_.matrix().setZero();
}
/// Direct access to VerticalBlockMatrix
VerticalBlockMatrix& Ab() {
return Ab_;
}
/**
* Build a dense joint factor from all the factors in a factor graph. If a VariableSlots
* structure computed for \c graph is already available, providing it will reduce the amount of

View File

@ -24,57 +24,8 @@
#include <boost/range/algorithm.hpp>
#include <numeric>
class ExpressionFactorWriteableJacobianFactorTest;
namespace gtsam {
/**
* Special version of JacobianFactor that allows Jacobians to be written
* Eliminates a large proportion of overhead
* Note all ExpressionFactor<T> are friends, not for general consumption.
*/
class WriteableJacobianFactor: public JacobianFactor {
public:
/**
* Constructor
* @param keys in some order
* @param diemnsions of the variables in same order
* @param m output dimension
* @param model noise model (default NULL)
*/
template<class KEYS, class DIMENSIONS>
WriteableJacobianFactor(const KEYS& keys, const DIMENSIONS& dims,
DenseIndex m, const SharedDiagonal& model = SharedDiagonal()) {
// Check noise model dimension
if (model && (DenseIndex) model->dim() != m)
throw InvalidNoiseModel(m, model->dim());
// copy the keys
keys_.resize(keys.size());
std::copy(keys.begin(), keys.end(), keys_.begin());
// Check number of variables
if (dims.size() != keys_.size())
throw std::invalid_argument(
"WriteableJacobianFactor: size of dimensions and keys do not agree.");
Ab_ = VerticalBlockMatrix(dims.begin(), dims.end(), m, true);
Ab_.matrix().setZero();
model_ = model;
}
VerticalBlockMatrix& Ab() {
return Ab_;
}
// friend class ::ExpressionFactorWriteableJacobianFactorTest;
// template<typename T>
// friend class ExpressionFactor;
};
/**
* Factor that supports arbitrary expressions via AD
*/
@ -164,9 +115,9 @@ public:
model = constrained->unit();
// Create a writeable JacobianFactor in advance
boost::shared_ptr<WriteableJacobianFactor> factor = boost::make_shared<
WriteableJacobianFactor>(keys_, dimensions_,
traits::dimension<T>::value, model);
boost::shared_ptr<JacobianFactor> factor(
new JacobianFactor(keys_, dimensions_, traits::dimension<T>::value,
model));
// Wrap keys and VerticalBlockMatrix into structure passed to expression_
JacobianMap map(keys_, factor->Ab());

View File

@ -431,9 +431,9 @@ TEST(ExpressionFactor, WriteableJacobianFactor) {
dimensions[0] = 6;
dimensions[1] = 3;
SharedDiagonal model;
WriteableJacobianFactor actual(keys, dimensions, 2, model);
JacobianFactor actual(keys, dimensions, 2, model);
JacobianFactor expected(1, zeros(2, 6), 2, zeros(2, 3), zero(2));
EXPECT( assert_equal(expected, *(JacobianFactor*)(&actual),1e-9));
EXPECT( assert_equal(expected, actual,1e-9));
}
/* ************************************************************************* */