Geomi
SO3_Algebra.hpp
1 #ifndef DEF_COMMON_SO3_ALGEBRA
2 #define DEF_COMMON_SO3_ALGEBRA
3 
4 #include <string>
5 
6 #include <Eigen/Dense>
7 #include <Eigen/Geometry>
8 
9 //#include "Common_SO3_Group.hpp"
10 //#include "include/Common/NOXVector.hpp"
11 //#include "include/Common/Utils.hpp"
12 
13 namespace SO3
14 {
15 
22 template <typename T_SCALAR_TYPE>
23 class Algebra : public LieAlgebraBase< Algebra<T_SCALAR_TYPE>,
24  Group<T_SCALAR_TYPE>,
25  3,
26  T_SCALAR_TYPE>
27 {
28 protected:
29  Eigen::Matrix<T_SCALAR_TYPE,3,1> m_v;
30 
31 public:
33  : m_v(Eigen::Matrix<T_SCALAR_TYPE,3,1>::Zero())
34  { }
35 
36  Algebra<T_SCALAR_TYPE> (const Eigen::Matrix<T_SCALAR_TYPE,3,1>& v)
37  : m_v(v)
38  { }
39 
40  Algebra<T_SCALAR_TYPE> (const T_SCALAR_TYPE a, const T_SCALAR_TYPE b, const T_SCALAR_TYPE c)
41  : m_v(Eigen::Matrix<T_SCALAR_TYPE,3,1>(a,b,c))
42  { }
43 
44  // Removed because ambiguity with Algebra<T_SCALAR_TYPE> (const Eigen::Matrix<T_SCALAR_TYPE,3,1>& v)
45  /* Algebra<T_SCALAR_TYPE> (const NOXVector<3> v)
46  : m_v(v)
47  { }
48  */
49 
50  /* Group operations */
51 
56  inverse ( ) const
57  {
58  Algebra<T_SCALAR_TYPE> a(-m_v);
59  return a;
60  }
61 
62  void
63  operator+= (const Algebra<T_SCALAR_TYPE>& g)
64  { m_v += g.v(); }
65 
71  {
72  Algebra<T_SCALAR_TYPE> res(Eigen::Matrix<T_SCALAR_TYPE,3,1>::Zero());
73  return res;
74  }
75 
76  using LieAlgebraBase<Algebra<T_SCALAR_TYPE>,Group<T_SCALAR_TYPE>,3,T_SCALAR_TYPE>::operator+;
77  using LieAlgebraBase<Algebra<T_SCALAR_TYPE>,Group<T_SCALAR_TYPE>,3,T_SCALAR_TYPE>::operator-;
78 
79  /* Vector space operations */
80 
81  void
82  operator*= (T_SCALAR_TYPE s)
83  { m_v *= s; }
84 
89  using LieAlgebraBase<Algebra<T_SCALAR_TYPE>,Group<T_SCALAR_TYPE>,3,T_SCALAR_TYPE>::operator*;
90  /*
91  Algebra<T_SCALAR_TYPE>
92  operator* (const T_SCALAR_TYPE& s) const
93  {
94  return LieAlgebraBase<Algebra<T_SCALAR_TYPE>,Group<T_SCALAR_TYPE>,3,T_SCALAR_TYPE>::operator*(s);
95  }
96  */
97 
98  /* Lie algebra operations */
99 
107  { return this->m_v.cross(g.v()); }
108 
110  Ad (const Group<T_SCALAR_TYPE>& g) const
111  { return Algebra<T_SCALAR_TYPE>(g.toRotationMatrix()*this->toVector()); }
112 
114  Ad_star (const Group<T_SCALAR_TYPE>& g) const
115  { return Algebra<T_SCALAR_TYPE>(g.toRotationMatrix().transpose()*this->toVector()); }
116 
117  /* Other operations */
118 
125  Eigen::Matrix<T_SCALAR_TYPE,3,1>
126  operator* (const Eigen::Matrix<T_SCALAR_TYPE,3,1>& vec) const
127  { return m_v.cross(vec); }
128 
129  /* Accessors */
130 
131  Eigen::Matrix<T_SCALAR_TYPE,3,1>
132  v ( ) const
133  { return m_v; }
134 
135  void
136  v (const Eigen::AngleAxis<T_SCALAR_TYPE>& aa)
137  { m_v = aa.angle()*aa.axis(); }
138 
139  void
140  v (const Eigen::Matrix<T_SCALAR_TYPE,3,1>& vec)
141  { m_v = vec; }
142 
143  T_SCALAR_TYPE const&
144  operator[] (size_t index) const
145  { return m_v[index]; }
146 
147  T_SCALAR_TYPE&
148  operator[] (size_t index)
149  { return m_v[index]; }
150 
151  // Les fonctions de normalisation sont-elles vraiment utiles ?
152  void
153  normalize ( )
154  { m_v.normalize(); }
155 
157  normalized ( ) const
158  {
159  Algebra<T_SCALAR_TYPE> res(*this);
160  res.normalize();
161  return res;
162  }
163 
164  T_SCALAR_TYPE
165  norm ( ) const
166  { return m_v.norm(); }
167 
168  T_SCALAR_TYPE
169  angle ( ) const
170  { return m_v.norm(); }
171 
172  Eigen::Matrix<T_SCALAR_TYPE,3,1>
173  axis ( ) const
174  { return m_v.normalized(); }
175 
181  Group<T_SCALAR_TYPE>
182  exp ( ) const
183  {
184  T_SCALAR_TYPE a = m_v.norm()/2.0;
185  Eigen::Matrix<T_SCALAR_TYPE,4,1> V;
186  //V << cos(a) << sin(a)*m_v.normalized();
187  //return Group<T>(V);
188  return Group<T_SCALAR_TYPE>(Eigen::AngleAxis<T_SCALAR_TYPE>(cos(a),sin(a)*m_v.normalized()));
189  }
190 
191  Eigen::Matrix<T_SCALAR_TYPE,3,3>
192  partialExp (const unsigned int i) const
193  {
194  T_SCALAR_TYPE nm = this->norm();
195  Eigen::Matrix<T_SCALAR_TYPE,3,3> K = (this->normalized()).toRotationMatrix();
196  T_SCALAR_TYPE c = cos(nm), s = sin(nm);
197 
198  Eigen::Matrix<T_SCALAR_TYPE,3,3> M = Algebra<T_SCALAR_TYPE>::GeneratorMatrix(i);
199  Eigen::Matrix<T_SCALAR_TYPE,3,3> dexpdw;
200 
201  if (isZero<T_SCALAR_TYPE>(nm))
202  dexpdw = M;
203  else
204  dexpdw = (c-(s/nm))*((*this)[i]*(1.0/nm))*K + (s/nm)*M + (s+(1.0-c)*(2.0/nm))*((*this)[i]*(1.0/nm))*K*K + ((1-c)/nm)*(M*K+K*M);
205 
206  return dexpdw;
207  }
208 
210  computeDExpRInv (const Algebra<T_SCALAR_TYPE>& y, unsigned int order_p = 0) const
211  {
212  Algebra<T_SCALAR_TYPE> res = y;
213  if (order_p>0) {
215  for (int i=0; i<order_p; i++) {
216  A = this->bracket(A);
217  res += BERNOULLI_NUMBERS[i+1]*A;
218  }
219  }
220  return res;
221  }
222 
228  Group<T_SCALAR_TYPE>
229  cay ( ) const
230  {
231  T_SCALAR_TYPE n = m_v.norm(),
232  den = 4.0+n*n;
233  //Eigen::Matrix<T_SCALAR_TYPE,4,1> V;
234  //V << 1.0 - 2.0*n*n/den << m_v.normalized() * 4.0*n/den;
235  //return Group<T>(V);
236  //return Group<T_SCALAR_TYPE>(Eigen::AngleAxis<T_SCALAR_TYPE>(1.0-2.0*n*n/den,m_v.normalized()*4.0*n/den));
237  Eigen::Matrix<T_SCALAR_TYPE,3,3> W = this->toRotationMatrix();
238  Eigen::Matrix<T_SCALAR_TYPE,3,3> M =
239  Eigen::Matrix<T_SCALAR_TYPE,3,3>::Identity()
240  + (4.0/den)*(W+0.5*W*W);
241  return Group<T_SCALAR_TYPE>(M);
242  }
243 
245  cay_inv (const Group<T_SCALAR_TYPE>& g)
246  { return fromRotationMatrix(2.0*(g.toRotationMatrix()-Eigen::Matrix<T_SCALAR_TYPE,3,3>::Identity())*(g.toRotationMatrix()+Eigen::Matrix<T_SCALAR_TYPE,3,3>::Identity()).inverse()); }
247 
248  Eigen::Matrix<T_SCALAR_TYPE,3,3>
249  dCayRInv () const
250  { return Eigen::Matrix<T_SCALAR_TYPE,3,3>::Identity()-0.5*this->toRotationMatrix()+0.25*this->toVector()*(this->toVector().transpose()); }
251 
253  dCayRInv (const Algebra<T_SCALAR_TYPE>& g) const
254  { return Algebra<T_SCALAR_TYPE>(this->dCayRInv()*g.toVector()); }
255 
259  Eigen::AngleAxis<T_SCALAR_TYPE>
260  toAngleAxis ( ) const
261  { return Eigen::AngleAxis<T_SCALAR_TYPE>(m_v.norm(),m_v.normalized()); }
262 
263  Eigen::Matrix<T_SCALAR_TYPE,3,3>
264  toRotationMatrix ( ) const
265  {
266  Eigen::Matrix<T_SCALAR_TYPE,3,3> mat;
267  mat << T_SCALAR_TYPE(0), -m_v[2], m_v[1],
268  m_v[2], T_SCALAR_TYPE(0), -m_v[0],
269  -m_v[1], m_v[0], T_SCALAR_TYPE(0);
270  return mat;
271  }
272 
274  fromRotationMatrix (const Eigen::Matrix<T_SCALAR_TYPE,3,3>& m)
275  {
276  return Algebra<T_SCALAR_TYPE>(m(2,1),m(0,2),m(1,0));
277  }
278 
279  Eigen::Matrix<T_SCALAR_TYPE,3,1>
280  toVector ( ) const
281  { return m_v; }
282 
284  toNOXVector ( ) const
285  { return NOXVector<3>(m_v); }
286 
299  static Eigen::Matrix<T_SCALAR_TYPE,3,3>
300  GeneratorMatrix (int const i)
301  {
302  Eigen::Matrix<T_SCALAR_TYPE,3,3> res(Eigen::Matrix<T_SCALAR_TYPE,3,3>::Zero());
303  if (i == 0) { res(1,2) = T_SCALAR_TYPE(-1); res(2,1) = T_SCALAR_TYPE(1); }
304  else if (i == 1) { res(0,2) = T_SCALAR_TYPE(1); res(2,0) = T_SCALAR_TYPE(-1); }
305  else { res(0,1) = T_SCALAR_TYPE(-1); res(1,0) = T_SCALAR_TYPE(1); }
306  return res;
307  }
308 
309  static Eigen::Matrix<T_SCALAR_TYPE,3,1>
310  GeneratorVector (int const i)
311  {
312  Eigen::Matrix<T_SCALAR_TYPE,3,1> res(Eigen::Matrix<T_SCALAR_TYPE,3,1>::Zero());
313  res(i) = T_SCALAR_TYPE(1);
314  return res;
315  }
316 
318  Generator (int const i)
319  { return Algebra(Algebra::GeneratorVector(i)); }
320 
322  Zero ( )
323  { return Algebra(Eigen::Matrix<T_SCALAR_TYPE,3,1>::Zero()); }
324 };
325 
326 } // namespace SO3
327 
328 template <typename T_SCALAR_TYPE>
329 std::ostream&
330 operator<< (std::ostream& stream, SO3::Algebra<T_SCALAR_TYPE> const& g)
331 {
332  stream << g.v();
333  return stream;
334 }
335 
336 template <typename T_SCALAR_TYPE>
338 operator* (T_SCALAR_TYPE s, const SO3::Algebra<T_SCALAR_TYPE> g)
339 { return g*s; }
340 
341 #endif
static Eigen::Matrix< T_SCALAR_TYPE, 3, 3 > GeneratorMatrix(int const i)
Definition: SO3_Algebra.hpp:300
static Algebra< T_SCALAR_TYPE > Identity()
Definition: SO3_Algebra.hpp:70
Algebra< T_SCALAR_TYPE > inverse() const
Definition: SO3_Algebra.hpp:56
Group< T_SCALAR_TYPE > exp() const
Definition: SO3_Algebra.hpp:182
Eigen::Matrix< T_SCALAR_TYPE, 3, 3 > toRotationMatrix() const
Definition: SO3_Group.hpp:169
Definition: SO3_Group.hpp:17
Group< T_SCALAR_TYPE > cay() const
Definition: SO3_Algebra.hpp:229
Definition: SO3_Algebra.hpp:13
Eigen::AngleAxis< T_SCALAR_TYPE > toAngleAxis() const
Definition: SO3_Algebra.hpp:260
Algebra< T_SCALAR_TYPE > bracket(const Algebra< T_SCALAR_TYPE > &g) const
Definition: SO3_Algebra.hpp:106
Definition: SO3_Algebra.hpp:23
Definition: LieAlgebraBase.hpp:29
Eigen::Matrix< T_SCALAR_TYPE, 3, 1 > operator*(const Eigen::Matrix< T_SCALAR_TYPE, 3, 1 > &vec) const
Definition: SO3_Algebra.hpp:126
Definition: NOXVector.hpp:14