mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-11 19:29:02 +08:00
* enable vectorization of sin, cos, etc. by default with an option to
disable them (-DEIGEN_FAST_MATH=0) * add a specialization of MatrixBase::operator*(RealScalar) for fast "matrix of complex" times scalar products (even more useful for autodiff scalar types)
This commit is contained in:
parent
62de40f8bb
commit
ce5669dbf9
@ -82,7 +82,7 @@ Cwise<ExpressionType>::log() const
|
|||||||
* Example: \include Cwise_cos.cpp
|
* Example: \include Cwise_cos.cpp
|
||||||
* Output: \verbinclude Cwise_cos.out
|
* Output: \verbinclude Cwise_cos.out
|
||||||
*
|
*
|
||||||
* \sa sin(), exp()
|
* \sa sin(), exp(), EIGEN_FAST_MATH
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op)
|
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op)
|
||||||
@ -99,7 +99,7 @@ Cwise<ExpressionType>::cos() const
|
|||||||
* Example: \include Cwise_sin.cpp
|
* Example: \include Cwise_sin.cpp
|
||||||
* Output: \verbinclude Cwise_sin.out
|
* Output: \verbinclude Cwise_sin.out
|
||||||
*
|
*
|
||||||
* \sa cos(), exp()
|
* \sa cos(), exp(), EIGEN_FAST_MATH
|
||||||
*/
|
*/
|
||||||
template<typename ExpressionType>
|
template<typename ExpressionType>
|
||||||
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op)
|
inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op)
|
||||||
|
@ -73,10 +73,12 @@ struct ei_functor_traits<ei_scalar_sqrt_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT {
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); }
|
||||||
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return ei_pexp(a); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
|
||||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
|
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::HasExp }; };
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
*
|
*
|
||||||
@ -88,10 +90,12 @@ struct ei_functor_traits<ei_scalar_exp_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT {
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_log(a); }
|
||||||
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return ei_plog(a); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_log_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_log_op<Scalar> >
|
||||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
|
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::HasLog }; };
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
*
|
*
|
||||||
@ -102,11 +106,18 @@ struct ei_functor_traits<ei_scalar_log_op<Scalar> >
|
|||||||
* \sa class CwiseUnaryOp, Cwise::cos()
|
* \sa class CwiseUnaryOp, Cwise::cos()
|
||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_cos_op EIGEN_EMPTY_STRUCT {
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
inline Scalar operator() (const Scalar& a) const { return ei_cos(a); }
|
||||||
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return ei_pcos(a); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
||||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
|
{
|
||||||
|
enum {
|
||||||
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
|
PacketAccess = ei_packet_traits<Scalar>::HasCos && EIGEN_FAST_MATH
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
*
|
*
|
||||||
@ -118,10 +129,17 @@ struct ei_functor_traits<ei_scalar_cos_op<Scalar> >
|
|||||||
*/
|
*/
|
||||||
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
|
template<typename Scalar> struct ei_scalar_sin_op EIGEN_EMPTY_STRUCT {
|
||||||
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
inline const Scalar operator() (const Scalar& a) const { return ei_sin(a); }
|
||||||
|
typedef typename ei_packet_traits<Scalar>::type Packet;
|
||||||
|
inline Packet packetOp(const Packet& a) const { return ei_psin(a); }
|
||||||
};
|
};
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_sin_op<Scalar> >
|
||||||
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
|
{
|
||||||
|
enum {
|
||||||
|
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||||
|
PacketAccess = ei_packet_traits<Scalar>::HasSin && EIGEN_FAST_MATH
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
*
|
*
|
||||||
|
@ -327,6 +327,18 @@ template<typename Scalar>
|
|||||||
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
|
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
|
||||||
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
|
{ enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = ei_packet_traits<Scalar>::size>1 }; };
|
||||||
|
|
||||||
|
template<typename Scalar1, typename Scalar2>
|
||||||
|
struct ei_scalar_multiple2_op {
|
||||||
|
typedef typename ei_scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
|
||||||
|
EIGEN_STRONG_INLINE ei_scalar_multiple2_op(const ei_scalar_multiple2_op& other) : m_other(other.m_other) { }
|
||||||
|
EIGEN_STRONG_INLINE ei_scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
|
||||||
|
EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
|
||||||
|
const Scalar2 m_other;
|
||||||
|
};
|
||||||
|
template<typename Scalar1,typename Scalar2>
|
||||||
|
struct ei_functor_traits<ei_scalar_multiple2_op<Scalar1,Scalar2> >
|
||||||
|
{ enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
|
||||||
|
|
||||||
template<typename Scalar, bool HasFloatingPoint>
|
template<typename Scalar, bool HasFloatingPoint>
|
||||||
struct ei_scalar_quotient1_impl {
|
struct ei_scalar_quotient1_impl {
|
||||||
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
|
||||||
|
@ -53,10 +53,17 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template<typename Derived> class MatrixBase
|
template<typename Derived> class MatrixBase
|
||||||
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
: public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
|
||||||
|
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>
|
||||||
|
#endif // not EIGEN_PARSED_BY_DOXYGEN
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
using ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar,
|
||||||
|
typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>::operator*;
|
||||||
|
|
||||||
class InnerIterator;
|
class InnerIterator;
|
||||||
|
|
||||||
typedef typename ei_traits<Derived>::Scalar Scalar;
|
typedef typename ei_traits<Derived>::Scalar Scalar;
|
||||||
@ -324,6 +331,9 @@ template<typename Derived> class MatrixBase
|
|||||||
Derived& operator/=(const Scalar& other);
|
Derived& operator/=(const Scalar& other);
|
||||||
|
|
||||||
const ScalarMultipleReturnType operator*(const Scalar& scalar) const;
|
const ScalarMultipleReturnType operator*(const Scalar& scalar) const;
|
||||||
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
|
const ScalarMultipleReturnType operator*(const RealScalar& scalar) const;
|
||||||
|
#endif
|
||||||
const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
|
const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived>
|
||||||
operator/(const Scalar& scalar) const;
|
operator/(const Scalar& scalar) const;
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ template<typename Scalar> struct ei_scalar_add_op;
|
|||||||
template<typename Scalar> struct ei_scalar_constant_op;
|
template<typename Scalar> struct ei_scalar_constant_op;
|
||||||
template<typename Scalar> struct ei_scalar_identity_op;
|
template<typename Scalar> struct ei_scalar_identity_op;
|
||||||
|
|
||||||
|
template<typename Scalar1,typename Scalar2> struct ei_scalar_multiple2_op;
|
||||||
|
|
||||||
struct IOFormat;
|
struct IOFormat;
|
||||||
|
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
|
@ -60,15 +60,15 @@
|
|||||||
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ColMajor
|
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION ColMajor
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \internal Defines the maximal loop size to enable meta unrolling of loops.
|
/** Defines the maximal loop size to enable meta unrolling of loops.
|
||||||
* Note that the value here is expressed in Eigen's own notion of "number of FLOPS",
|
* Note that the value here is expressed in Eigen's own notion of "number of FLOPS",
|
||||||
* it does not correspond to the number of iterations or the number of instructions
|
* it does not correspond to the number of iterations or the number of instructions
|
||||||
*/
|
*/
|
||||||
#ifndef EIGEN_UNROLLING_LIMIT
|
#ifndef EIGEN_UNROLLING_LIMIT
|
||||||
#define EIGEN_UNROLLING_LIMIT 100
|
#define EIGEN_UNROLLING_LIMIT 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** \internal Define the maximal size in Bytes of blocks fitting in CPU cache.
|
/** Defines the maximal size in Bytes of blocks fitting in CPU cache.
|
||||||
* The current value is set to generate blocks of 256x256 for float
|
* The current value is set to generate blocks of 256x256 for float
|
||||||
*
|
*
|
||||||
* Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes
|
* Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes
|
||||||
@ -82,6 +82,15 @@
|
|||||||
#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE.
|
#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Allows to disable some optimizations which might affect the accuracy of the result.
|
||||||
|
* Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them.
|
||||||
|
* They currently include:
|
||||||
|
* - single precision Cwise::sin() and Cwise::cos() when SSE vectorization is enabled.
|
||||||
|
*/
|
||||||
|
#ifndef EIGEN_FAST_MATH
|
||||||
|
#define EIGEN_FAST_MATH 1
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USING_PART_OF_NAMESPACE_EIGEN \
|
#define USING_PART_OF_NAMESPACE_EIGEN \
|
||||||
EIGEN_USING_MATRIX_TYPEDEFS \
|
EIGEN_USING_MATRIX_TYPEDEFS \
|
||||||
using Eigen::Matrix; \
|
using Eigen::Matrix; \
|
||||||
|
@ -64,6 +64,14 @@ template<typename T> struct ei_cleantype<T&> { typedef typename ei_cleant
|
|||||||
template<typename T> struct ei_cleantype<const T*> { typedef typename ei_cleantype<T>::type type; };
|
template<typename T> struct ei_cleantype<const T*> { typedef typename ei_cleantype<T>::type type; };
|
||||||
template<typename T> struct ei_cleantype<T*> { typedef typename ei_cleantype<T>::type type; };
|
template<typename T> struct ei_cleantype<T*> { typedef typename ei_cleantype<T>::type type; };
|
||||||
|
|
||||||
|
/** \internal Allows to enable/disable an overload
|
||||||
|
* according to a compile time condition.
|
||||||
|
*/
|
||||||
|
template<bool Condition, typename T> struct ei_enable_if;
|
||||||
|
|
||||||
|
template<typename T> struct ei_enable_if<true,T>
|
||||||
|
{ typedef T type; };
|
||||||
|
|
||||||
/** \internal
|
/** \internal
|
||||||
* Convenient struct to get the result type of a unary or binary functor.
|
* Convenient struct to get the result type of a unary or binary functor.
|
||||||
*
|
*
|
||||||
|
@ -198,6 +198,28 @@ template<unsigned int Flags> struct ei_are_flags_consistent
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** \internal Helper base class to add a scalar multiple operator
|
||||||
|
* overloads for complex types */
|
||||||
|
template<typename Derived,typename Scalar,typename OtherScalar,
|
||||||
|
bool EnableIt = !ei_is_same_type<Scalar,OtherScalar>::ret >
|
||||||
|
struct ei_special_scalar_op_base
|
||||||
|
{
|
||||||
|
// dummy operator* so that the
|
||||||
|
// "using ei_special_scalar_op_base::operator*" compiles
|
||||||
|
void operator*() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Derived,typename Scalar,typename OtherScalar>
|
||||||
|
struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true>
|
||||||
|
{
|
||||||
|
const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||||
|
operator*(const OtherScalar& scalar) const
|
||||||
|
{
|
||||||
|
return CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived>
|
||||||
|
(*static_cast<const Derived*>(this), ei_scalar_multiple2_op<Scalar,OtherScalar>(scalar));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size
|
/** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size
|
||||||
* TODO: could be a good idea to define a big ReturnType struct ??
|
* TODO: could be a good idea to define a big ReturnType struct ??
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user