Skip to content

Commit

Permalink
Store rowmajor flag for each Hessian block
Browse files Browse the repository at this point in the history
The BaseFixedSizedEdge template needs to store for each Hessian block if
the respective block is transposed or not. Before a single boolean was
used which means that for an edge all blocks had to be on the upper
triangular block of the Hessian.

fixes RainerKuemmerle#504
  • Loading branch information
RainerKuemmerle committed Oct 9, 2021
1 parent f5d454f commit 97521b4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
18 changes: 16 additions & 2 deletions g2o/core/base_fixed_sized_edge.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#ifndef G2O_BASE_FIXED_SIZED_EDGE_H
#define G2O_BASE_FIXED_SIZED_EDGE_H

#include <array>
#include <iostream>
#include <limits>
#include <utility>
Expand All @@ -46,6 +47,18 @@
namespace g2o {

namespace internal {

// creating a bool array
template <int K>
std::array<bool, K> createBoolArray() {
std::array<bool, K> aux = {false};
return aux;
}
template <>
inline std::array<bool, 0> createBoolArray<0>() {
return std::array<bool, 0>();
}

// assumes i < j
// duplication of internal::computeUpperTriangleIndex in g2o/core/base_variable_sized_edge.hpp
constexpr int pair_to_index(const int i, const int j) { return j * (j - 1) / 2 + i; }
Expand Down Expand Up @@ -186,10 +199,11 @@ class BaseFixedSizedEdge : public BaseEdge<D, E> {
typename HessianTupleType<std::make_index_sequence<_nr_of_vertex_pairs>>::type;
using HessianTupleTransposed =
typename HessianTupleType<std::make_index_sequence<_nr_of_vertex_pairs>>::typeTransposed;
using HessianRowMajorStorage = std::array<bool, _nr_of_vertex_pairs>;

BaseFixedSizedEdge()
: BaseEdge<D, E>(),
_hessianRowMajor(false),
_hessianRowMajor(internal::createBoolArray<_nr_of_vertex_pairs>()),
_hessianTuple(internal::createHessianMaps(_hessianTuple)),
_hessianTupleTransposed(internal::createHessianMaps(_hessianTupleTransposed)),
_jacobianOplus({nullptr, D, VertexTypes::Dimension}...) {
Expand Down Expand Up @@ -266,7 +280,7 @@ class BaseFixedSizedEdge : public BaseEdge<D, E> {
using BaseEdge<D, E>::_vertices;
using BaseEdge<D, E>::_dimension;

bool _hessianRowMajor;
HessianRowMajorStorage _hessianRowMajor;
HessianTuple _hessianTuple;
HessianTupleTransposed _hessianTupleTransposed;
std::tuple<JacobianType<D, VertexTypes::Dimension>...> _jacobianOplus;
Expand Down
13 changes: 7 additions & 6 deletions g2o/core/base_fixed_sized_edge.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,14 @@ void BaseFixedSizedEdge<D, E, VertexTypes...>::constructOffDiagonalQuadraticForm
const AtOType& AtO) {
constexpr auto fromId = N;
constexpr auto toId = N + M + 1;
assert(fromId < toId && "Index mixed up");
auto to = vertexXn<toId>();
if (!to->fixed()) {
const auto& B = std::get<toId>(_jacobianOplus);
constexpr auto K = internal::pair_to_index(fromId, toId);
internal::QuadraticFormLock lck(*to);
(void)lck;
if (_hessianRowMajor) { // we have to write to the block as transposed
if (_hessianRowMajor[K]) { // we have to write to the block as transposed
auto& hessianTransposed = std::get<K>(_hessianTupleTransposed);
hessianTransposed.noalias() += B.transpose() * AtO.transpose();
} else {
Expand Down Expand Up @@ -217,14 +218,14 @@ struct MapHessianMemoryK {
template <int D, typename E, typename... VertexTypes>
void BaseFixedSizedEdge<D, E, VertexTypes...>::mapHessianMemory(number_t* d, int i, int j,
bool rowMajor) {
assert(i < j && "index assumption violated");
// get the size of the vertices
int vi_dim = static_cast<OptimizableGraph::Vertex*>(HyperGraph::Edge::vertex(i))->dimension();
int vj_dim = static_cast<OptimizableGraph::Vertex*>(HyperGraph::Edge::vertex(j))->dimension();
_hessianRowMajor = rowMajor;
int k = internal::pair_to_index(i, j);
_hessianRowMajor[k] = rowMajor;
if (rowMajor)
tuple_apply_i(MapHessianMemoryK{d, vj_dim, vi_dim}, _hessianTupleTransposed,
internal::pair_to_index(i, j));
tuple_apply_i(MapHessianMemoryK{d, vj_dim, vi_dim}, _hessianTupleTransposed, k);
else
tuple_apply_i(MapHessianMemoryK{d, vi_dim, vj_dim}, _hessianTuple,
internal::pair_to_index(i, j));
tuple_apply_i(MapHessianMemoryK{d, vi_dim, vj_dim}, _hessianTuple, k);
}

0 comments on commit 97521b4

Please sign in to comment.