29template <
int D,
typename E,
typename... VertexTypes>
30void BaseFixedSizedEdge<D, E, VertexTypes...>::resize(
size_t size) {
31 assert(size == _nr_of_vertices &&
32 "attempting to resize a constant size edge");
33 BaseEdge<D, E>::resize(size);
36template <
int D,
typename E,
typename... VertexTypes>
37template <std::size_t... Ints>
39 std::index_sequence<Ints...>)
const {
43template <
int D,
typename E,
typename... VertexTypes>
45 return allVerticesFixedNs(std::make_index_sequence<_nr_of_vertices>());
48template <
int D,
typename E,
typename... VertexTypes>
49void BaseFixedSizedEdge<D, E, VertexTypes...>::constructQuadraticForm() {
50 if (this->robustKernel()) {
51 double error = this->chi2();
53 this->robustKernel()->robustify(error, rho);
54 Eigen::Matrix<double, D, 1, Eigen::ColMajor> omega_r =
55 -_information * _error;
57 constructQuadraticFormNs(this->robustInformation(rho), omega_r,
58 std::make_index_sequence<_nr_of_vertices>());
60 constructQuadraticFormNs(_information, -_information * _error,
61 std::make_index_sequence<_nr_of_vertices>());
65template <
int D,
typename E,
typename... VertexTypes>
66template <std::size_t... Ints>
69 std::index_sequence<Ints...>) {
75template <
int D,
typename E,
typename... VertexTypes>
76template <
int N,
typename AtOType>
81template <
int D,
typename E,
typename... VertexTypes>
82template <
int N, std::size_t... Ints,
typename AtOType>
85 std::index_sequence<Ints...>) {
89template <
int D,
typename E,
typename... VertexTypes>
90template <
int N,
int M,
typename AtOType>
93 constexpr auto fromId = N;
94 constexpr auto toId = N + M + 1;
95 assert(fromId < toId &&
"Index mixed up");
104 hessianTransposed.noalias() += B.transpose() * AtO.transpose();
107 hessian.noalias() += AtO * B;
112template <
int D,
typename E,
typename... VertexTypes>
119 if (!(from->fixed())) {
120 const auto AtO = A.transpose() * omega;
124 from->b().noalias() += A.transpose() * weightedError;
125 from->A().noalias() += AtO * A;
128 AtO, std::make_index_sequence<_nr_of_vertices - N - 1>());
132template <
int D,
typename E,
typename... VertexTypes>
135 linearizeOplus_allocate(jacobianWorkspace,
136 std::make_index_sequence<_nr_of_vertices>());
140template <
int D,
typename E,
typename... VertexTypes>
141template <std::size_t... Ints>
152template <
int D,
typename E,
typename... VertexTypes>
157 if (
vertex->fixed())
return;
161 constexpr double delta =
cst(1e-9);
162 constexpr double scalar = 1 / (2 * delta);
167 typedef typename std::conditional<
177 for (
int d = 0; d < vertexDimension<N>(); ++d) {
179 add_vertex[d] = delta;
182 auto errorBak = this->error();
185 add_vertex[d] = -delta;
188 errorBak -= this->error();
192 jacobianOplus.col(d) = scalar * errorBak;
196template <
int D,
typename E,
typename... VertexTypes>
197template <std::size_t... Ints>
199 std::index_sequence<Ints...>) {
203template <
int D,
typename E,
typename... VertexTypes>
205 if (allVerticesFixed())
return;
207 linearizeOplusNs(std::make_index_sequence<_nr_of_vertices>());
208 _error = errorBeforeNumeric;
219 template <
typename HessianT>
222 typename std::remove_reference<
decltype(hessian)>::type(
d,
rows,
cols);
226template <
int D,
typename E,
typename... VertexTypes>
227void BaseFixedSizedEdge<D, E, VertexTypes...>::mapHessianMemory(
double* d,
230 assert(i < j &&
"index assumption violated");
233 static_cast<OptimizableGraph::Vertex*
>(HyperGraph::Edge::vertex(i))
236 static_cast<OptimizableGraph::Vertex*
>(HyperGraph::Edge::vertex(j))
238 int k = internal::pair_to_index(i, j);
239 _hessianRowMajor[k] = rowMajor;
BaseEdge< D, OdomAndLaserMotion >::InformationType InformationType
virtual bool allVerticesFixed() const
bool allVerticesFixedNs(std::index_sequence< Ints... >) const
typename Eigen::Matrix< double, EdgeDimension, VertexDimension, EdgeDimension==1 ? Eigen::RowMajor :Eigen::ColMajor >::AlignedMapType JacobianType
BaseEdge< D, OdomAndLaserMotion >::ErrorVector ErrorVector
void linearizeOplusNs(std::index_sequence< Ints... >)
HessianTuple _hessianTuple
void constructOffDiagonalQuadraticFormMs(const AtOType &, std::index_sequence<>)
static constexpr int VertexDimension()
virtual void linearizeOplus(JacobianWorkspace &jacobianWorkspace)
HessianTupleTransposed _hessianTupleTransposed
void linearizeOplus_allocate(JacobianWorkspace &jacobianWorkspace, std::index_sequence< Ints... >)
void constructQuadraticFormN(const InformationType &omega, const ErrorVector &weightedError)
HessianRowMajorStorage _hessianRowMajor
constexpr std::enable_if< VertexXnType< VertexN >::Dimension!=-1, int >::type vertexDimension() const
std::tuple< JacobianType< D, VertexTypes::Dimension >... > _jacobianOplus
void constructOffDiagonalQuadraticFormM(const AtOType &AtO)
NthType< VertexN, VertexTypes... > VertexXnType
void constructQuadraticFormNs(const InformationType &omega, const ErrorVector &weightedError, std::index_sequence< Ints... >)
const VertexXnType< VertexN > * vertexXn() const
const Vertex * vertex(size_t i) const
provide memory workspace for computing the Jacobians
double * workspaceForVertex(int vertexIndex)
int dimension() const
returns the dimensions of the error function
virtual void computeError()=0
const_pointer data() const
void fill(const value_type &val)
constexpr int pair_to_index(const int i, const int j)
constexpr double cst(long double v)
void tuple_apply_i(F &&f, T &t, int i)
void operator()(HessianT &hessian)