Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
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 <[email protected]>
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// IWYU pragma: private
14#include "./InternalHeaderCheck.h"
15
16namespace Eigen {
17
18namespace internal {
19
20// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
21// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
22// looking at the static assertions. Thus this is a trick to get better compile errors.
23template <typename T, typename U,
24 bool NeedToTranspose = T::IsVectorAtCompileTime && U::IsVectorAtCompileTime &&
25 ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1) ||
26 (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))>
27struct dot_nocheck {
28 typedef scalar_conj_product_op<typename traits<T>::Scalar, typename traits<U>::Scalar> conj_prod;
29 typedef typename conj_prod::result_type ResScalar;
30 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b) {
31 return a.template binaryExpr<conj_prod>(b).sum();
32 }
33};
34
35template <typename T, typename U>
36struct dot_nocheck<T, U, true> {
37 typedef scalar_conj_product_op<typename traits<T>::Scalar, typename traits<U>::Scalar> conj_prod;
38 typedef typename conj_prod::result_type ResScalar;
39 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE static ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b) {
40 return a.transpose().template binaryExpr<conj_prod>(b).sum();
41 }
42};
43
44} // end namespace internal
45
57template <typename Derived>
58template <typename OtherDerived>
59EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
60 typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,
61 typename internal::traits<OtherDerived>::Scalar>::ReturnType
63 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
64 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
65 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived, OtherDerived)
66#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
67 EIGEN_CHECK_BINARY_COMPATIBILIY(
68 Eigen::internal::scalar_conj_product_op<Scalar EIGEN_COMMA typename OtherDerived::Scalar>, Scalar,
69 typename OtherDerived::Scalar);
70#endif
71
72 eigen_assert(size() == other.size());
73
74 return internal::dot_nocheck<Derived, OtherDerived>::run(*this, other);
75}
76
77//---------- implementation of L2 norm and related functions ----------
78
85template <typename Derived>
86EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
88 return numext::real((*this).cwiseAbs2().sum());
89}
90
97template <typename Derived>
98EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
100 return numext::sqrt(squaredNorm());
101}
102
112template <typename Derived>
113EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject MatrixBase<Derived>::normalized()
114 const {
115 typedef typename internal::nested_eval<Derived, 2>::type Nested_;
116 Nested_ n(derived());
117 RealScalar z = n.squaredNorm();
118 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
119 if (z > RealScalar(0))
120 return n / numext::sqrt(z);
121 else
122 return n;
123}
124
133template <typename Derived>
134EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::normalize() {
135 RealScalar z = squaredNorm();
136 // NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
137 if (z > RealScalar(0)) derived() /= numext::sqrt(z);
138}
139
152template <typename Derived>
153EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::PlainObject
155 typedef typename internal::nested_eval<Derived, 3>::type Nested_;
156 Nested_ n(derived());
157 RealScalar w = n.cwiseAbs().maxCoeff();
158 RealScalar z = (n / w).squaredNorm();
159 if (z > RealScalar(0))
160 return n / (numext::sqrt(z) * w);
161 else
162 return n;
163}
164
176template <typename Derived>
177EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase<Derived>::stableNormalize() {
178 RealScalar w = cwiseAbs().maxCoeff();
179 RealScalar z = (derived() / w).squaredNorm();
180 if (z > RealScalar(0)) derived() /= numext::sqrt(z) * w;
181}
182
183//---------- implementation of other norms ----------
184
185namespace internal {
186
187template <typename Derived, int p>
188struct lpNorm_selector {
189 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
190 EIGEN_DEVICE_FUNC static inline RealScalar run(const MatrixBase<Derived>& m) {
191 EIGEN_USING_STD(pow)
192 return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1) / p);
196template <typename Derived>
197struct lpNorm_selector<Derived, 1> {
198 EIGEN_DEVICE_FUNC static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(
199 const MatrixBase<Derived>& m) {
200 return m.cwiseAbs().sum();
201 }
202};
203
204template <typename Derived>
205struct lpNorm_selector<Derived, 2> {
206 EIGEN_DEVICE_FUNC static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(
207 const MatrixBase<Derived>& m) {
208 return m.norm();
209 }
210};
211
212template <typename Derived>
213struct lpNorm_selector<Derived, Infinity> {
214 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
215 EIGEN_DEVICE_FUNC static inline RealScalar run(const MatrixBase<Derived>& m) {
216 if (Derived::SizeAtCompileTime == 0 || (Derived::SizeAtCompileTime == Dynamic && m.size() == 0))
217 return RealScalar(0);
218 return m.cwiseAbs().maxCoeff();
219 }
220};
221
222} // end namespace internal
223
238template <typename Derived>
239template <int p>
240#ifndef EIGEN_PARSED_BY_DOXYGEN
241EIGEN_DEVICE_FUNC inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
242#else
243EIGEN_DEVICE_FUNC MatrixBase<Derived>::RealScalar
244#endif
246 return internal::lpNorm_selector<Derived, p>::run(*this);
247}
248
249//---------- implementation of isOrthogonal / isUnitary ----------
250
257template <typename Derived>
258template <typename OtherDerived>
259bool MatrixBase<Derived>::isOrthogonal(const MatrixBase<OtherDerived>& other, const RealScalar& prec) const {
260 typename internal::nested_eval<Derived, 2>::type nested(derived());
261 typename internal::nested_eval<OtherDerived, 2>::type otherNested(other.derived());
262 return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
263}
264
276template <typename Derived>
277bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const {
278 typename internal::nested_eval<Derived, 1>::type self(derived());
279 for (Index i = 0; i < cols(); ++i) {
280 if (!internal::isApprox(self.col(i).squaredNorm(), static_cast<RealScalar>(1), prec)) return false;
281 for (Index j = 0; j < i; ++j)
282 if (!internal::isMuchSmallerThan(self.col(i).dot(self.col(j)), static_cast<Scalar>(1), prec)) return false;
283 }
284 return true;
285}
286
287} // end namespace Eigen
288
289#endif // EIGEN_DOT_H
internal::traits< Derived >::Scalar Scalar
Definition DenseBase.h:62
internal::traits< Derived >::Scalar maxCoeff() const
Definition Redux.h:470
Scalar sum() const
Definition Redux.h:481
Derived & derived()
Definition EigenBase.h:49
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition EigenBase.h:64
Base class for all dense matrices, vectors, and expressions.
Definition MatrixBase.h:52
bool isUnitary(const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Dot.h:277
RealScalar norm() const
Definition Dot.h:99
bool isOrthogonal(const MatrixBase< OtherDerived > &other, const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition Dot.h:259
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Infinity
Definition Constants.h:39
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition Meta.h:523