gtsam 4.1.1
gtsam
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
19#pragma once
20
21#include <gtsam/base/Matrix.h>
23#include <gtsam/basis/ParameterMatrix.h>
24
25#include <iostream>
26
68namespace gtsam {
69
70using Weights = Eigen::Matrix<double, 1, -1>; /* 1xN vector */
71
82template <size_t M>
83Matrix kroneckerProductIdentity(const Weights& w) {
84 Matrix result(M, w.cols() * M);
85 result.setZero();
86
87 for (int i = 0; i < w.cols(); i++) {
88 result.block(0, i * M, M, M).diagonal().array() = w(i);
89 }
90 return result;
91}
92
94template <typename DERIVED>
95class GTSAM_EXPORT Basis {
96 public:
102 static Matrix WeightMatrix(size_t N, const Vector& X) {
103 Matrix W(X.size(), N);
104 for (int i = 0; i < X.size(); i++)
105 W.row(i) = DERIVED::CalculateWeights(N, X(i));
106 return W;
107 }
108
118 static Matrix WeightMatrix(size_t N, const Vector& X, double a, double b) {
119 Matrix W(X.size(), N);
120 for (int i = 0; i < X.size(); i++)
121 W.row(i) = DERIVED::CalculateWeights(N, X(i), a, b);
122 return W;
123 }
124
133 protected:
134 Weights weights_;
135
136 public:
139
141 EvaluationFunctor(size_t N, double x)
142 : weights_(DERIVED::CalculateWeights(N, x)) {}
143
145 EvaluationFunctor(size_t N, double x, double a, double b)
146 : weights_(DERIVED::CalculateWeights(N, x, a, b)) {}
147
149 double apply(const typename DERIVED::Parameters& p,
150 OptionalJacobian<-1, -1> H = boost::none) const {
151 if (H) *H = weights_;
152 return (weights_ * p)(0);
153 }
154
156 double operator()(const typename DERIVED::Parameters& p,
157 OptionalJacobian<-1, -1> H = boost::none) const {
158 return apply(p, H); // might call apply in derived
159 }
160
161 void print(const std::string& s = "") const {
162 std::cout << s << (s != "" ? " " : "") << weights_ << std::endl;
163 }
164 };
165
172 template <int M>
174 protected:
175 using VectorM = Eigen::Matrix<double, M, 1>;
176 using Jacobian = Eigen::Matrix<double, /*MxMN*/ M, -1>;
177 Jacobian H_;
178
188 H_ = kroneckerProductIdentity<M>(this->weights_);
189 }
190
191 public:
192 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
193
196
198 VectorEvaluationFunctor(size_t N, double x) : EvaluationFunctor(N, x) {
199 calculateJacobian();
200 }
201
203 VectorEvaluationFunctor(size_t N, double x, double a, double b)
204 : EvaluationFunctor(N, x, a, b) {
205 calculateJacobian();
206 }
207
209 VectorM apply(const ParameterMatrix<M>& P,
210 OptionalJacobian</*MxN*/ -1, -1> H = boost::none) const {
211 if (H) *H = H_;
212 return P.matrix() * this->weights_.transpose();
213 }
214
217 OptionalJacobian</*MxN*/ -1, -1> H = boost::none) const {
218 return apply(P, H);
219 }
220 };
221
229 template <int M>
231 protected:
232 using Jacobian = Eigen::Matrix<double, /*1xMN*/ 1, -1>;
233 size_t rowIndex_;
234 Jacobian H_;
235
236 /*
237 * Calculate the `1*(M*N)` Jacobian of this functor with respect to
238 * the M*N parameter matrix `P`.
239 * We flatten assuming column-major order, e.g., if N=3 and M=2, we have
240 * H=[w(0) 0 w(1) 0 w(2) 0] for rowIndex==0
241 * H=[0 w(0) 0 w(1) 0 w(2)] for rowIndex==1
242 * i.e., one row of the Kronecker product of weights_ with the
243 * MxM identity matrix. See also VectorEvaluationFunctor.
244 */
245 void calculateJacobian(size_t N) {
246 H_.setZero(1, M * N);
247 for (int j = 0; j < EvaluationFunctor::weights_.size(); j++)
248 H_(0, rowIndex_ + j * M) = EvaluationFunctor::weights_(j);
249 }
250
251 public:
254
256 VectorComponentFunctor(size_t N, size_t i, double x)
257 : EvaluationFunctor(N, x), rowIndex_(i) {
258 calculateJacobian(N);
259 }
260
262 VectorComponentFunctor(size_t N, size_t i, double x, double a, double b)
263 : EvaluationFunctor(N, x, a, b), rowIndex_(i) {
264 calculateJacobian(N);
265 }
266
268 double apply(const ParameterMatrix<M>& P,
269 OptionalJacobian</*1xMN*/ -1, -1> H = boost::none) const {
270 if (H) *H = H_;
271 return P.row(rowIndex_) * EvaluationFunctor::weights_.transpose();
272 }
273
276 OptionalJacobian</*1xMN*/ -1, -1> H = boost::none) const {
277 return apply(P, H);
278 }
279 };
280
294 template <class T>
296 : public VectorEvaluationFunctor<traits<T>::dimension> {
297 enum { M = traits<T>::dimension };
299
300 public:
303
305 ManifoldEvaluationFunctor(size_t N, double x) : Base(N, x) {}
306
308 ManifoldEvaluationFunctor(size_t N, double x, double a, double b)
309 : Base(N, x, a, b) {}
310
313 OptionalJacobian</*MxMN*/ -1, -1> H = boost::none) const {
314 // Interpolate the M-dimensional vector to yield a vector in tangent space
315 Eigen::Matrix<double, M, 1> xi = Base::operator()(P, H);
316
317 // Now call retract with this M-vector, possibly with derivatives
318 Eigen::Matrix<double, M, M> D_result_xi;
319 T result = T::ChartAtOrigin::Retract(xi, H ? &D_result_xi : 0);
320
321 // Finally, if derivatives are asked, apply chain rule where H is Mx(M*N)
322 // derivative of interpolation and D_result_xi is MxM derivative of
323 // retract.
324 if (H) *H = D_result_xi * (*H);
325
326 // and return a T
327 return result;
328 }
329
331 T operator()(const ParameterMatrix<M>& P,
332 OptionalJacobian</*MxN*/ -1, -1> H = boost::none) const {
333 return apply(P, H); // might call apply in derived
334 }
335 };
336
339 protected:
340 Weights weights_;
341
342 public:
345
346 DerivativeFunctorBase(size_t N, double x)
347 : weights_(DERIVED::DerivativeWeights(N, x)) {}
348
349 DerivativeFunctorBase(size_t N, double x, double a, double b)
350 : weights_(DERIVED::DerivativeWeights(N, x, a, b)) {}
351
352 void print(const std::string& s = "") const {
353 std::cout << s << (s != "" ? " " : "") << weights_ << std::endl;
354 }
355 };
356
365 public:
368
369 DerivativeFunctor(size_t N, double x) : DerivativeFunctorBase(N, x) {}
370
371 DerivativeFunctor(size_t N, double x, double a, double b)
372 : DerivativeFunctorBase(N, x, a, b) {}
373
374 double apply(const typename DERIVED::Parameters& p,
375 OptionalJacobian</*1xN*/ -1, -1> H = boost::none) const {
376 if (H) *H = this->weights_;
377 return (this->weights_ * p)(0);
378 }
380 double operator()(const typename DERIVED::Parameters& p,
381 OptionalJacobian</*1xN*/ -1, -1> H = boost::none) const {
382 return apply(p, H); // might call apply in derived
383 }
384 };
385
394 template <int M>
396 protected:
397 using VectorM = Eigen::Matrix<double, M, 1>;
398 using Jacobian = Eigen::Matrix<double, /*MxMN*/ M, -1>;
399 Jacobian H_;
400
410 H_ = kroneckerProductIdentity<M>(this->weights_);
411 }
412
413 public:
414 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
415
418
420 VectorDerivativeFunctor(size_t N, double x) : DerivativeFunctorBase(N, x) {
421 calculateJacobian();
422 }
423
425 VectorDerivativeFunctor(size_t N, double x, double a, double b)
426 : DerivativeFunctorBase(N, x, a, b) {
427 calculateJacobian();
428 }
429
430 VectorM apply(const ParameterMatrix<M>& P,
431 OptionalJacobian</*MxMN*/ -1, -1> H = boost::none) const {
432 if (H) *H = H_;
433 return P.matrix() * this->weights_.transpose();
434 }
436 VectorM operator()(
437 const ParameterMatrix<M>& P,
438 OptionalJacobian</*MxMN*/ -1, -1> H = boost::none) const {
439 return apply(P, H);
440 }
441 };
442
450 template <int M>
452 protected:
453 using Jacobian = Eigen::Matrix<double, /*1xMN*/ 1, -1>;
454 size_t rowIndex_;
455 Jacobian H_;
456
457 /*
458 * Calculate the `1*(M*N)` Jacobian of this functor with respect to
459 * the M*N parameter matrix `P`.
460 * We flatten assuming column-major order, e.g., if N=3 and M=2, we have
461 * H=[w(0) 0 w(1) 0 w(2) 0] for rowIndex==0
462 * H=[0 w(0) 0 w(1) 0 w(2)] for rowIndex==1
463 * i.e., one row of the Kronecker product of weights_ with the
464 * MxM identity matrix. See also VectorDerivativeFunctor.
465 */
466 void calculateJacobian(size_t N) {
467 H_.setZero(1, M * N);
468 for (int j = 0; j < this->weights_.size(); j++)
469 H_(0, rowIndex_ + j * M) = this->weights_(j);
470 }
471
472 public:
475
477 ComponentDerivativeFunctor(size_t N, size_t i, double x)
478 : DerivativeFunctorBase(N, x), rowIndex_(i) {
479 calculateJacobian(N);
480 }
481
483 ComponentDerivativeFunctor(size_t N, size_t i, double x, double a, double b)
484 : DerivativeFunctorBase(N, x, a, b), rowIndex_(i) {
485 calculateJacobian(N);
486 }
488 double apply(const ParameterMatrix<M>& P,
489 OptionalJacobian</*1xMN*/ -1, -1> H = boost::none) const {
490 if (H) *H = H_;
491 return P.row(rowIndex_) * this->weights_.transpose();
492 }
495 OptionalJacobian</*1xMN*/ -1, -1> H = boost::none) const {
496 return apply(P, H);
497 }
498 };
499
500 // Vector version for MATLAB :-(
501 static double Derivative(double x, const Vector& p, //
502 OptionalJacobian</*1xN*/ -1, -1> H = boost::none) {
503 return DerivativeFunctor(x)(p.transpose(), H);
504 }
505};
506
507} // namespace gtsam
typedef and functions to augment Eigen's MatrixXd
Special class for optional Jacobian arguments.
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
Matrix kroneckerProductIdentity(const Weights &w)
Function for computing the kronecker product of the 1*N Weight vector w with the MxM identity matrix ...
Definition: Basis.h:83
void print(const Matrix &A, const string &s, ostream &stream)
print without optional string, must specify cout yourself
Definition: Matrix.cpp:155
DecisionTree< L, Y > apply(const DecisionTree< L, Y > &f, const typename DecisionTree< L, Y >::Unary &op)
free versions of apply
Definition: DecisionTree.h:218
A manifold defines a space in which there is a notion of a linear tangent space that can be centered ...
Definition: concepts.h:30
OptionalJacobian is an Eigen::Ref like class that can take be constructed using either a fixed size o...
Definition: OptionalJacobian.h:39
CRTP Base class for function bases.
Definition: Basis.h:95
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:118
static Matrix WeightMatrix(size_t N, const Vector &X)
Calculate weights for all x in vector X.
Definition: Basis.h:102
An instance of an EvaluationFunctor calculates f(x;p) at a given x, applied to Parameters p.
Definition: Basis.h:132
EvaluationFunctor(size_t N, double x)
Constructor with interval [a,b].
Definition: Basis.h:141
EvaluationFunctor(size_t N, double x, double a, double b)
Constructor with interval [a,b].
Definition: Basis.h:145
double apply(const typename DERIVED::Parameters &p, OptionalJacobian<-1, -1 > H=boost::none) const
Regular 1D evaluation.
Definition: Basis.h:149
EvaluationFunctor()
For serialization.
Definition: Basis.h:138
double operator()(const typename DERIVED::Parameters &p, OptionalJacobian<-1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:156
VectorEvaluationFunctor at a given x, applied to ParameterMatrix<M>.
Definition: Basis.h:173
VectorEvaluationFunctor(size_t N, double x, double a, double b)
Constructor, with interval [a,b].
Definition: Basis.h:203
EIGEN_MAKE_ALIGNED_OPERATOR_NEW VectorEvaluationFunctor()
For serialization.
Definition: Basis.h:195
VectorEvaluationFunctor(size_t N, double x)
Default Constructor.
Definition: Basis.h:198
void calculateJacobian()
Calculate the M*(M*N) Jacobian of this functor with respect to the M*N parameter matrix P.
Definition: Basis.h:187
VectorM operator()(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:216
VectorM apply(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
M-dimensional evaluation.
Definition: Basis.h:209
Given a M*N Matrix of M-vectors at N polynomial points, an instance of VectorComponentFunctor compute...
Definition: Basis.h:230
double operator()(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:275
VectorComponentFunctor()
For serialization.
Definition: Basis.h:253
VectorComponentFunctor(size_t N, size_t i, double x)
Construct with row index.
Definition: Basis.h:256
VectorComponentFunctor(size_t N, size_t i, double x, double a, double b)
Construct with row index and interval.
Definition: Basis.h:262
double apply(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
Calculate component of component rowIndex_ of P.
Definition: Basis.h:268
Manifold EvaluationFunctor at a given x, applied to ParameterMatrix<M>.
Definition: Basis.h:296
ManifoldEvaluationFunctor(size_t N, double x, double a, double b)
Constructor, with interval [a,b].
Definition: Basis.h:308
ManifoldEvaluationFunctor()
For serialization.
Definition: Basis.h:302
ManifoldEvaluationFunctor(size_t N, double x)
Default Constructor.
Definition: Basis.h:305
Base class for functors below that calculate derivative weights.
Definition: Basis.h:338
DerivativeFunctorBase()
For serialization.
Definition: Basis.h:344
An instance of a DerivativeFunctor calculates f'(x;p) at a given x, applied to Parameters p.
Definition: Basis.h:364
DerivativeFunctor()
For serialization.
Definition: Basis.h:367
double operator()(const typename DERIVED::Parameters &p, OptionalJacobian< -1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:380
VectorDerivativeFunctor at a given x, applied to ParameterMatrix<M>.
Definition: Basis.h:395
void calculateJacobian()
Calculate the M*(M*N) Jacobian of this functor with respect to the M*N parameter matrix P.
Definition: Basis.h:409
VectorDerivativeFunctor(size_t N, double x, double a, double b)
Constructor, with optional interval [a,b].
Definition: Basis.h:425
VectorM operator()(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:436
EIGEN_MAKE_ALIGNED_OPERATOR_NEW VectorDerivativeFunctor()
For serialization.
Definition: Basis.h:417
VectorDerivativeFunctor(size_t N, double x)
Default Constructor.
Definition: Basis.h:420
Given a M*N Matrix of M-vectors at N polynomial points, an instance of ComponentDerivativeFunctor com...
Definition: Basis.h:451
ComponentDerivativeFunctor(size_t N, size_t i, double x)
Construct with row index.
Definition: Basis.h:477
double operator()(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
c++ sugar
Definition: Basis.h:494
ComponentDerivativeFunctor()
For serialization.
Definition: Basis.h:474
ComponentDerivativeFunctor(size_t N, size_t i, double x, double a, double b)
Construct with row index and interval.
Definition: Basis.h:483
double apply(const ParameterMatrix< M > &P, OptionalJacobian< -1, -1 > H=boost::none) const
Calculate derivative of component rowIndex_ of F.
Definition: Basis.h:488
A matrix abstraction of MxN values at the Basis points.
Definition: ParameterMatrix.h:38