Eigen  3.4.1 (git rev 28ded8800c26864e537852658428ab44c8399e87)
 
Loading...
Searching...
No Matches
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
13namespace Eigen {
14
15namespace 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.
20template<typename T, typename U,
21 bool NeedToTranspose = T::IsVectorAtCompileTime && U::IsVectorAtCompileTime &&
22 ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1) ||
23 (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))>
24struct dot_nocheck
25{
26 typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
27 typedef typename conj_prod::result_type ResScalar;
28 EIGEN_DEVICE_FUNC
29 EIGEN_STRONG_INLINE
30 static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
31 {
32 return a.template binaryExpr<conj_prod>(b).sum();
33 }
34};
35
36template<typename T, typename U>
37struct dot_nocheck<T, U, true>
38{
39 typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
40 typedef typename conj_prod::result_type ResScalar;
41 EIGEN_DEVICE_FUNC
42 EIGEN_STRONG_INLINE
43 static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
44 {
45 return a.transpose().template binaryExpr<conj_prod>(b).sum();
46 }
47};
48
49} // end namespace internal
50
62template<typename Derived>
63template<typename OtherDerived>
64EIGEN_DEVICE_FUNC
65EIGEN_STRONG_INLINE
66typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
67MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
68{
69 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
70 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
71 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
72#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
73 typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func;
74 EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
75#endif
76
77 eigen_assert(size() == other.size());
78
79 return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
80}
81
82//---------- implementation of L2 norm and related functions ----------
83
90template<typename Derived>
92{
93 return numext::real((*this).cwiseAbs2().sum());
94}
95
102template<typename Derived>
104{
105 return numext::sqrt(squaredNorm());
106}
107
117template<typename Derived>
118EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
120{
121 typedef typename internal::nested_eval<Derived,2>::type _Nested;
122 _Nested n(derived());
123 RealScalar z = n.squaredNorm();
124 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
125 if(z>RealScalar(0))
126 return n / numext::sqrt(z);
127 else
128 return n;
129}
130
139template<typename Derived>
140EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
141{
142 RealScalar z = squaredNorm();
143 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
144 if(z>RealScalar(0))
145 derived() /= numext::sqrt(z);
146}
147
160template<typename Derived>
161EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
163{
164 typedef typename internal::nested_eval<Derived,3>::type _Nested;
165 _Nested n(derived());
166 RealScalar w = n.cwiseAbs().maxCoeff();
167 RealScalar z = (n/w).squaredNorm();
168 if(z>RealScalar(0))
169 return n / (numext::sqrt(z)*w);
170 else
171 return n;
172}
173
185template<typename Derived>
186EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
187{
188 RealScalar w = cwiseAbs().maxCoeff();
189 RealScalar z = (derived()/w).squaredNorm();
190 if(z>RealScalar(0))
191 derived() /= numext::sqrt(z)*w;
194//---------- implementation of other norms ----------
195
196namespace internal {
198template<typename Derived, int p>
199struct lpNorm_selector
201 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
202 EIGEN_DEVICE_FUNC
203 static inline RealScalar run(const MatrixBase<Derived>& m)
204 {
205 EIGEN_USING_STD(pow)
206 return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
207 }
208};
209
210template<typename Derived>
211struct lpNorm_selector<Derived, 1>
212{
213 EIGEN_DEVICE_FUNC
215 {
216 return m.cwiseAbs().sum();
217 }
218};
219
220template<typename Derived>
221struct lpNorm_selector<Derived, 2>
222{
223 EIGEN_DEVICE_FUNC
224 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
225 {
226 return m.norm();
227 }
228};
229
230template<typename Derived>
231struct lpNorm_selector<Derived, Infinity>
232{
233 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
234 EIGEN_DEVICE_FUNC
235 static inline RealScalar run(const MatrixBase<Derived>& m)
236 {
237 if(Derived::SizeAtCompileTime==0 || (Derived::SizeAtCompileTime==Dynamic && m.size()==0))
238 return RealScalar(0);
239 return m.cwiseAbs().maxCoeff();
240 }
241};
242
243} // end namespace internal
244
255template<typename Derived>
256template<int p>
257#ifndef EIGEN_PARSED_BY_DOXYGEN
258EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
259#else
260EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
261#endif
263{
264 return internal::lpNorm_selector<Derived, p>::run(*this);
265}
266
267//---------- implementation of isOrthogonal / isUnitary ----------
268
275template<typename Derived>
276template<typename OtherDerived>
278(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
279{
280 typename internal::nested_eval<Derived,2>::type nested(derived());
281 typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
282 return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
283}
284
296template<typename Derived>
297bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
298{
299 typename internal::nested_eval<Derived,1>::type self(derived());
300 for(Index i = 0; i < cols(); ++i)
301 {
302 if(!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
303 return false;
304 for(Index j = 0; j < i; ++j)
305 if(!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec))
306 return false;
307 }
308 return true;
309}
310
311} // end namespace Eigen
312
313#endif // EIGEN_DOT_H
const CwiseBinaryOp< internal::scalar_pow_op< Derived::Scalar, ScalarExponent >, Derived, Constant< ScalarExponent > > pow(const Eigen::ArrayBase< Derived > &x, const ScalarExponent &exponent)
internal::traits< Derived >::Scalar Scalar
Definition DenseBase.h:66
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
void stableNormalize()
Definition Dot.h:186
const PlainObject stableNormalized() const
Definition Dot.h:162
const PlainObject normalized() const
Definition Dot.h:119
RealScalar lpNorm() const
Definition Dot.h:262
ScalarBinaryOpTraits< typenameinternal::traits< Derived >::Scalar, typenameinternal::traits< OtherDerived >::Scalar >::ReturnType dot(const MatrixBase< OtherDerived > &other) const
Definition Dot.h:67
bool isUnitary(const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Dot.h:297
const MatrixPowerReturnValue< MatrixWrapper< ExpressionType > > pow(const RealScalar &p) const
RealScalar squaredNorm() const
Definition Dot.h:91
void normalize()
Definition Dot.h:140
RealScalar norm() const
Definition Dot.h:103
const CwiseAbsReturnType cwiseAbs() const
Definition MatrixBase.h:34
bool isOrthogonal(const MatrixBase< OtherDerived > &other, const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Dot.h:278
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
const int Infinity
Definition Constants.h:36
const int Dynamic
Definition Constants.h:22
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition NumTraits.h:236
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition XprHelper.h:806