WPILibC++ 2023.4.3-108-ge5452e3
Dot.h
Go to the documentation of this file.
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>
30{
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{
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
56/** \fn MatrixBase::dot
57 * \returns the dot product of *this with other.
58 *
59 * \only_for_vectors
60 *
61 * \note If the scalar type is complex numbers, then this function returns the hermitian
62 * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the
63 * second variable.
64 *
65 * \sa squaredNorm(), norm()
66 */
67template<typename Derived>
68template<typename OtherDerived>
71typename ScalarBinaryOpTraits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
73{
76 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
77#if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
79 EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
80#endif
81
82 eigen_assert(size() == other.size());
83
85}
86
87//---------- implementation of L2 norm and related functions ----------
88
89/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the squared Frobenius norm.
90 * In both cases, it consists in the sum of the square of all the matrix entries.
91 * For vectors, this is also equals to the dot product of \c *this with itself.
92 *
93 * \sa dot(), norm(), lpNorm()
94 */
95template<typename Derived>
97{
98 return numext::real((*this).cwiseAbs2().sum());
99}
100
101/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
102 * In both cases, it consists in the square root of the sum of the square of all the matrix entries.
103 * For vectors, this is also equals to the square root of the dot product of \c *this with itself.
104 *
105 * \sa lpNorm(), dot(), squaredNorm()
106 */
107template<typename Derived>
109{
110 return numext::sqrt(squaredNorm());
111}
112
113/** \returns an expression of the quotient of \c *this by its own norm.
114 *
115 * \warning If the input vector is too small (i.e., this->norm()==0),
116 * then this function returns a copy of the input.
117 *
118 * \only_for_vectors
119 *
120 * \sa norm(), normalize()
121 */
122template<typename Derived>
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
136/** Normalizes the vector, i.e. divides it by its own norm.
137 *
138 * \only_for_vectors
139 *
140 * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
141 *
142 * \sa norm(), normalized()
143 */
144template<typename Derived>
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
153/** \returns an expression of the quotient of \c *this by its own norm while avoiding underflow and overflow.
154 *
155 * \only_for_vectors
156 *
157 * This method is analogue to the normalized() method, but it reduces the risk of
158 * underflow and overflow when computing the norm.
159 *
160 * \warning If the input vector is too small (i.e., this->norm()==0),
161 * then this function returns a copy of the input.
162 *
163 * \sa stableNorm(), stableNormalize(), normalized()
164 */
165template<typename Derived>
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
179/** Normalizes the vector while avoid underflow and overflow
180 *
181 * \only_for_vectors
182 *
183 * This method is analogue to the normalize() method, but it reduces the risk of
184 * underflow and overflow when computing the norm.
185 *
186 * \warning If the input vector is too small (i.e., this->norm()==0), then \c *this is left unchanged.
187 *
188 * \sa stableNorm(), stableNormalized(), normalize()
189 */
190template<typename Derived>
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>
205{
208 static inline RealScalar run(const MatrixBase<Derived>& m)
209 {
211 return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
212 }
213};
214
215template<typename Derived>
216struct lpNorm_selector<Derived, 1>
217{
220 {
221 return m.cwiseAbs().sum();
222 }
223};
224
225template<typename Derived>
226struct lpNorm_selector<Derived, 2>
227{
230 {
231 return m.norm();
232 }
233};
234
235template<typename Derived>
236struct lpNorm_selector<Derived, Infinity>
237{
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
250/** \returns the \b coefficient-wise \f$ \ell^p \f$ norm of \c *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values
251 * of the coefficients of \c *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$
252 * norm, that is the maximum of the absolute values of the coefficients of \c *this.
253 *
254 * In all cases, if \c *this is empty, then the value 0 is returned.
255 *
256 * \note For matrices, this function does not compute the <a href="https://en.wikipedia.org/wiki/Operator_norm">operator-norm</a>. That is, if \c *this is a matrix, then its coefficients are interpreted as a 1D vector. Nonetheless, you can easily compute the 1-norm and \f$\infty\f$-norm matrix operator norms using \link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \endlink.
257 *
258 * \sa norm()
259 */
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
266#endif
268{
270}
271
272//---------- implementation of isOrthogonal / isUnitary ----------
273
274/** \returns true if *this is approximately orthogonal to \a other,
275 * within the precision given by \a prec.
276 *
277 * Example: \include MatrixBase_isOrthogonal.cpp
278 * Output: \verbinclude MatrixBase_isOrthogonal.out
279 */
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
290/** \returns true if *this is approximately an unitary matrix,
291 * within the precision given by \a prec. In the case where the \a Scalar
292 * type is real numbers, a unitary matrix is an orthogonal matrix, whence the name.
293 *
294 * \note This can be used to check whether a family of vectors forms an orthonormal basis.
295 * Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an
296 * orthonormal basis.
297 *
298 * Example: \include MatrixBase_isUnitary.cpp
299 * Output: \verbinclude MatrixBase_isUnitary.out
300 */
301template<typename Derived>
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;
312 }
313 return true;
314}
315
316} // end namespace Eigen
317
318#endif // EIGEN_DOT_H
EIGEN_DEVICE_FUNC RealReturnType real() const
Definition: CommonCwiseUnaryOps.h:100
#define EIGEN_USING_STD(FUNC)
Definition: Macros.h:1195
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:986
#define eigen_assert(x)
Definition: Macros.h:1047
#define EIGEN_STRONG_INLINE
Definition: Macros.h:927
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseAbsReturnType cwiseAbs() const
Definition: MatrixCwiseUnaryOps.h:33
#define EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0, TYPE1)
Definition: StaticAssert.h:167
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE)
Definition: StaticAssert.h:142
#define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP, LHS, RHS)
Definition: XprHelper.h:850
EIGEN_DEVICE_FUNC internal::traits< Derived >::Scalar maxCoeff() const
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:96
EIGEN_DEVICE_FUNC ScalarBinaryOpTraits< typenameinternal::traits< Derived >::Scalar, typenameinternal::traits< OtherDerived >::Scalar >::ReturnType dot(const MatrixBase< OtherDerived > &other) const
EIGEN_DEVICE_FUNC RealScalar lpNorm() const
EIGEN_DEVICE_FUNC void stableNormalize()
Normalizes the vector while avoid underflow and overflow.
Definition: Dot.h:191
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ArrayWrapper< Derived > array()
Definition: MatrixBase.h:319
NumTraits< Scalar >::Real RealScalar
Definition: MatrixBase.h:58
EIGEN_DEVICE_FUNC void normalize()
Normalizes the vector, i.e.
Definition: Dot.h:145
bool isUnitary(const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition: Dot.h:302
EIGEN_DEVICE_FUNC const PlainObject normalized() const
Definition: Dot.h:124
EIGEN_DEVICE_FUNC const PlainObject stableNormalized() const
Definition: Dot.h:167
internal::traits< Derived >::Scalar Scalar
Definition: MatrixBase.h:56
EIGEN_DEVICE_FUNC RealScalar norm() const
Definition: Dot.h:108
bool isOrthogonal(const MatrixBase< OtherDerived > &other, const RealScalar &prec=NumTraits< Scalar >::dummy_precision()) const
Definition: Dot.h:283
EIGEN_DEVICE_FUNC bool isApprox(const Scalar &x, const Scalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1947
EIGEN_DEVICE_FUNC bool isMuchSmallerThan(const Scalar &x, const OtherScalar &y, const typename NumTraits< Scalar >::Real &precision=NumTraits< Scalar >::dummy_precision())
Definition: MathFunctions.h:1940
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE float sqrt(const float &x)
Definition: MathFunctions.h:177
EIGEN_DEVICE_FUNC bool abs2(bool x)
Definition: MathFunctions.h:1292
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
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: Eigen_Colamd.h:50
b
Definition: data.h:44
constexpr common_t< T1, T2 > pow(const T1 base, const T2 exp_term) noexcept
Compile-time power function.
Definition: pow.hpp:76
Holds information about the various numeric (i.e.
Definition: NumTraits.h:233
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ResScalar run(const MatrixBase< T > &a, const MatrixBase< U > &b)
Definition: Dot.h:48
conj_prod::result_type ResScalar
Definition: Dot.h:45
scalar_conj_product_op< typename traits< T >::Scalar, typename traits< U >::Scalar > conj_prod
Definition: Dot.h:44
Definition: Dot.h:30
EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE ResScalar run(const MatrixBase< T > &a, const MatrixBase< U > &b)
Definition: Dot.h:35
conj_prod::result_type ResScalar
Definition: Dot.h:32
scalar_conj_product_op< typename traits< T >::Scalar, typename traits< U >::Scalar > conj_prod
Definition: Dot.h:31
static EIGEN_DEVICE_FUNC NumTraits< typenametraits< Derived >::Scalar >::Real run(const MatrixBase< Derived > &m)
Definition: Dot.h:219
static EIGEN_DEVICE_FUNC NumTraits< typenametraits< Derived >::Scalar >::Real run(const MatrixBase< Derived > &m)
Definition: Dot.h:229
static EIGEN_DEVICE_FUNC RealScalar run(const MatrixBase< Derived > &m)
Definition: Dot.h:240
NumTraits< typenametraits< Derived >::Scalar >::Real RealScalar
Definition: Dot.h:238
static EIGEN_DEVICE_FUNC RealScalar run(const MatrixBase< Derived > &m)
Definition: Dot.h:208
NumTraits< typenametraits< Derived >::Scalar >::Real RealScalar
Definition: Dot.h:206
Definition: BinaryFunctors.h:108
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_conj_product_op >::ReturnType result_type
Definition: BinaryFunctors.h:114
Definition: ForwardDeclarations.h:17
Definition: Meta.h:96