31 int elemsUpToCol = ((j - 1) * j) / 2;
32 return elemsUpToCol + i;
36template <
int D,
typename E>
38 if (this->robustKernel()) {
39 double error = this->chi2();
41 this->robustKernel()->robustify(error, rho);
42 Eigen::Matrix<double, D, 1, Eigen::ColMajor> omega_r =
43 -_information * _error;
45 computeQuadraticForm(this->robustInformation(rho), omega_r);
47 computeQuadraticForm(_information, -_information * _error);
51template <
int D,
typename E>
54 for (
size_t i = 0; i < _vertices.size(); ++i) {
58 new (&_jacobianOplus[i])
65template <
int D,
typename E>
67 const double delta =
cst(1e-9);
68 const double scalar = 1 / (2 * delta);
72 for (
size_t i = 0; i < _vertices.size(); ++i) {
85 assert(_dimension >= 0);
86 assert(_jacobianOplus[i].rows() == _dimension &&
87 _jacobianOplus[i].cols() == vi_dim &&
88 "jacobian cache dimension does not match");
89 _jacobianOplus[i].resize(_dimension, vi_dim);
93 for (
int d = 0; d < vi_dim; ++d) {
96 vi->
oplus(add_vi.data());
102 vi->
oplus(add_vi.data());
108 _jacobianOplus[i].col(d) = scalar * errorBak;
110 _error = errorBeforeNumeric;
114template <
int D,
typename E>
118 assert(idx < (
int)_hessian.size());
136template <
int D,
typename E>
139 int n = (int)_vertices.size();
140 int maxIdx = (n * (n - 1)) / 2;
142 _hessian.resize(maxIdx);
146template <
int D,
typename E>
148 for (
size_t i = 0; i < _vertices.size(); ++i) {
156template <
int D,
typename E>
159 for (
size_t i = 0; i < _vertices.size(); ++i) {
162 bool istatus = !(from->
fixed());
167 MatrixX AtO = A.transpose() * omega;
169 assert(fromDim >= 0);
170 Eigen::Map<MatrixX> fromMap(from->
hessianData(), fromDim, fromDim);
171 Eigen::Map<VectorX> fromB(from->
bData(), fromDim);
176 fromMap.noalias() += AtO * A;
177 fromB.noalias() += A.transpose() * weightedError;
181 for (
size_t j = i + 1; j < _vertices.size(); ++j) {
185 bool jstatus = !(to->
fixed());
190 assert(idx < (
int)_hessian.size());
194 hhelper.
matrix.noalias() += B.transpose() * AtO.transpose();
196 hhelper.
matrix.noalias() += AtO * B;
base class to represent an edge connecting an arbitrary number of nodes
Eigen::Map< MatrixX, MatrixX::Flags &Eigen::PacketAccessBit ? Eigen::Aligned :Eigen::Unaligned > HessianBlockType
MatrixX::MapType JacobianType
BaseEdge< D, E >::ErrorVector ErrorVector
BaseEdge< D, E >::InformationType InformationType
provide memory workspace for computing the Jacobians
double * workspaceForVertex(int vertexIndex)
A general case Vertex for optimization.
int dimension() const
dimension of the estimated state belonging to this node
bool fixed() const
true => this node is fixed during the optimization
virtual void push()=0
backup the position of the vertex to a stack
virtual double * hessianData()=0
virtual double * bData()=0
return a pointer to the b vector associated with this vertex
void oplus(const double *v)
MatrixN< Eigen::Dynamic > MatrixX
constexpr double cst(long double v)
int computeUpperTriangleIndex(int i, int j)
helper for mapping the Hessian memory of the upper triangular block
bool transposed
the block has to be transposed
Eigen::Map< MatrixX > matrix
the mapped memory