2007-10-12 05:15:25 +00:00
// This file is part of Eigen, a lightweight C++ template library
2009-05-22 20:25:33 +02:00
// for linear algebra.
2007-10-08 07:17:54 +00:00
//
2010-02-27 10:03:27 -05:00
// Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
2007-10-08 07:17:54 +00:00
//
2012-07-13 14:42:47 -04:00
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
2007-10-08 07:17:54 +00:00
2007-11-26 08:47:07 +00:00
# ifndef EIGEN_DOT_H
# define EIGEN_DOT_H
2007-10-08 07:17:54 +00:00
2021-09-10 19:12:26 +00:00
# include "./InternalHeaderCheck.h"
2012-04-15 11:06:28 +01:00
namespace Eigen {
2010-10-25 10:15:22 -04:00
namespace internal {
2010-02-27 10:03:27 -05:00
// helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
// with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
// looking at the static assertions. Thus this is a trick to get better compile errors.
template < typename T , typename U ,
2010-02-27 11:19:14 -05:00
// the NeedToTranspose condition here is taken straight from Assign.h
bool NeedToTranspose = T : : IsVectorAtCompileTime
& & U : : IsVectorAtCompileTime
& & ( ( int ( T : : RowsAtCompileTime ) = = 1 & & int ( U : : ColsAtCompileTime ) = = 1 )
| // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
// revert to || as soon as not needed anymore.
( int ( T : : ColsAtCompileTime ) = = 1 & & int ( U : : RowsAtCompileTime ) = = 1 ) )
>
2010-10-25 10:15:22 -04:00
struct dot_nocheck
2007-10-08 07:17:54 +00:00
{
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
typedef scalar_conj_product_op < typename traits < T > : : Scalar , typename traits < U > : : Scalar > conj_prod ;
typedef typename conj_prod : : result_type ResScalar ;
2013-06-05 15:38:33 +02:00
EIGEN_DEVICE_FUNC
2017-10-26 22:44:28 +02:00
EIGEN_STRONG_INLINE
static ResScalar run ( const MatrixBase < T > & a , const MatrixBase < U > & b )
2007-10-08 07:17:54 +00:00
{
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
return a . template binaryExpr < conj_prod > ( b ) . sum ( ) ;
2007-10-08 07:17:54 +00:00
}
} ;
2010-02-27 10:03:27 -05:00
template < typename T , typename U >
2010-10-25 10:15:22 -04:00
struct dot_nocheck < T , U , true >
2010-02-27 11:19:14 -05:00
{
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
typedef scalar_conj_product_op < typename traits < T > : : Scalar , typename traits < U > : : Scalar > conj_prod ;
typedef typename conj_prod : : result_type ResScalar ;
2013-06-05 15:38:33 +02:00
EIGEN_DEVICE_FUNC
2017-10-26 22:44:28 +02:00
EIGEN_STRONG_INLINE
static ResScalar run ( const MatrixBase < T > & a , const MatrixBase < U > & b )
2010-02-27 11:19:14 -05:00
{
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
return a . transpose ( ) . template binaryExpr < conj_prod > ( b ) . sum ( ) ;
2010-02-27 11:19:14 -05:00
}
} ;
2010-10-25 10:15:22 -04:00
} // end namespace internal
2017-01-04 23:27:33 +01:00
/** \fn MatrixBase::dot
* \ returns the dot product of * this with other .
2007-12-27 21:43:10 +00:00
*
* \ only_for_vectors
2008-03-05 13:18:19 +00:00
*
2007-12-27 21:43:10 +00:00
* \ note If the scalar type is complex numbers , then this function returns the hermitian
2009-08-03 17:20:45 +02:00
* ( sesquilinear ) dot product , conjugate - linear in the first variable and linear in the
2007-12-27 21:43:10 +00:00
* second variable .
*
2008-11-03 19:14:17 +00:00
* \ sa squaredNorm ( ) , norm ( )
2007-12-27 21:43:10 +00:00
*/
2008-03-10 17:23:11 +00:00
template < typename Derived >
2007-10-08 07:17:54 +00:00
template < typename OtherDerived >
2013-04-05 16:35:49 +02:00
EIGEN_DEVICE_FUNC
2017-10-26 22:44:28 +02:00
EIGEN_STRONG_INLINE
Relax mixing-type constraints for binary coefficient-wise operators:
- Replace internal::scalar_product_traits<A,B> by Eigen::ScalarBinaryOpTraits<A,B,OP>
- Remove the "functor_is_product_like" helper (was pretty ugly)
- Currently, OP is not used, but it is available to the user for fine grained tuning
- Currently, only the following operators have been generalized: *,/,+,-,=,*=,/=,+=,-=
- TODO: generalize all other binray operators (comparisons,pow,etc.)
- TODO: handle "scalar op array" operators (currently only * is handled)
- TODO: move the handling of the "void" scalar type to ScalarBinaryOpTraits
2016-06-06 15:11:41 +02:00
typename ScalarBinaryOpTraits < typename internal : : traits < Derived > : : Scalar , typename internal : : traits < OtherDerived > : : Scalar > : : ReturnType
2008-03-10 17:23:11 +00:00
MatrixBase < Derived > : : dot ( const MatrixBase < OtherDerived > & other ) const
2007-10-08 07:17:54 +00:00
{
2009-01-07 16:58:17 +00:00
EIGEN_STATIC_ASSERT_VECTOR_ONLY ( Derived )
EIGEN_STATIC_ASSERT_VECTOR_ONLY ( OtherDerived )
EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE ( Derived , OtherDerived )
2016-12-01 21:23:43 +01:00
# if !(defined(EIGEN_NO_STATIC_ASSERT) && defined(EIGEN_NO_DEBUG))
2011-01-27 09:59:19 +01:00
typedef internal : : scalar_conj_product_op < Scalar , typename OtherDerived : : Scalar > func ;
EIGEN_CHECK_BINARY_COMPATIBILIY ( func , Scalar , typename OtherDerived : : Scalar ) ;
2016-12-01 21:23:43 +01:00
# endif
2010-10-25 10:15:22 -04:00
eigen_assert ( size ( ) = = other . size ( ) ) ;
2008-06-24 15:13:00 +00:00
2010-10-25 10:15:22 -04:00
return internal : : dot_nocheck < Derived , OtherDerived > : : run ( * this , other ) ;
2007-10-08 07:17:54 +00:00
}
2010-06-19 23:36:38 +02:00
//---------- implementation of L2 norm and related functions ----------
2021-08-18 15:04:53 +02:00
/** \returns, for vectors, the squared \em l2 norm of \c *this, and for matrices the squared Frobenius norm.
2011-06-18 08:30:34 +02:00
* In both cases , it consists in the sum of the square of all the matrix entries .
* For vectors , this is also equals to the dot product of \ c * this with itself .
2008-11-03 19:14:17 +00:00
*
2015-12-30 16:04:24 +01:00
* \ sa dot ( ) , norm ( ) , lpNorm ( )
2008-11-03 19:14:17 +00:00
*/
template < typename Derived >
2017-02-28 14:00:15 -08:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits < typename internal : : traits < Derived > : : Scalar > : : Real MatrixBase < Derived > : : squaredNorm ( ) const
2008-11-03 19:14:17 +00:00
{
2013-06-10 23:40:56 +02:00
return numext : : real ( ( * this ) . cwiseAbs2 ( ) . sum ( ) ) ;
2008-11-03 19:14:17 +00:00
}
2011-06-18 08:30:34 +02:00
/** \returns, for vectors, the \em l2 norm of \c *this, and for matrices the Frobenius norm.
* In both cases , it consists in the square root of the sum of the square of all the matrix entries .
* For vectors , this is also equals to the square root of the dot product of \ c * this with itself .
2007-12-27 21:43:10 +00:00
*
2015-12-30 16:04:24 +01:00
* \ sa lpNorm ( ) , dot ( ) , squaredNorm ( )
2007-12-27 21:43:10 +00:00
*/
2008-03-10 17:23:11 +00:00
template < typename Derived >
2017-10-26 22:44:28 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE typename NumTraits < typename internal : : traits < Derived > : : Scalar > : : Real MatrixBase < Derived > : : norm ( ) const
2007-10-10 06:09:56 +00:00
{
2016-01-21 20:18:51 +01:00
return numext : : sqrt ( squaredNorm ( ) ) ;
2007-10-10 06:09:56 +00:00
}
2016-01-21 20:43:42 +01:00
/** \returns an expression of the quotient of \c *this by its own norm.
*
* \ warning If the input vector is too small ( i . e . , this - > norm ( ) = = 0 ) ,
* then this function returns a copy of the input .
2007-12-27 21:43:10 +00:00
*
* \ only_for_vectors
*
2008-06-24 15:13:00 +00:00
* \ sa norm ( ) , normalize ( )
2007-12-27 21:43:10 +00:00
*/
2008-03-10 17:23:11 +00:00
template < typename Derived >
2017-10-26 22:44:28 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase < Derived > : : PlainObject
2008-03-10 17:23:11 +00:00
MatrixBase < Derived > : : normalized ( ) const
2007-10-10 06:09:56 +00:00
{
2014-01-26 15:35:44 +01:00
typedef typename internal : : nested_eval < Derived , 2 > : : type _Nested ;
2008-08-11 02:25:40 +00:00
_Nested n ( derived ( ) ) ;
2016-01-21 20:43:42 +01:00
RealScalar z = n . squaredNorm ( ) ;
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
if ( z > RealScalar ( 0 ) )
return n / numext : : sqrt ( z ) ;
else
return n ;
2008-06-24 15:13:00 +00:00
}
/** Normalizes the vector, i.e. divides it by its own norm.
*
* \ only_for_vectors
*
2016-01-21 20:43:42 +01:00
* \ warning If the input vector is too small ( i . e . , this - > norm ( ) = = 0 ) , then \ c * this is left unchanged .
*
2008-06-24 15:13:00 +00:00
* \ sa norm ( ) , normalized ( )
*/
template < typename Derived >
2017-10-26 22:44:28 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase < Derived > : : normalize ( )
2008-06-24 15:13:00 +00:00
{
2016-01-21 20:43:42 +01:00
RealScalar z = squaredNorm ( ) ;
// NOTE: after extensive benchmarking, this conditional does not impact performance, at least on recent x86 CPU
if ( z > RealScalar ( 0 ) )
derived ( ) / = numext : : sqrt ( z ) ;
2007-10-10 06:09:56 +00:00
}
2016-01-23 22:40:11 +01:00
/** \returns an expression of the quotient of \c *this by its own norm while avoiding underflow and overflow.
*
* \ only_for_vectors
*
* This method is analogue to the normalized ( ) method , but it reduces the risk of
* underflow and overflow when computing the norm .
*
* \ warning If the input vector is too small ( i . e . , this - > norm ( ) = = 0 ) ,
* then this function returns a copy of the input .
*
* \ sa stableNorm ( ) , stableNormalize ( ) , normalized ( )
*/
template < typename Derived >
2017-10-26 22:44:28 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename MatrixBase < Derived > : : PlainObject
2016-01-23 22:40:11 +01:00
MatrixBase < Derived > : : stableNormalized ( ) const
{
typedef typename internal : : nested_eval < Derived , 3 > : : type _Nested ;
_Nested n ( derived ( ) ) ;
RealScalar w = n . cwiseAbs ( ) . maxCoeff ( ) ;
RealScalar z = ( n / w ) . squaredNorm ( ) ;
if ( z > RealScalar ( 0 ) )
return n / ( numext : : sqrt ( z ) * w ) ;
else
return n ;
}
/** Normalizes the vector while avoid underflow and overflow
*
* \ only_for_vectors
*
* This method is analogue to the normalize ( ) method , but it reduces the risk of
* underflow and overflow when computing the norm .
*
* \ warning If the input vector is too small ( i . e . , this - > norm ( ) = = 0 ) , then \ c * this is left unchanged .
*
* \ sa stableNorm ( ) , stableNormalized ( ) , normalize ( )
*/
template < typename Derived >
2017-10-26 22:44:28 +02:00
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void MatrixBase < Derived > : : stableNormalize ( )
2016-01-23 22:40:11 +01:00
{
RealScalar w = cwiseAbs ( ) . maxCoeff ( ) ;
RealScalar z = ( derived ( ) / w ) . squaredNorm ( ) ;
if ( z > RealScalar ( 0 ) )
derived ( ) / = numext : : sqrt ( z ) * w ;
}
2010-06-19 23:36:38 +02:00
//---------- implementation of other norms ----------
2010-10-25 10:15:22 -04:00
namespace internal {
2010-06-19 23:36:38 +02:00
template < typename Derived , int p >
2010-10-25 10:15:22 -04:00
struct lpNorm_selector
2010-06-19 23:36:38 +02:00
{
2010-10-25 10:15:22 -04:00
typedef typename NumTraits < typename traits < Derived > : : Scalar > : : Real RealScalar ;
2013-04-05 16:35:49 +02:00
EIGEN_DEVICE_FUNC
2012-01-31 12:58:52 +01:00
static inline RealScalar run ( const MatrixBase < Derived > & m )
2010-06-19 23:36:38 +02:00
{
2020-10-09 02:05:05 +02:00
EIGEN_USING_STD ( pow )
2010-10-25 10:15:22 -04:00
return pow ( m . cwiseAbs ( ) . array ( ) . pow ( p ) . sum ( ) , RealScalar ( 1 ) / p ) ;
2010-06-19 23:36:38 +02:00
}
} ;
template < typename Derived >
2010-10-25 10:15:22 -04:00
struct lpNorm_selector < Derived , 1 >
2010-06-19 23:36:38 +02:00
{
2013-04-05 16:35:49 +02:00
EIGEN_DEVICE_FUNC
2012-01-31 12:58:52 +01:00
static inline typename NumTraits < typename traits < Derived > : : Scalar > : : Real run ( const MatrixBase < Derived > & m )
2010-06-19 23:36:38 +02:00
{
return m . cwiseAbs ( ) . sum ( ) ;
}
} ;
template < typename Derived >
2010-10-25 10:15:22 -04:00
struct lpNorm_selector < Derived , 2 >
2010-06-19 23:36:38 +02:00
{
2013-04-05 16:35:49 +02:00
EIGEN_DEVICE_FUNC
2012-01-31 12:58:52 +01:00
static inline typename NumTraits < typename traits < Derived > : : Scalar > : : Real run ( const MatrixBase < Derived > & m )
2010-06-19 23:36:38 +02:00
{
return m . norm ( ) ;
}
} ;
template < typename Derived >
2010-10-25 10:15:22 -04:00
struct lpNorm_selector < Derived , Infinity >
2010-06-19 23:36:38 +02:00
{
2016-06-02 15:29:59 +02:00
typedef typename NumTraits < typename traits < Derived > : : Scalar > : : Real RealScalar ;
2013-04-05 16:35:49 +02:00
EIGEN_DEVICE_FUNC
2016-06-02 15:29:59 +02:00
static inline RealScalar run ( const MatrixBase < Derived > & m )
2010-06-19 23:36:38 +02:00
{
2016-06-02 15:29:59 +02:00
if ( Derived : : SizeAtCompileTime = = 0 | | ( Derived : : SizeAtCompileTime = = Dynamic & & m . size ( ) = = 0 ) )
return RealScalar ( 0 ) ;
2010-06-19 23:36:38 +02:00
return m . cwiseAbs ( ) . maxCoeff ( ) ;
}
} ;
2010-10-25 10:15:22 -04:00
} // end namespace internal
2015-09-28 11:55:36 +02:00
/** \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
* of the coefficients of \ c * this . If \ a p is the special value \ a Eigen : : Infinity , this function returns the \ f $ \ ell ^ \ infty \ f $
* norm , that is the maximum of the absolute values of the coefficients of \ c * this .
*
2016-06-02 15:29:59 +02:00
* In all cases , if \ c * this is empty , then the value 0 is returned .
*
2015-09-28 11:55:36 +02:00
* \ 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 1 D vector . Nonetheless , you can easily compute the 1 - norm and \ f $ \ infty \ f $ - norm matrix operator norms using \ link TutorialReductionsVisitorsBroadcastingReductionsNorm partial reductions \ endlink .
2010-06-19 23:36:38 +02:00
*
* \ sa norm ( )
*/
template < typename Derived >
template < int p >
2015-12-30 16:04:24 +01:00
# ifndef EIGEN_PARSED_BY_DOXYGEN
2017-02-28 14:00:15 -08:00
EIGEN_DEVICE_FUNC inline typename NumTraits < typename internal : : traits < Derived > : : Scalar > : : Real
2015-12-30 16:04:24 +01:00
# else
2017-02-28 14:00:15 -08:00
EIGEN_DEVICE_FUNC MatrixBase < Derived > : : RealScalar
2015-12-30 16:04:24 +01:00
# endif
2010-06-19 23:36:38 +02:00
MatrixBase < Derived > : : lpNorm ( ) const
{
2010-10-25 10:15:22 -04:00
return internal : : lpNorm_selector < Derived , p > : : run ( * this ) ;
2010-06-19 23:36:38 +02:00
}
//---------- implementation of isOrthogonal / isUnitary ----------
2008-01-06 16:35:21 +00:00
/** \returns true if *this is approximately orthogonal to \a other,
* within the precision given by \ a prec .
*
2008-06-24 15:13:00 +00:00
* Example : \ include MatrixBase_isOrthogonal . cpp
* Output : \ verbinclude MatrixBase_isOrthogonal . out
2008-01-06 16:35:21 +00:00
*/
2008-03-10 17:23:11 +00:00
template < typename Derived >
2008-01-05 10:57:14 +00:00
template < typename OtherDerived >
2008-06-24 15:13:00 +00:00
bool MatrixBase < Derived > : : isOrthogonal
2012-06-28 02:08:59 +02:00
( const MatrixBase < OtherDerived > & other , const RealScalar & prec ) const
2008-01-05 10:57:14 +00:00
{
2014-08-01 14:48:22 +02:00
typename internal : : nested_eval < Derived , 2 > : : type nested ( derived ( ) ) ;
typename internal : : nested_eval < OtherDerived , 2 > : : type otherNested ( other . derived ( ) ) ;
2013-06-10 23:40:56 +02:00
return numext : : abs2 ( nested . dot ( otherNested ) ) < = prec * prec * nested . squaredNorm ( ) * otherNested . squaredNorm ( ) ;
2008-01-05 10:57:14 +00:00
}
2008-01-06 16:35:21 +00:00
/** \returns true if *this is approximately an unitary matrix,
* within the precision given by \ a prec . In the case where the \ a Scalar
* type is real numbers , a unitary matrix is an orthogonal matrix , whence the name .
*
* \ note This can be used to check whether a family of vectors forms an orthonormal basis .
2008-06-24 15:13:00 +00:00
* Indeed , \ c m . isUnitary ( ) returns true if and only if the columns ( equivalently , the rows ) of m form an
2008-01-06 16:35:21 +00:00
* orthonormal basis .
*
2008-06-24 15:13:00 +00:00
* Example : \ include MatrixBase_isUnitary . cpp
* Output : \ verbinclude MatrixBase_isUnitary . out
2008-01-06 16:35:21 +00:00
*/
2008-03-10 17:23:11 +00:00
template < typename Derived >
2012-06-28 02:08:59 +02:00
bool MatrixBase < Derived > : : isUnitary ( const RealScalar & prec ) const
2008-01-05 10:57:14 +00:00
{
2015-03-24 13:42:42 +01:00
typename internal : : nested_eval < Derived , 1 > : : type self ( derived ( ) ) ;
2010-05-30 16:00:58 -04:00
for ( Index i = 0 ; i < cols ( ) ; + + i )
2008-01-05 10:57:14 +00:00
{
2015-03-24 13:42:42 +01:00
if ( ! internal : : isApprox ( self . col ( i ) . squaredNorm ( ) , static_cast < RealScalar > ( 1 ) , prec ) )
2008-01-05 10:57:14 +00:00
return false ;
2010-05-30 16:00:58 -04:00
for ( Index j = 0 ; j < i ; + + j )
2015-03-24 13:42:42 +01:00
if ( ! internal : : isMuchSmallerThan ( self . col ( i ) . dot ( self . col ( j ) ) , static_cast < Scalar > ( 1 ) , prec ) )
2008-01-05 10:57:14 +00:00
return false ;
}
return true ;
}
2010-06-19 23:36:38 +02:00
2012-04-15 11:06:28 +01:00
} // end namespace Eigen
2007-11-26 08:47:07 +00:00
# endif // EIGEN_DOT_H