farm-ng-core
sim_mat_w.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 #pragma once
10 
11 #include "sophus/common/common.h"
12 
13 namespace sophus {
14 namespace details {
15 
16 template <class TScalar, int kMatrixDim>
17 auto calcW(
18  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const &omega,
19  TScalar const theta,
20  TScalar const sigma) -> Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> {
21  using std::abs;
22  using std::cos;
23  using std::exp;
24  using std::sin;
25  static Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const kI =
26  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim>::Identity();
27  static TScalar const kOne(1);
28  static TScalar const kHalf(0.5);
29  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const omega2 = omega * omega;
30  TScalar const scale = exp(sigma);
31  TScalar a;
32 
33  TScalar b;
34 
35  TScalar c;
36  if (abs(sigma) < kEpsilon<TScalar>) {
37  c = kOne;
38  if (abs(theta) < kEpsilon<TScalar>) {
39  a = kHalf;
40  b = TScalar(1. / 6.);
41  } else {
42  TScalar theta_sq = theta * theta;
43  a = (kOne - cos(theta)) / theta_sq;
44  b = (theta - sin(theta)) / (theta_sq * theta);
45  }
46  } else {
47  c = (scale - kOne) / sigma;
48  if (abs(theta) < kEpsilon<TScalar>) {
49  TScalar sigma_sq = sigma * sigma;
50  a = ((sigma - kOne) * scale + kOne) / sigma_sq;
51  b = (scale * kHalf * sigma_sq + scale - kOne - sigma * scale) /
52  (sigma_sq * sigma);
53  } else {
54  TScalar theta_sq = theta * theta;
55  TScalar tmp_a = scale * sin(theta);
56  TScalar tmp_b = scale * cos(theta);
57  TScalar tmp_c = theta_sq + sigma * sigma;
58  a = (tmp_a * sigma + (kOne - tmp_b) * theta) / (theta * tmp_c);
59  b = (c - ((tmp_b - kOne) * sigma + tmp_a * theta) / (tmp_c)) * kOne /
60  (theta_sq);
61  }
62  }
63  return a * omega + b * omega2 + c * kI;
64 }
65 
66 template <class TScalar>
67 void calcWDerivatives(
68  TScalar const theta,
69  TScalar const sigma,
70  TScalar &a_out,
71  TScalar &b_out,
72  TScalar &c_out,
73  TScalar &a_dsigma_out,
74  TScalar &b_dsigma_out,
75  TScalar &c_dsigma_out,
76  TScalar &a_dtheta_out,
77  TScalar &b_dtheta_out) {
78  using std::abs;
79  using std::cos;
80  using std::exp;
81  using std::sin;
82  using Scalar = TScalar;
83  static Scalar const kZero(0.0);
84  static Scalar const kOne(1.0);
85  static Scalar const kHalf(0.5);
86  static Scalar const kTwo(2.0);
87  static Scalar const kThree(3.0);
88  Scalar const theta_sq = theta * theta;
89  Scalar const theta_c = theta * theta_sq;
90  Scalar const sin_theta = sin(theta);
91  Scalar const cos_theta = cos(theta);
92 
93  Scalar const scale = exp(sigma);
94  Scalar const sigma_sq = sigma * sigma;
95  Scalar const sigma_c = sigma * sigma_sq;
96 
97  if (abs(sigma) < kEpsilon<TScalar>) {
98  c_out = kOne;
99  c_dsigma_out = kHalf;
100  if (abs(theta) < kEpsilon<TScalar>) {
101  a_out = kHalf;
102  b_out = TScalar(1. / 6.);
103  a_dtheta_out = a_dsigma_out = kZero;
104  b_dtheta_out = b_dsigma_out = kZero;
105  } else {
106  a_out = (kOne - cos_theta) / theta_sq;
107  b_out = (theta - sin_theta) / theta_c;
108  a_dtheta_out = (theta * sin_theta + kTwo * cos_theta - kTwo) / theta_c;
109  b_dtheta_out = -(kTwo * theta - kThree * sin_theta + theta * cos_theta) /
110  (theta_c * theta);
111  a_dsigma_out = (sin_theta - theta * cos_theta) / theta_c;
112  b_dsigma_out =
113  (kHalf - (cos_theta + theta * sin_theta - kOne) / theta_sq) /
114  theta_sq;
115  }
116  } else {
117  c_out = (scale - kOne) / sigma;
118  c_dsigma_out = (scale * (sigma - kOne) + kOne) / sigma_sq;
119  if (abs(theta) < kEpsilon<TScalar>) {
120  a_out = ((sigma - kOne) * scale + kOne) / sigma_sq;
121  b_out =
122  (scale * kHalf * sigma_sq + scale - kOne - sigma * scale) / sigma_c;
123  a_dsigma_out =
124  (scale * (sigma_sq - kTwo * sigma + kTwo) - kTwo) / sigma_c;
125  b_dsigma_out = (scale * (kHalf * sigma_c - (kOne + kHalf) * sigma_sq +
126  kThree * sigma - kThree) +
127  kThree) /
128  (sigma_c * sigma);
129  a_dtheta_out = b_dtheta_out = kZero;
130  } else {
131  Scalar const a = scale * sin_theta;
132  Scalar const b = scale * cos_theta;
133  Scalar const b_one = b - kOne;
134  Scalar const theta_b_one = theta * b_one;
135  Scalar const c = theta_sq + sigma_sq;
136  Scalar const c_sq = c * c;
137  Scalar const theta_sq_c = theta_sq * c;
138  Scalar const a_theta = theta * a;
139  Scalar const b_theta = theta * b;
140  Scalar const c_theta = theta * c;
141  Scalar const a_sigma = sigma * a;
142  Scalar const b_sigma = sigma * b;
143  Scalar const two_sigma = sigma * kTwo;
144  Scalar const two_theta = theta * kTwo;
145  Scalar const sigma_b_one = sigma * b_one;
146 
147  a_out = (a_sigma - theta_b_one) / c_theta;
148  a_dtheta_out = (kTwo * (theta_b_one - a_sigma)) / c_sq +
149  (b_sigma - b + a_theta + kOne) / c_theta +
150  (theta_b_one - a_sigma) / theta_sq_c;
151  a_dsigma_out = (a - b_theta + a_sigma) / c_theta -
152  (two_sigma * (theta - b_theta + a_sigma)) / (theta * c_sq);
153 
154  b_out = (c_out - (sigma_b_one + a_theta) / (c)) * kOne / (theta_sq);
155  b_dtheta_out =
156  ((two_theta * (b_sigma - sigma + a_theta)) / c_sq -
157  ((a + b_theta - a_sigma)) / c) /
158  theta_sq -
159  (kTwo * ((scale - kOne) / sigma - (b_sigma - sigma + a_theta) / c)) /
160  theta_c;
161  b_dsigma_out =
162  -((b_sigma + a_theta + b_one) / c + (scale - kOne) / sigma_sq -
163  (two_sigma * (sigma_b_one + a_theta)) / c_sq - scale / sigma) /
164  theta_sq;
165  }
166  }
167 }
168 
169 template <class TScalar, int kMatrixDim>
170 auto calcWInv(
171  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const &omega,
172  TScalar const theta,
173  TScalar const sigma,
174  TScalar const scale) -> Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> {
175  using std::abs;
176  using std::cos;
177  using std::sin;
178  static Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const kI =
179  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim>::Identity();
180  static TScalar const kHalf(0.5);
181  static TScalar const kOne(1);
182  static TScalar const kTwo(2);
183  Eigen::Matrix<TScalar, kMatrixDim, kMatrixDim> const omega2 = omega * omega;
184  TScalar const scale_sq = scale * scale;
185  TScalar const theta_sq = theta * theta;
186  TScalar const sin_theta = sin(theta);
187  TScalar const cos_theta = cos(theta);
188 
189  TScalar a;
190 
191  TScalar b;
192 
193  TScalar c;
194  if (abs(sigma * sigma) < kEpsilon<TScalar>) {
195  c = kOne - kHalf * sigma;
196  a = -kHalf;
197  if (abs(theta_sq) < kEpsilon<TScalar>) {
198  b = TScalar(1. / 12.);
199  } else {
200  b = (theta * sin_theta + kTwo * cos_theta - kTwo) /
201  (kTwo * theta_sq * (cos_theta - kOne));
202  }
203  } else {
204  TScalar const scale_cu = scale_sq * scale;
205  c = sigma / (scale - kOne);
206  if (abs(theta_sq) < kEpsilon<TScalar>) {
207  a = (-sigma * scale + scale - kOne) / ((scale - kOne) * (scale - kOne));
208  b = (scale_sq * sigma - kTwo * scale_sq + scale * sigma + kTwo * scale) /
209  (kTwo * scale_cu - TScalar(6) * scale_sq + TScalar(6) * scale - kTwo);
210  } else {
211  TScalar const s_sin_theta = scale * sin_theta;
212  TScalar const s_cos_theta = scale * cos_theta;
213  a = (theta * s_cos_theta - theta - sigma * s_sin_theta) /
214  (theta * (scale_sq - kTwo * s_cos_theta + kOne));
215  b = -scale *
216  (theta * s_sin_theta - theta * sin_theta + sigma * s_cos_theta -
217  scale * sigma + sigma * cos_theta - sigma) /
218  (theta_sq * (scale_cu - kTwo * scale * s_cos_theta - scale_sq +
219  kTwo * s_cos_theta + scale - kOne));
220  }
221  }
222  return a * omega + b * omega2 + c * kI;
223 }
224 
225 } // namespace details
226 } // namespace sophus
sophus
Image MutImage, owning images types.
Definition: num_diff.h:20
common.h