gtsam
Loading...
Searching...
No Matches
OptionalJacobian.h
Go to the documentation of this file.
1/* ----------------------------------------------------------------------------
2
3 * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4 * Atlanta, Georgia 30332-0415
5 * All Rights Reserved
6 * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7
8 * See LICENSE for the license information
9
10 * -------------------------------------------------------------------------- */
11
19
20#pragma once
21#include <gtsam/config.h> // Configuration from CMake
22
23#include <Eigen/Core>
24#include <Eigen/LU>
25#include <cstddef>
26#include <functional>
27#include <optional>
28#include <stdexcept>
29#include <string>
30
31namespace gtsam {
32
39template<int Rows, int Cols>
40class OptionalJacobian {
41
42public:
43
46 typedef Eigen::Matrix<double, Rows, Cols> Jacobian;
47 typedef Eigen::Stride<Eigen::Dynamic, 1> Stride;
48 typedef Eigen::Map<Jacobian, 0, Stride> Map;
49
50private:
51
52 Map map_;
53
54 // Trick from http://eigen.tuxfamily.org/dox/group__TutorialMapClass.html
55 // uses "placement new" to make map_ usurp the memory of the fixed size matrix
56 void usurp(double* data, Eigen::Index outerStride) {
57 new (&map_) Map(data, Stride(outerStride, 1));
58 }
59
60 // Private and very dangerous constructor straight from memory
61 OptionalJacobian(double* data, Eigen::Index outerStride)
62 : map_(nullptr, Stride(1, 1)) {
63 if (data) usurp(data, outerStride);
64 }
65
66 template<int M, int N>
67 friend class OptionalJacobian;
68
69public:
70
72 OptionalJacobian() : map_(nullptr, Stride(1, 1)) {
73 }
74
78 OptionalJacobian(std::nullptr_t /*unused*/) :
79 map_(nullptr, Stride(1, 1)) {
80 }
81
84 map_(nullptr, Stride(1, 1)) {
85 usurp(fixed.data(), fixed.rows());
86 }
87
90 map_(nullptr, Stride(1, 1)) {
91 if (fixedPtr)
92 usurp(fixedPtr->data(), fixedPtr->rows());
93 }
94
96 OptionalJacobian(Eigen::MatrixXd& dynamic) :
97 map_(nullptr, Stride(1, 1)) {
98 dynamic.resize(Rows, Cols); // no malloc if correct size
99 usurp(dynamic.data(), dynamic.rows());
100 }
101
103 OptionalJacobian(Eigen::MatrixXd* dynamic) :
104 map_(nullptr, Stride(1, 1)) {
105 if (dynamic) {
106 dynamic->resize(Rows, Cols); // no malloc if correct size
107 usurp(dynamic->data(), dynamic->rows());
108 }
109 }
110
115 template<class MATRIX>
116 OptionalJacobian(Eigen::Ref<MATRIX> dynamic_ref) :
117 map_(nullptr, Stride(1, 1)) {
118 if (dynamic_ref.rows() == Rows && dynamic_ref.cols() == Cols &&
119 !dynamic_ref.IsRowMajor && dynamic_ref.innerStride() == 1) {
120 usurp(dynamic_ref.data(), dynamic_ref.outerStride());
121 } else {
122 throw std::invalid_argument(
123 std::string("OptionalJacobian called with wrong dimensions or "
124 "storage order.\n"
125 "Expected: ") +
126 "(" + std::to_string(Rows) + ", " + std::to_string(Cols) + ")");
127 }
128 }
129
131 OptionalJacobian(std::nullopt_t /*none*/) :
132 map_(nullptr, Stride(1, 1)) {
133 }
134
136 OptionalJacobian(const std::optional<std::reference_wrapper<Eigen::MatrixXd>> optional) :
137 map_(nullptr, Stride(1, 1)) {
138 if (optional) {
139 optional->get().resize(Rows, Cols);
140 usurp(optional->get().data(), optional->get().rows());
141 }
142 }
143
145 // template <typename Derived, bool InnerPanel>
146 // OptionalJacobian(Eigen::Block<Derived,Rows,Cols,InnerPanel> block) : map_(nullptr) { ?? }
147
149 operator bool() const {
150 return map_.data() != nullptr;
151 }
152
154 Map& operator*() {
155 return map_;
156 }
157
159 Map* operator->() {
160 return &map_;
161 }
162
165 // template <int M, int N>
166 // OptionalJacobian<M, N> block(int startRow, int startCol) {
167 // if (*this)
168 // OptionalJacobian<M, N>(map_.block<M, N>(startRow, startCol));
169 // else
170 // return OptionalJacobian<M, N>();
171 // }
172
176 template <int N>
177 OptionalJacobian<Rows, N> cols(int startCol) {
178 if (*this)
179 return OptionalJacobian<Rows, N>(&map_(0, startCol), map_.outerStride());
180 else
182 }
183
188};
189
190// The pure dynamic specialization of this is needed to support
191// variable-sized types. Note that this is designed to work like the
192// boost optional scheme from GTSAM 3.
193template<>
194class OptionalJacobian<Eigen::Dynamic, Eigen::Dynamic> {
195
196public:
197
199 typedef Eigen::MatrixXd Jacobian;
200
201private:
202
203 Jacobian* pointer_;
204
205public:
206
209 pointer_(nullptr) {
210 }
211
213 OptionalJacobian(Jacobian* pointer) : pointer_(pointer) {}
214
216 OptionalJacobian(Jacobian& dynamic) : pointer_(&dynamic) {}
217
219 OptionalJacobian(std::nullopt_t /*none*/) :
220 pointer_(nullptr) {
221 }
222
224 OptionalJacobian(const std::optional<std::reference_wrapper<Eigen::MatrixXd>> optional) :
225 pointer_(nullptr) {
226 if (optional) pointer_ = &((*optional).get());
227 }
228
230 operator bool() const {
231 return pointer_!=nullptr;
232 }
233
236 return *pointer_;
237 }
238
240 Jacobian* operator->(){ return pointer_; }
241};
242
243// forward declare
244template <typename T> struct traits;
245
251template <class T, class A>
253 typedef Eigen::Matrix<double, traits<T>::dimension, traits<A>::dimension> type;
254};
255
262template<class T, class A>
267
268} // namespace gtsam
Global functions in a separate testing namespace.
Definition chartTesting.h:28
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition Group.h:37
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition OptionalJacobian.h:40
OptionalJacobian(Eigen::MatrixXd &dynamic)
Constructor that will resize a dynamic matrix (unless already correct).
Definition OptionalJacobian.h:96
OptionalJacobian()
Default constructor.
Definition OptionalJacobian.h:72
OptionalJacobian(Jacobian &fixed)
Constructor that will usurp data of a fixed-size matrix.
Definition OptionalJacobian.h:83
Map & operator*()
De-reference, like boost optional.
Definition OptionalJacobian.h:154
OptionalJacobian(std::nullptr_t)
Default constructor with nullptr_t To guide the compiler when nullptr is passed to args of the type O...
Definition OptionalJacobian.h:78
OptionalJacobian(Eigen::Ref< MATRIX > dynamic_ref)
Constructor from an Eigen::Ref value.
Definition OptionalJacobian.h:116
OptionalJacobian(Eigen::MatrixXd *dynamic)
Constructor that will resize a dynamic matrix (unless already correct).
Definition OptionalJacobian.h:103
OptionalJacobian(const std::optional< std::reference_wrapper< Eigen::MatrixXd > > optional)
Constructor compatible with old-style derivatives.
Definition OptionalJacobian.h:136
Eigen::Matrix< double, Rows, Cols > Jacobian
Definition OptionalJacobian.h:46
OptionalJacobian(Jacobian *fixedPtr)
Constructor that will usurp data of a fixed-size matrix, pointer version.
Definition OptionalJacobian.h:89
Map * operator->()
operator->()
Definition OptionalJacobian.h:159
OptionalJacobian(std::nullopt_t)
Constructor with std::nullopt just makes empty.
Definition OptionalJacobian.h:131
OptionalJacobian< Rows, N > cols(int startCol)
Access M*N sub-block if we are allocated, otherwise none TODO(frank): this could work as is below if ...
Definition OptionalJacobian.h:177
OptionalJacobian()
View on constructor argument, if given.
Definition OptionalJacobian.h:208
Eigen::MatrixXd Jacobian
Jacobian size type.
Definition OptionalJacobian.h:199
OptionalJacobian(std::nullopt_t)
Constructor with std::nullopt just makes empty.
Definition OptionalJacobian.h:219
OptionalJacobian(const std::optional< std::reference_wrapper< Eigen::MatrixXd > > optional)
Constructor for optional matrix reference.
Definition OptionalJacobian.h:224
Jacobian & operator*()
De-reference, like boost optional.
Definition OptionalJacobian.h:235
OptionalJacobian(Jacobian *pointer)
Construct from pointer to dynamic matrix.
Definition OptionalJacobian.h:213
OptionalJacobian(Jacobian &dynamic)
Construct from refrence to dynamic matrix.
Definition OptionalJacobian.h:216
Jacobian * operator->()
TODO: operator->().
Definition OptionalJacobian.h:240
: meta-function to generate Jacobian
Definition OptionalJacobian.h:252
: meta-function to generate JacobianTA optional reference Used mainly by Expressions
Definition OptionalJacobian.h:263