Added GaussianFactorGraph::sparseJacobian function to create a sparse Jacobian matrix suitable for Matlab
parent
900227234f
commit
bdbc09ba42
|
@ -27,6 +27,7 @@
|
|||
#include <gtsam/linear/GaussianFactorGraph.h>
|
||||
#include <gtsam/inference/FactorGraph-inl.h>
|
||||
#include <gtsam/linear/iterative.h>
|
||||
#include <gtsam/linear/HessianFactor.h>
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
@ -82,6 +83,34 @@ namespace gtsam {
|
|||
return fg;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
std::vector<boost::tuple<size_t,size_t,double> >
|
||||
GaussianFactorGraph::sparseJacobian(const std::vector<size_t>& columnIndices) const {
|
||||
std::vector<boost::tuple<size_t,size_t,double> > entries;
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(const sharedFactor& factor, *this) {
|
||||
// Convert to JacobianFactor if necessary
|
||||
JacobianFactor::shared_ptr jacobianFactor(boost::dynamic_pointer_cast<JacobianFactor>(factor));
|
||||
if(!jacobianFactor) {
|
||||
HessianFactor::shared_ptr hessianFactor(boost::dynamic_pointer_cast<HessianFactor>(factor));
|
||||
if(hessianFactor)
|
||||
jacobianFactor.reset(new JacobianFactor(*hessianFactor));
|
||||
else
|
||||
throw invalid_argument("GaussianFactorGraph contains a factor that is neither a JacobianFactor nor a HessianFactor.");
|
||||
}
|
||||
|
||||
// Add entries, adjusting the row index i
|
||||
std::vector<boost::tuple<size_t,size_t,double> > factorEntries(jacobianFactor->sparse(columnIndices));
|
||||
entries.reserve(entries.size() + factorEntries.size());
|
||||
for(size_t entry=0; entry<factorEntries.size(); ++entry)
|
||||
entries.push_back(boost::make_tuple(factorEntries[entry].get<0>()+i, factorEntries[entry].get<1>(), factorEntries[entry].get<2>()));
|
||||
|
||||
// Increment row index
|
||||
i += jacobianFactor->size1();
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
// VectorValues GaussianFactorGraph::allocateVectorValuesb() const {
|
||||
// std::vector<size_t> dimensions(size()) ;
|
||||
// Index i = 0 ;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <gtsam/base/FastSet.h>
|
||||
#include <gtsam/inference/FactorGraph.h>
|
||||
|
@ -120,6 +121,14 @@ namespace gtsam {
|
|||
*/
|
||||
void combine(const GaussianFactorGraph &lfg);
|
||||
|
||||
/**
|
||||
* Return vector of i, j, and s to generate an m-by-n sparse Jacobain matrix
|
||||
* such that S(i(k),j(k)) = s(k), which can be given to MATLAB's sparse.
|
||||
* The standard deviations are baked into A and b
|
||||
* @param first column index for each variable
|
||||
*/
|
||||
std::vector<boost::tuple<size_t,size_t,double> > sparseJacobian(const std::vector<size_t>& columnIndices) const;
|
||||
|
||||
// get b
|
||||
// void getb(VectorValues &b) const ;
|
||||
// VectorValues getb() const ;
|
||||
|
|
|
@ -337,31 +337,28 @@ namespace gtsam {
|
|||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
boost::tuple<list<int>, list<int>, list<double> >
|
||||
JacobianFactor::sparse(const map<Index,size_t>& columnIndices) const {
|
||||
std::vector<boost::tuple<size_t, size_t, double> >
|
||||
JacobianFactor::sparse(const std::vector<size_t>& columnIndices) const {
|
||||
|
||||
// declare return values
|
||||
list<int> I,J;
|
||||
list<double> S;
|
||||
std::vector<boost::tuple<size_t, size_t, double> > entries;
|
||||
|
||||
// iterate over all matrices in the factor
|
||||
for(size_t pos=0; pos<keys_.size(); ++pos) {
|
||||
constABlock A(Ab_(pos));
|
||||
// iterate over all variables in the factor
|
||||
for(const_iterator var=begin(); var<end(); ++var) {
|
||||
Matrix whitenedA(model_->Whiten(getA(var)));
|
||||
// find first column index for this key
|
||||
int column_start = columnIndices.at(keys_[pos]);
|
||||
for (size_t i = 0; i < A.size1(); i++) {
|
||||
double sigma_i = model_->sigma(i);
|
||||
for (size_t j = 0; j < A.size2(); j++)
|
||||
if (A(i, j) != 0.0) {
|
||||
I.push_back(i + 1);
|
||||
J.push_back(j + column_start);
|
||||
S.push_back(A(i, j) / sigma_i);
|
||||
}
|
||||
}
|
||||
size_t column_start = columnIndices[*var];
|
||||
for (size_t i = 0; i < whitenedA.size1(); i++)
|
||||
for (size_t j = 0; j < whitenedA.size2(); j++)
|
||||
entries.push_back(boost::make_tuple(i, column_start+j, whitenedA(i,j)));
|
||||
}
|
||||
|
||||
Vector whitenedb(model_->whiten(getb()));
|
||||
size_t bcolumn = columnIndices.back();
|
||||
for (size_t i = 0; i < whitenedb.size(); i++)
|
||||
entries.push_back(boost::make_tuple(i, bcolumn, whitenedb(i)));
|
||||
|
||||
// return the result
|
||||
return boost::tuple<list<int>, list<int>, list<double> >(I,J,S);
|
||||
return entries;
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
|
|
|
@ -178,13 +178,13 @@ namespace gtsam {
|
|||
Matrix matrix_augmented(bool weight = true) const;
|
||||
|
||||
/**
|
||||
* Return vectors i, j, and s to generate an m-by-n sparse matrix
|
||||
* Return vector of i, j, and s to generate an m-by-n sparse matrix
|
||||
* such that S(i(k),j(k)) = s(k), which can be given to MATLAB's sparse.
|
||||
* As above, the standard deviations are baked into A and b
|
||||
* @param first column index for each variable
|
||||
*/
|
||||
boost::tuple<std::list<int>, std::list<int>, std::list<double> >
|
||||
sparse(const std::map<Index, size_t>& columnIndices) const;
|
||||
std::vector<boost::tuple<size_t, size_t, double> >
|
||||
sparse(const std::vector<size_t>& columnIndices) const;
|
||||
|
||||
/**
|
||||
* Return a whitened version of the factor, i.e. with unit diagonal noise
|
||||
|
|
Loading…
Reference in New Issue