29template <
int D,
typename E,
typename... VertexTypes>
31 assert(size == _nr_of_vertices &&
32 "attempting to resize a constant size edge");
36template <
int D,
typename E,
typename... VertexTypes>
37template <std::size_t... Ints>
39 std::index_sequence<Ints...>)
const {
40 return (... && vertexXn<Ints>()->fixed());
43template <
int D,
typename E,
typename... VertexTypes>
45 return allVerticesFixedNs(std::make_index_sequence<_nr_of_vertices>());
48template <
int D,
typename E,
typename... VertexTypes>
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...>) {
70 (void(constructQuadraticFormN<Ints>(omega, weightedError)), ...);
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...>) {
86 (void(constructOffDiagonalQuadraticFormM<N, Ints, AtOType>(AtO)), ...);
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");
96 auto to = vertexXn<toId>();
98 const auto& B = std::get<toId>(_jacobianOplus);
99 constexpr auto K = internal::pair_to_index(fromId, toId);
102 if (_hessianRowMajor[K]) {
103 auto& hessianTransposed = std::get<K>(_hessianTupleTransposed);
104 hessianTransposed.noalias() += B.transpose() * AtO.transpose();
106 auto& hessian = std::get<K>(_hessianTuple);
107 hessian.noalias() += AtO * B;
112template <
int D,
typename E,
typename... VertexTypes>
116 auto from = vertexXn<N>();
117 const auto& A = std::get<N>(_jacobianOplus);
119 if (!(from->fixed())) {
120 const auto AtO = A.transpose() * omega;
124 from->b().noalias() += A.transpose() * weightedError;
125 from->A().noalias() += AtO * A;
127 constructOffDiagonalQuadraticFormMs<N>(
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>
144 (
new (&std::get<Ints>(_jacobianOplus))
147 VertexDimension<Ints>() < 0 ? vertexXn<Ints>()->dimension()
148 : VertexDimension<Ints>()),
152template <
int D,
typename E,
typename... VertexTypes>
155 auto vertex = vertexXn<N>();
157 if (vertex->fixed())
return;
159 auto& jacobianOplus = std::get<N>(_jacobianOplus);
161 constexpr double delta =
cst(1e-9);
162 constexpr double scalar = 1 / (2 * delta);
167 typedef typename std::conditional<
172 FixedArray add_vertex(vertexDimension<N>());
177 for (
int d = 0; d < vertexDimension<N>(); ++d) {
179 add_vertex[d] = delta;
180 vertex->oplus(add_vertex.
data());
182 auto errorBak = this->error();
185 add_vertex[d] = -delta;
186 vertex->oplus(add_vertex.
data());
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...>) {
200 (void(linearizeOplusN<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>
230 assert(i < j &&
"index assumption violated");
238 int k = internal::pair_to_index(i, j);
239 _hessianRowMajor[k] = rowMajor;
BaseEdge< D, E >::InformationType InformationType
BaseEdge< D, E >::ErrorVector ErrorVector
typename Eigen::Matrix< double, EdgeDimension, VertexDimension, EdgeDimension==1 ? Eigen::RowMajor :Eigen::ColMajor >::AlignedMapType JacobianType
NthType< VertexN, VertexTypes... > VertexXnType
The type of the N-th vertex.
provide memory workspace for computing the Jacobians
double * workspaceForVertex(int vertexIndex)
A general case Vertex for optimization.
const_pointer data() const
void fill(const value_type &val)
constexpr double cst(long double v)
void tuple_apply_i(F &&f, T &t, int i)
void operator()(HessianT &hessian)