Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.4.0
 
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// 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>
29struct dot_nocheck
30{
31 typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
32 typedef typename conj_prod::result_type ResScalar;
33 EIGEN_DEVICE_FUNC
34 EIGEN_STRONG_INLINE
35 static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
36 {
37 return a.template binaryExpr<conj_prod>(b).sum();
38 }
39};
40
41template<typename T, typename U>
42struct dot_nocheck<T, U, true>
43{
44 typedef scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> conj_prod;
45 typedef typename conj_prod::result_type ResScalar;
46 EIGEN_DEVICE_FUNC
47 EIGEN_STRONG_INLINE
48 static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
49 {
50 return a.transpose().template binaryExpr<conj_prod>(b).sum();
51 }
52};
53
54} // end namespace internal
55
67template<typename Derived>
68template<typename OtherDerived>
69EIGEN_DEVICE_FUNC
70EIGEN_STRONG_INLINE
71typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
73{
74 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
75 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
76 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
77#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
78 typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func;
79 EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
80#endif
81
82 eigen_assert(size() == other.size());
83
84 return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
85}
86
87//---------- implementation of L2 norm and related functions ----------
88
95template<typename Derived>
96EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
97{
98 return numext::real((*this).cwiseAbs2().sum());
99}
100
107template<typename Derived>
108EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
109{
110 return numext::sqrt(squaredNorm());
111}
112
122template<typename Derived>
123EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
125{
126 typedef typename internal::nested_eval<Derived,2>::type _Nested;
127 _Nested n(derived());
128 RealScalar z = n.squaredNorm();
129 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
130 if(z>RealScalar(0))
131 return n / numext::sqrt(z);
132 else
133 return n;
134}
135
144template<typename Derived>
145EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize()
146{
147 RealScalar z = squaredNorm();
148 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
149 if(z>RealScalar(0))
150 derived() /= numext::sqrt(z);
151}
152
165template<typename Derived>
166EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
168{
169 typedef typename internal::nested_eval<Derived,3>::type _Nested;
170 _Nested n(derived());
171 RealScalar w = n.cwiseAbs().maxCoeff();
172 RealScalar z = (n/w).squaredNorm();
173 if(z>RealScalar(0))
174 return n / (numext::sqrt(z)*w);
175 else
176 return n;
177}
178
190template<typename Derived>
191EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize()
193 RealScalar w = cwiseAbs().maxCoeff();
194 RealScalar z = (derived()/w).squaredNorm();
195 if(z>RealScalar(0))
196 derived() /= numext::sqrt(z)*w;
199//---------- implementation of other norms ----------
201namespace internal {
202
203template<typename Derived, int p>
204struct lpNorm_selector
205{
206 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
207 EIGEN_DEVICE_FUNC
208 static inline RealScalar run(const MatrixBase<Derived>& m)
209 {
210 EIGEN_USING_STD(pow)
211 return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
212 }
213};
214
215template<typename Derived>
216struct lpNorm_selector<Derived, 1>
217{
218 EIGEN_DEVICE_FUNC
219 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
220 {
221 return m.cwiseAbs().sum();
222 }
223};
224
225template<typename Derived>
226struct lpNorm_selector<Derived, 2>
227{
228 EIGEN_DEVICE_FUNC
229 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
230 {
231 return m.norm();
232 }
233};
234
235template<typename Derived>
236struct lpNorm_selector<Derived, Infinity>
237{
238 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
239 EIGEN_DEVICE_FUNC
240 static inline RealScalar run(const MatrixBase<Derived>& m)
241 {
242 if(Derived::SizeAtCompileTime==0 || (Derived::SizeAtCompileTime==Dynamic && m.size()==0))
243 return RealScalar(0);
244 return m.cwiseAbs().maxCoeff();
245 }
246};
247
248} // end namespace internal
249
260template<typename Derived>
261template<int p>
262#ifndef EIGEN_PARSED_BY_DOXYGEN
263EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
264#else
265EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
266#endif
268{
269 return internal::lpNorm_selector<Derived, p>::run(*this);
270}
271
272//---------- implementation of isOrthogonal / isUnitary ----------
273
280template<typename Derived>
281template<typename OtherDerived>
283(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
284{
285 typename internal::nested_eval<Derived,2>::type nested(derived());
286 typename internal::nested_eval<OtherDerived,2>::type otherNested(other.derived());
287 return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
288}
289
301template<typename Derived>
302bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
303{
304 typename internal::nested_eval<Derived,1>::type self(derived());
305 for(Index i = 0; i < cols(); ++i)
306 {
307 if(!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
308 return false;
309 for(Index j = 0; j < i; ++j)
310 if(!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec))
311 return false;
313 return true;
314}
315
316} // end namespace Eigen
317
318#endif // EIGEN_DOT_H
internal::traits< Derived >::Scalar Scalar
Definition: DenseBase.h:66
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:446
Scalar sum() const
Definition: Redux.h:459
Derived & derived()
Definition: EigenBase.h:46
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition: EigenBase.h:67
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:50
ArrayWrapper< Derived > array()
Definition: MatrixBase.h:319
RealScalar norm() const
Definition: Dot.h:108
Namespace containing all symbols from the Eigen library.
Definition: Core:141
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:233