OrthoMethods.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_ORTHOMETHODS_H
12 #define EIGEN_ORTHOMETHODS_H
13 
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 // Vector3 version (default)
21 template<typename Derived, typename OtherDerived, int Size>
22 struct cross_impl
23 {
24  typedef typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar;
26 
27  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
28  return_type run(const MatrixBase<Derived>& first, const MatrixBase<OtherDerived>& second)
29  {
32 
33  // Note that there is no need for an expression here since the compiler
34  // optimize such a small temporary very well (even within a complex expression)
35  typename internal::nested_eval<Derived,2>::type lhs(first.derived());
36  typename internal::nested_eval<OtherDerived,2>::type rhs(second.derived());
37  return return_type(
38  numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
39  numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
40  numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0))
41  );
42  }
43 };
44 
45 // Vector2 version
46 template<typename Derived, typename OtherDerived>
47 struct cross_impl<Derived, OtherDerived, 2>
48 {
49  typedef typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType Scalar;
50  typedef Scalar return_type;
51 
52  static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
53  return_type run(const MatrixBase<Derived>& first, const MatrixBase<OtherDerived>& second)
54  {
57  typename internal::nested_eval<Derived,2>::type lhs(first.derived());
58  typename internal::nested_eval<OtherDerived,2>::type rhs(second.derived());
59  return numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0));
60  }
61 };
62 
63 } // end namespace internal
64 
84 template<typename Derived>
85 template<typename OtherDerived>
86 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
87 #ifndef EIGEN_PARSED_BY_DOXYGEN
88 typename internal::cross_impl<Derived, OtherDerived>::return_type
89 #else
90 inline std::conditional_t<SizeAtCompileTime==2, Scalar, PlainObject>
91 #endif
93 {
94  return internal::cross_impl<Derived, OtherDerived>::run(*this, other);
95 }
96 
97 namespace internal {
98 
99 template< int Arch,typename VectorLhs,typename VectorRhs,
100  typename Scalar = typename VectorLhs::Scalar,
101  bool Vectorizable = bool((VectorLhs::Flags&VectorRhs::Flags)&PacketAccessBit)>
102 struct cross3_impl {
103  EIGEN_DEVICE_FUNC static inline typename internal::plain_matrix_type<VectorLhs>::type
104  run(const VectorLhs& lhs, const VectorRhs& rhs)
105  {
106  return typename internal::plain_matrix_type<VectorLhs>::type(
107  numext::conj(lhs.coeff(1) * rhs.coeff(2) - lhs.coeff(2) * rhs.coeff(1)),
108  numext::conj(lhs.coeff(2) * rhs.coeff(0) - lhs.coeff(0) * rhs.coeff(2)),
109  numext::conj(lhs.coeff(0) * rhs.coeff(1) - lhs.coeff(1) * rhs.coeff(0)),
110  0
111  );
112  }
113 };
114 
115 }
116 
126 template<typename Derived>
127 template<typename OtherDerived>
130 {
133 
134  typedef typename internal::nested_eval<Derived,2>::type DerivedNested;
135  typedef typename internal::nested_eval<OtherDerived,2>::type OtherDerivedNested;
136  DerivedNested lhs(derived());
137  OtherDerivedNested rhs(other.derived());
138 
139  return internal::cross3_impl<Architecture::Target,
142 }
143 
153 template<typename ExpressionType, int Direction>
154 template<typename OtherDerived>
158 {
160  EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
161  YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
162 
163  typename internal::nested_eval<ExpressionType,2>::type mat(_expression());
164  typename internal::nested_eval<OtherDerived,2>::type vec(other.derived());
165 
166  CrossReturnType res(_expression().rows(),_expression().cols());
167  if(Direction==Vertical)
168  {
169  eigen_assert(CrossReturnType::RowsAtCompileTime==3 && "the matrix must have exactly 3 rows");
170  res.row(0) = (mat.row(1) * vec.coeff(2) - mat.row(2) * vec.coeff(1)).conjugate();
171  res.row(1) = (mat.row(2) * vec.coeff(0) - mat.row(0) * vec.coeff(2)).conjugate();
172  res.row(2) = (mat.row(0) * vec.coeff(1) - mat.row(1) * vec.coeff(0)).conjugate();
173  }
174  else
175  {
176  eigen_assert(CrossReturnType::ColsAtCompileTime==3 && "the matrix must have exactly 3 columns");
177  res.col(0) = (mat.col(1) * vec.coeff(2) - mat.col(2) * vec.coeff(1)).conjugate();
178  res.col(1) = (mat.col(2) * vec.coeff(0) - mat.col(0) * vec.coeff(2)).conjugate();
179  res.col(2) = (mat.col(0) * vec.coeff(1) - mat.col(1) * vec.coeff(0)).conjugate();
180  }
181  return res;
182 }
183 
184 namespace internal {
185 
186 template<typename Derived, int Size = Derived::SizeAtCompileTime>
187 struct unitOrthogonal_selector
188 {
189  typedef typename plain_matrix_type<Derived>::type VectorType;
190  typedef typename traits<Derived>::Scalar Scalar;
191  typedef typename NumTraits<Scalar>::Real RealScalar;
192  typedef Matrix<Scalar,2,1> Vector2;
194  static inline VectorType run(const Derived& src)
195  {
196  VectorType perp = VectorType::Zero(src.size());
197  Index maxi = 0;
198  Index sndi = 0;
199  src.cwiseAbs().maxCoeff(&maxi);
200  if (maxi==0)
201  sndi = 1;
202  RealScalar invnm = RealScalar(1)/(Vector2() << src.coeff(sndi),src.coeff(maxi)).finished().norm();
203  perp.coeffRef(maxi) = -numext::conj(src.coeff(sndi)) * invnm;
204  perp.coeffRef(sndi) = numext::conj(src.coeff(maxi)) * invnm;
205 
206  return perp;
207  }
208 };
209 
210 template<typename Derived>
211 struct unitOrthogonal_selector<Derived,3>
212 {
213  typedef typename plain_matrix_type<Derived>::type VectorType;
214  typedef typename traits<Derived>::Scalar Scalar;
215  typedef typename NumTraits<Scalar>::Real RealScalar;
217  static inline VectorType run(const Derived& src)
218  {
219  VectorType perp;
220  /* Let us compute the crossed product of *this with a vector
221  * that is not too close to being colinear to *this.
222  */
223 
224  /* unless the x and y coords are both close to zero, we can
225  * simply take ( -y, x, 0 ) and normalize it.
226  */
227  if((!isMuchSmallerThan(src.x(), src.z()))
228  || (!isMuchSmallerThan(src.y(), src.z())))
229  {
230  RealScalar invnm = RealScalar(1)/src.template head<2>().norm();
231  perp.coeffRef(0) = -numext::conj(src.y())*invnm;
232  perp.coeffRef(1) = numext::conj(src.x())*invnm;
233  perp.coeffRef(2) = 0;
234  }
235  /* if both x and y are close to zero, then the vector is close
236  * to the z-axis, so it's far from colinear to the x-axis for instance.
237  * So we take the crossed product with (1,0,0) and normalize it.
238  */
239  else
240  {
241  RealScalar invnm = RealScalar(1)/src.template tail<2>().norm();
242  perp.coeffRef(0) = 0;
243  perp.coeffRef(1) = -numext::conj(src.z())*invnm;
244  perp.coeffRef(2) = numext::conj(src.y())*invnm;
245  }
246 
247  return perp;
248  }
249 };
250 
251 template<typename Derived>
252 struct unitOrthogonal_selector<Derived,2>
253 {
254  typedef typename plain_matrix_type<Derived>::type VectorType;
256  static inline VectorType run(const Derived& src)
257  { return VectorType(-numext::conj(src.y()), numext::conj(src.x())).normalized(); }
258 };
259 
260 } // end namespace internal
261 
271 template<typename Derived>
274 {
276  return internal::unitOrthogonal_selector<Derived>::run(derived());
277 }
278 
279 } // end namespace Eigen
280 
281 #endif // EIGEN_ORTHOMETHODS_H
ConjugateReturnType conjugate() const
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:883
#define eigen_assert(x)
Definition: Macros.h:902
v tail< 2 >().setZero()
v head< 2 >().setZero()
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
#define EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE)
Definition: StaticAssert.h:51
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE)
Definition: StaticAssert.h:36
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:52
internal::cross_impl< Derived, OtherDerived >::return_type cross(const MatrixBase< OtherDerived > &other) const
Base::PlainObject PlainObject
Definition: MatrixBase.h:106
The matrix class, also used for vectors and row-vectors.
Definition: Matrix.h:182
ExpressionType::PlainObject CrossReturnType
Definition: VectorwiseOp.h:713
const CrossReturnType cross(const MatrixBase< OtherDerived > &other) const
Definition: OrthoMethods.h:157
PlainObject unitOrthogonal(void) const
Definition: OrthoMethods.h:273
PlainObject cross3(const MatrixBase< OtherDerived > &other) const
Definition: OrthoMethods.h:129
@ Vertical
Definition: Constants.h:266
const unsigned int PacketAccessBit
Definition: Constants.h:96
Matrix< Type, 2, 1 > Vector2
[c++11] 2×1 vector of type Type.
Definition: Matrix.h:534
typename remove_all< T >::type remove_all_t
Definition: Meta.h:119
EIGEN_CONSTEXPR Index first(const T &x) EIGEN_NOEXCEPT
bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
EIGEN_ALWAYS_INLINE T maxi(const T &x, const T &y)
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_conjugate_op< typename Derived::Scalar >, const Derived > conj(const Eigen::ArrayBase< Derived > &x)
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:231