Medial Code Documentation
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))>
25{
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{
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
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))
74 EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
75#endif
76
77 eigen_assert(size() == other.size());
78
80}
81
82//---------- implementation of L2 norm and related functions ----------
83
90template<typename Derived>
91EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
92{
93 return numext::real((*this).cwiseAbs2().sum());
94}
95
102template<typename Derived>
103EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
104{
105 return numext::sqrt(squaredNorm());
106}
107
117template<typename Derived>
118EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
120{
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{
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>
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
214 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
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{
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
266
267//---------- implementation of isOrthogonal / isUnitary ----------
268
275template<typename Derived>
276template<typename OtherDerived>
278(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
279{
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
EIGEN_DEVICE_FUNC Scalar sum() const
Definition Redux.h:459
EIGEN_DEVICE_FUNC TransposeReturnType transpose()
Definition Transpose.h:182
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:50
EIGEN_DEVICE_FUNC RealScalar squaredNorm() const
Definition Dot.h:91
EIGEN_DEVICE_FUNC ScalarBinaryOpTraits< typenameinternal::traits< Derived >::Scalar, typenameinternal::traits< OtherDerived >::Scalar >::ReturnType dot(const MatrixBase< OtherDerived > &other) const
Namespace containing all symbols from the Eigen library.
Definition LDLT.h:16
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:74
const int Infinity
This value means +Infinity; it is currently used only as the p parameter to MatrixBase::lpNorm<int>()...
Definition Constants.h:36
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition Constants.h:22
Definition Dot.h:25
Definition BinaryFunctors.h:108
Definition ForwardDeclarations.h:17
Definition Meta.h:96