gtsam
Loading...
Searching...
No Matches
Basis.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
18
19#pragma once
20
21#include <gtsam/base/Matrix.h>
23
24#include <iostream>
25
66
67namespace gtsam {
68
69using Weights = Eigen::Matrix<double, 1, -1>; /* 1xN vector */
70
83Matrix GTSAM_EXPORT kroneckerProductIdentity(size_t M, const Weights& w);
84
89template <typename DERIVED>
90class Basis {
91 public:
97 static Matrix WeightMatrix(size_t N, const Vector& X) {
98 Matrix W(X.size(), N);
99 for (int i = 0; i < X.size(); i++)
100 W.row(i) = DERIVED::CalculateWeights(N, X(i));
101 return W;
102 }
103
113 static Matrix WeightMatrix(size_t N, const Vector& X, double a, double b) {
114 Matrix W(X.size(), N);
115 for (int i = 0; i < X.size(); i++)
116 W.row(i) = DERIVED::CalculateWeights(N, X(i), a, b);
117 return W;
118 }
119
128 protected:
129 Weights weights_;
130
131 public:
134
136 EvaluationFunctor(size_t N, double x)
137 : weights_(DERIVED::CalculateWeights(N, x)) {}
138
140 EvaluationFunctor(size_t N, double x, double a, double b)
141 : weights_(DERIVED::CalculateWeights(N, x, a, b)) {}
142
144 double apply(const typename DERIVED::Parameters& p,
145 OptionalJacobian<-1, -1> H = {}) const {
146 if (H) *H = weights_;
147 return weights_.transpose().dot(p);
148 }
149
151 double operator()(const typename DERIVED::Parameters& p,
152 OptionalJacobian<-1, -1> H = {}) const {
153 return apply(p, H); // might call apply in derived
154 }
155
156 void print(const std::string& s = "") const {
157 std::cout << s << (s != "" ? " " : "") << weights_ << std::endl;
158 }
159 };
160
168 protected:
169 using Jacobian = Eigen::Matrix<double, /*MxMN*/ -1, -1>;
170 Jacobian H_;
171
172 size_t M_;
173
183 H_ = kroneckerProductIdentity(M_, this->weights_);
184 }
185
186 public:
189
191 VectorEvaluationFunctor(size_t M, size_t N, double x)
192 : EvaluationFunctor(N, x), M_(M) {
194 }
195
197 VectorEvaluationFunctor(size_t M, size_t N, double x, double a, double b)
198 : EvaluationFunctor(N, x, a, b), M_(M) {
200 }
201
203 Vector apply(const Matrix& P,
205 if (H) *H = H_;
206 return P.matrix() * this->weights_.transpose();
207 }
208
210 Vector operator()(const Matrix& P,
212 return apply(P, H);
213 }
214 };
215
224 protected:
225 using Jacobian = Eigen::Matrix<double, /*1xMN*/ 1, -1>;
226 Jacobian H_;
227
228 size_t M_;
229 size_t rowIndex_;
230
231 /*
232 * Calculate the `1*(M*N)` Jacobian of this functor with respect to
233 * the M*N parameter matrix `P`.
234 * We flatten assuming column-major order, e.g., if N=3 and M=2, we have
235 * H=[w(0) 0 w(1) 0 w(2) 0] for rowIndex==0
236 * H=[0 w(0) 0 w(1) 0 w(2)] for rowIndex==1
237 * i.e., one row of the Kronecker product of weights_ with the
238 * MxM identity matrix. See also VectorEvaluationFunctor.
239 */
240 void calculateJacobian() {
241 H_.setZero(1, M_ * EvaluationFunctor::weights_.size());
242 for (int j = 0; j < EvaluationFunctor::weights_.size(); j++)
243 H_(0, rowIndex_ + j * M_) = EvaluationFunctor::weights_(j);
244 }
245
246 public:
249
251 VectorComponentFunctor(size_t M, size_t N, size_t i, double x)
252 : EvaluationFunctor(N, x), M_(M), rowIndex_(i) {
253 calculateJacobian();
254 }
255
257 VectorComponentFunctor(size_t M, size_t N, size_t i, double x, double a,
258 double b)
259 : EvaluationFunctor(N, x, a, b), M_(M), rowIndex_(i) {
260 calculateJacobian();
261 }
262
264 double apply(const Matrix& P,
266 if (H) *H = H_;
267 return P.row(rowIndex_) * EvaluationFunctor::weights_.transpose();
268 }
269
271 double operator()(const Matrix& P,
273 return apply(P, H);
274 }
275 };
276
290 template <class T>
292 inline constexpr static auto M = traits<T>::dimension;
293 using Base = VectorEvaluationFunctor;
294
295 public:
298
300 ManifoldEvaluationFunctor(size_t N, double x) : Base(M, N, x) {}
301
303 ManifoldEvaluationFunctor(size_t N, double x, double a, double b)
304 : Base(M, N, x, a, b) {}
305
307 T apply(const Matrix& P, OptionalJacobian</*MxMN*/ -1, -1> H = {}) const {
308 // Interpolate the M-dimensional vector to yield a vector in tangent space
309 Eigen::Matrix<double, M, 1> xi = Base::operator()(P, H);
310
311 // Now call retract with this M-vector, possibly with derivatives
312 Eigen::Matrix<double, M, M> D_result_xi;
313 T result = T::ChartAtOrigin::Retract(xi, H ? &D_result_xi : 0);
314
315 // Finally, if derivatives are asked, apply chain rule where H is Mx(M*N)
316 // derivative of interpolation and D_result_xi is MxM derivative of
317 // retract.
318 if (H) *H = D_result_xi * (*H);
319
320 // and return a T
321 return result;
322 }
323
325 T operator()(const Matrix& P,
327 return apply(P, H); // might call apply in derived
328 }
329 };
330
333 protected:
334 Weights weights_;
335
336 public:
339
340 DerivativeFunctorBase(size_t N, double x)
341 : weights_(DERIVED::DerivativeWeights(N, x)) {}
342
343 DerivativeFunctorBase(size_t N, double x, double a, double b)
344 : weights_(DERIVED::DerivativeWeights(N, x, a, b)) {}
345
346 void print(const std::string& s = "") const {
347 std::cout << s << (s != "" ? " " : "") << weights_ << std::endl;
348 }
349 };
350
359 public:
362
363 DerivativeFunctor(size_t N, double x) : DerivativeFunctorBase(N, x) {}
364
365 DerivativeFunctor(size_t N, double x, double a, double b)
366 : DerivativeFunctorBase(N, x, a, b) {}
367
368 double apply(const typename DERIVED::Parameters& p,
369 OptionalJacobian</*1xN*/ -1, -1> H = {}) const {
370 if (H) *H = this->weights_;
371 return (this->weights_ * p)(0);
372 }
374 double operator()(const typename DERIVED::Parameters& p,
376 return apply(p, H); // might call apply in derived
377 }
378 };
379
389 protected:
390 using Jacobian = Eigen::Matrix<double, /*MxMN*/ -1, -1>;
391 Jacobian H_;
392
393 size_t M_;
394
404 H_ = kroneckerProductIdentity(M_, this->weights_);
405 }
406
407 public:
410
412 VectorDerivativeFunctor(size_t M, size_t N, double x)
413 : DerivativeFunctorBase(N, x), M_(M) {
415 }
416
418 VectorDerivativeFunctor(size_t M, size_t N, double x, double a, double b)
419 : DerivativeFunctorBase(N, x, a, b), M_(M) {
421 }
422
423 Vector apply(const Matrix& P,
425 if (H) *H = H_;
426 return P.matrix() * this->weights_.transpose();
427 }
429 Vector operator()(const Matrix& P,
431 return apply(P, H);
432 }
433 };
434
443 protected:
444 using Jacobian = Eigen::Matrix<double, /*1xMN*/ 1, -1>;
445 Jacobian H_;
446
447 size_t M_;
448 size_t rowIndex_;
449
450 /*
451 * Calculate the `1*(M*N)` Jacobian of this functor with respect to
452 * the M*N parameter matrix `P`.
453 * We flatten assuming column-major order, e.g., if N=3 and M=2, we have
454 * H=[w(0) 0 w(1) 0 w(2) 0] for rowIndex==0
455 * H=[0 w(0) 0 w(1) 0 w(2)] for rowIndex==1
456 * i.e., one row of the Kronecker product of weights_ with the
457 * MxM identity matrix. See also VectorDerivativeFunctor.
458 */
459 void calculateJacobian() {
460 H_.setZero(1, M_ * this->weights_.size());
461 for (int j = 0; j < this->weights_.size(); j++)
462 H_(0, rowIndex_ + j * M_) = this->weights_(j);
463 }
464
465 public:
468
470 ComponentDerivativeFunctor(size_t M, size_t N, size_t i, double x)
471 : DerivativeFunctorBase(N, x), M_(M), rowIndex_(i) {
472 calculateJacobian();
473 }
474
476 ComponentDerivativeFunctor(size_t M, size_t N, size_t i, double x, double a,
477 double b)
478 : DerivativeFunctorBase(N, x, a, b), M_(M), rowIndex_(i) {
479 calculateJacobian();
480 }
481
482 double apply(const Matrix& P,
484 if (H) *H = H_;
485 return P.row(rowIndex_) * this->weights_.transpose();
486 }
487
488 double operator()(const Matrix& P,
490 return apply(P, H);
491 }
492 };
493};
494
495} // namespace gtsam
typedef and functions to augment Eigen's MatrixXd
Special class for optional Jacobian arguments.
Matrix kroneckerProductIdentity(size_t M, const Weights &w)
Function for computing the kronecker product of the 1*N Weight vector w with the MxM identity matrix ...
Definition Basis.cpp:23
Global functions in a separate testing namespace.
Definition chartTesting.h:28
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition Matrix.cpp:143
DecisionTree< L, Y > apply(const DecisionTree< L, Y > &f, const typename DecisionTree< L, Y >::Unary &op)
free versions of apply
Definition DecisionTree.h:467
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
CRTP Base class for function bases.
Definition Basis.h:90
static Matrix WeightMatrix(size_t N, const Vector &X, double a, double b)
Calculate weights for all x in vector X, with interval [a,b].
Definition Basis.h:113
static Matrix WeightMatrix(size_t N, const Vector &X)
Calculate weights for all x in vector X.
Definition Basis.h:97
EvaluationFunctor(size_t N, double x)
Constructor with interval [a,b].
Definition Basis.h:136
double operator()(const typename DERIVED::Parameters &p, OptionalJacobian<-1, -1 > H={}) const
c++ sugar
Definition Basis.h:151
EvaluationFunctor(size_t N, double x, double a, double b)
Constructor with interval [a,b].
Definition Basis.h:140
double apply(const typename DERIVED::Parameters &p, OptionalJacobian<-1, -1 > H={}) const
Regular 1D evaluation.
Definition Basis.h:144
EvaluationFunctor()
For serialization.
Definition Basis.h:133
VectorEvaluationFunctor(size_t M, size_t N, double x, double a, double b)
Constructor, with interval [a,b].
Definition Basis.h:197
VectorEvaluationFunctor(size_t M, size_t N, double x)
Default Constructor.
Definition Basis.h:191
Vector operator()(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:210
VectorEvaluationFunctor()
For serialization.
Definition Basis.h:188
Vector apply(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
M-dimensional evaluation.
Definition Basis.h:203
void calculateJacobian()
Calculate the M*(M*N) Jacobian of this functor with respect to the M*N parameter matrix P.
Definition Basis.h:182
double apply(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
Calculate component of component rowIndex_ of P.
Definition Basis.h:264
VectorComponentFunctor(size_t M, size_t N, size_t i, double x, double a, double b)
Construct with row index and interval.
Definition Basis.h:257
VectorComponentFunctor()
For serialization.
Definition Basis.h:248
VectorComponentFunctor(size_t M, size_t N, size_t i, double x)
Construct with row index.
Definition Basis.h:251
double operator()(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:271
ManifoldEvaluationFunctor(size_t N, double x, double a, double b)
Constructor, with interval [a,b].
Definition Basis.h:303
T operator()(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:325
T apply(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
Manifold evaluation.
Definition Basis.h:307
ManifoldEvaluationFunctor()
For serialization.
Definition Basis.h:297
ManifoldEvaluationFunctor(size_t N, double x)
Default Constructor.
Definition Basis.h:300
Base class for functors below that calculate derivative weights.
Definition Basis.h:332
DerivativeFunctorBase()
For serialization.
Definition Basis.h:338
DerivativeFunctor()
For serialization.
Definition Basis.h:361
double operator()(const typename DERIVED::Parameters &p, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:374
void calculateJacobian()
Calculate the M*(M*N) Jacobian of this functor with respect to the M*N parameter matrix P.
Definition Basis.h:403
VectorDerivativeFunctor()
For serialization.
Definition Basis.h:409
VectorDerivativeFunctor(size_t M, size_t N, double x, double a, double b)
Constructor, with optional interval [a,b].
Definition Basis.h:418
Vector operator()(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:429
VectorDerivativeFunctor(size_t M, size_t N, double x)
Default Constructor.
Definition Basis.h:412
ComponentDerivativeFunctor(size_t M, size_t N, size_t i, double x, double a, double b)
Construct with row index and interval.
Definition Basis.h:476
ComponentDerivativeFunctor(size_t M, size_t N, size_t i, double x)
Construct with row index.
Definition Basis.h:470
double apply(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
Calculate derivative of component rowIndex_ of F.
Definition Basis.h:482
double operator()(const Matrix &P, OptionalJacobian< -1, -1 > H={}) const
c++ sugar
Definition Basis.h:488
ComponentDerivativeFunctor()
For serialization.
Definition Basis.h:467