farm-ng-core
num_diff.h
Go to the documentation of this file.
1 // Copyright (c) 2011, Hauke Strasdat
2 // Copyright (c) 2012, Steven Lovegrove
3 // Copyright (c) 2021, farm-ng, inc.
4 //
5 // Use of this source code is governed by an MIT-style
6 // license that can be found in the LICENSE file or at
7 // https://opensource.org/licenses/MIT.
8 
9 /// @file
10 /// Numerical differentiation using finite differences
11 
12 #pragma once
13 
14 #include "sophus/common/common.h"
15 
16 #include <functional>
17 #include <type_traits>
18 #include <utility>
19 
20 namespace sophus {
21 
22 namespace details {
23 template <class TScalar>
24 class Curve {
25  public:
26  template <class TFn>
27  static auto numDiff(TFn curve, TScalar t, TScalar h) -> decltype(curve(t)) {
28  static_assert(
29  std::is_floating_point<TScalar>::value,
30  "Scalar must be a floating point type.");
31 
32  return (curve(t + h) - curve(t - h)) / (TScalar(2) * h);
33  }
34 };
35 
36 template <class TScalar, int kMatrixDim, int kM>
37 class VectorField {
38  public:
39  static auto numDiff(
40  std::function<Eigen::Vector<TScalar, kMatrixDim>(
41  Eigen::Vector<TScalar, kM>)> vector_field,
42  Eigen::Vector<TScalar, kM> const& a,
43  TScalar eps) -> Eigen::Matrix<TScalar, kMatrixDim, kM> {
44  static_assert(
45  std::is_floating_point<TScalar>::value,
46  "Scalar must be a floating point type.");
47  Eigen::Matrix<TScalar, kMatrixDim, kM> j;
48  Eigen::Vector<TScalar, kM> h;
49  h.setZero();
50  for (int i = 0; i < kM; ++i) {
51  h[i] = eps;
52  Eigen::Vector<TScalar, kMatrixDim> vfp = vector_field(a + h);
53  Eigen::Vector<TScalar, kMatrixDim> vfm = vector_field(a - h);
54 
55  j.col(i) = (vfp - vfm) / (TScalar(2) * eps);
56  h[i] = TScalar(0);
57  }
58 
59  return j;
60  }
61 };
62 
63 } // namespace details
64 
65 /// Calculates the derivative of a curve at a point ``t``.
66 ///
67 /// Here, a curve is a function from a Scalar to a Euclidean space. Thus, it
68 /// returns either a Scalar, a vector or a matrix.
69 ///
70 template <class TScalar, class TFn>
71 auto curveNumDiff(TFn curve, TScalar t, TScalar h = kEpsilonSqrt<TScalar>)
72  -> decltype(details::Curve<TScalar>::numDiff(std::move(curve), t, h)) {
73  return details::Curve<TScalar>::numDiff(std::move(curve), t, h);
74 }
75 
76 /// Calculates the derivative of a vector field at a point ``a``.
77 ///
78 /// Here, a vector field is a function from a vector space to another vector
79 /// space.
80 ///
81 template <
82  class TScalar,
83  int kMatrixDim,
84  int kM,
85  class TScalarOrVector,
86  class TFn>
88  TFn vector_field,
89  TScalarOrVector const& a,
90  TScalar eps = kEpsilonSqrt<TScalar>)
91  -> Eigen::Matrix<TScalar, kMatrixDim, kM> {
92  return details::VectorField<TScalar, kMatrixDim, kM>::numDiff(
93  vector_field, a, eps);
94 }
95 
96 } // namespace sophus
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
sophus::curveNumDiff
auto curveNumDiff(TFn curve, TScalar t, TScalar h=kEpsilonSqrt< TScalar >) -> decltype(details::Curve< TScalar >::numDiff(std::move(curve), t, h))
Calculates the derivative of a curve at a point t.
Definition: num_diff.h:71
sophus::vectorFieldNumDiff
auto vectorFieldNumDiff(TFn vector_field, TScalarOrVector const &a, TScalar eps=kEpsilonSqrt< TScalar >) -> Eigen::Matrix< TScalar, kMatrixDim, kM >
Calculates the derivative of a vector field at a point a.
Definition: num_diff.h:87
common.h