compbio
Dot.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_DOT_H
11 #define EIGEN_DOT_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 // helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
18 // with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
19 // looking at the static assertions. Thus this is a trick to get better compile errors.
20 template<typename T, typename U,
21 // the NeedToTranspose condition here is taken straight from Assign.h
22  bool NeedToTranspose = T::IsVectorAtCompileTime
23  && U::IsVectorAtCompileTime
24  && ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
25  | // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
26  // revert to || as soon as not needed anymore.
27  (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
28 >
30 {
32  typedef typename conj_prod::result_type ResScalar;
33  EIGEN_DEVICE_FUNC
34  static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
35  {
36  return a.template binaryExpr<conj_prod>(b).sum();
37  }
38 };
39 
40 template<typename T, typename U>
41 struct dot_nocheck<T, U, true>
42 {
44  typedef typename conj_prod::result_type ResScalar;
45  EIGEN_DEVICE_FUNC
46  static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
47  {
48  return a.transpose().template binaryExpr<conj_prod>(b).sum();
49  }
50 };
51 
52 } // end namespace internal
53 
64 template<typename Derived>
65 template<typename OtherDerived>
66 EIGEN_DEVICE_FUNC
69 {
70  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
71  EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
72  EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
73 #if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
75  EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
76 #endif
77 
78  eigen_assert(size() == other.size());
79 
81 }
82 
83 //---------- implementation of L2 norm and related functions ----------
84 
91 template<typename Derived>
93 {
94  return numext::real((*this).cwiseAbs2().sum());
95 }
96 
103 template<typename Derived>
105 {
106  return numext::sqrt(squaredNorm());
107 }
108 
118 template<typename Derived>
119 inline const typename MatrixBase<Derived>::PlainObject
121 {
122  typedef typename internal::nested_eval<Derived,2>::type _Nested;
123  _Nested n(derived());
124  RealScalar z = n.squaredNorm();
125  // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
126  if(z>RealScalar(0))
127  return n / numext::sqrt(z);
128  else
129  return n;
130 }
131 
140 template<typename Derived>
142 {
143  RealScalar z = squaredNorm();
144  // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
145  if(z>RealScalar(0))
146  derived() /= numext::sqrt(z);
147 }
148 
161 template<typename Derived>
162 inline const typename MatrixBase<Derived>::PlainObject
164 {
165  typedef typename internal::nested_eval<Derived,3>::type _Nested;
166  _Nested n(derived());
167  RealScalar w = n.cwiseAbs().maxCoeff();
168  RealScalar z = (n/w).squaredNorm();
169  if(z>RealScalar(0))
170  return n / (numext::sqrt(z)*w);
171  else
172  return n;
173 }
174 
186 template<typename Derived>
188 {
189  RealScalar w = cwiseAbs().maxCoeff();
190  RealScalar z = (derived()/w).squaredNorm();
191  if(z>RealScalar(0))
192  derived() /= numext::sqrt(z)*w;
193 }
194 
195 //---------- implementation of other norms ----------
196 
197 namespace internal {
198 
199 template<typename Derived, int p>
201 {
203  EIGEN_DEVICE_FUNC
204  static inline RealScalar run(const MatrixBase<Derived>& m)
205  {
206  EIGEN_USING_STD_MATH(pow)
207  return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
208  }
209 };
210 
211 template<typename Derived>
212 struct lpNorm_selector<Derived, 1>
213 {
214  EIGEN_DEVICE_FUNC
215  static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
216  {
217  return m.cwiseAbs().sum();
218  }
219 };
220 
221 template<typename Derived>
222 struct lpNorm_selector<Derived, 2>
223 {
224  EIGEN_DEVICE_FUNC
225  static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
226  {
227  return m.norm();
228  }
229 };
230 
231 template<typename Derived>
232 struct lpNorm_selector<Derived, Infinity>
233 {
235  EIGEN_DEVICE_FUNC
236  static inline RealScalar run(const MatrixBase<Derived>& m)
237  {
238  if(Derived::SizeAtCompileTime==0 || (Derived::SizeAtCompileTime==Dynamic && m.size()==0))
239  return RealScalar(0);
240  return m.cwiseAbs().maxCoeff();
241  }
242 };
243 
244 } // end namespace internal
245 
256 template<typename Derived>
257 template<int p>
258 #ifndef EIGEN_PARSED_BY_DOXYGEN
260 #else
261 MatrixBase<Derived>::RealScalar
262 #endif
264 {
266 }
267 
268 //---------- implementation of isOrthogonal / isUnitary ----------
269 
276 template<typename Derived>
277 template<typename OtherDerived>
279 (const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
280 {
281  typename internal::nested_eval<Derived,2>::type nested(derived());
282  typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
283  return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
284 }
285 
297 template<typename Derived>
298 bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
299 {
300  typename internal::nested_eval<Derived,1>::type self(derived());
301  for(Index i = 0; i < cols(); ++i)
302  {
303  if(!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
304  return false;
305  for(Index j = 0; j < i; ++j)
306  if(!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec))
307  return false;
308  }
309  return true;
310 }
311 
312 } // end namespace Eigen
313 
314 #endif // EIGEN_DOT_H
internal::traits< Derived >::Scalar Scalar
The numeric type of the expression&#39; coefficients, e.g.
Definition: DenseBase.h:66
bool isUnitary(const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition: Dot.h:298
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:85
Holds information about the various numeric (i.e.
Definition: NumTraits.h:150
EIGEN_DEVICE_FUNC const PlainObject normalized() const
Definition: Dot.h:120
EIGEN_DEVICE_FUNC TransposeReturnType transpose()
Definition: Transpose.h:172
EIGEN_DEVICE_FUNC RealScalar squaredNorm() const
Definition: Dot.h:92
EIGEN_DEVICE_FUNC void normalize()
Normalizes the vector, i.e.
Definition: Dot.h:141
EIGEN_DEVICE_FUNC RealScalar norm() const
Definition: Dot.h:104
EIGEN_DEVICE_FUNC void stableNormalize()
Normalizes the vector while avoid underflow and overflow.
Definition: Dot.h:187
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseAbsReturnType cwiseAbs() const
Definition: MatrixBase.h:33
EIGEN_DEVICE_FUNC ScalarBinaryOpTraits< typename internal::traits< Derived >::Scalar, typename internal::traits< OtherDerived >::Scalar >::ReturnType dot(const MatrixBase< OtherDerived > &other) const
Definition: Dot.h:68
Definition: benchGeometry.cpp:23
EIGEN_DEVICE_FUNC const PlainObject stableNormalized() const
Definition: Dot.h:163
Definition: BandTriangularSolver.h:13
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:757
bool isOrthogonal(const MatrixBase< OtherDerived > &other, const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition: Dot.h:279
Definition: Dot.h:29
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.
Definition: Constants.h:21
Generic expression where a coefficient-wise unary operator is applied to an expression.
Definition: CwiseUnaryOp.h:55
Definition: BinaryFunctors.h:109
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Definition: ForwardDeclarations.h:17
const int Infinity
This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>()...
Definition: Constants.h:31