mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Apply clang-format
This commit is contained in:
@@ -16,159 +16,166 @@
|
||||
namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment
|
||||
*
|
||||
*/
|
||||
template<typename DstScalar,typename SrcScalar> struct assign_op {
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment
|
||||
*
|
||||
*/
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct assign_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a = b; }
|
||||
|
||||
template<int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,b); }
|
||||
template <int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
|
||||
internal::pstoret<DstScalar, Packet, Alignment>(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
// Empty overload for void type (used by PermutationMatrix)
|
||||
template<typename DstScalar> struct assign_op<DstScalar,void> {};
|
||||
template <typename DstScalar>
|
||||
struct assign_op<DstScalar, void> {};
|
||||
|
||||
template<typename DstScalar,typename SrcScalar>
|
||||
struct functor_traits<assign_op<DstScalar,SrcScalar> > {
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<assign_op<DstScalar, SrcScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<DstScalar>::ReadCost,
|
||||
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::Vectorizable && packet_traits<SrcScalar>::Vectorizable
|
||||
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::Vectorizable &&
|
||||
packet_traits<SrcScalar>::Vectorizable
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment with addition
|
||||
*
|
||||
*/
|
||||
template<typename DstScalar,typename SrcScalar> struct add_assign_op {
|
||||
|
||||
* \brief Template functor for scalar/packet assignment with addition
|
||||
*
|
||||
*/
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct add_assign_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a += b; }
|
||||
|
||||
template<int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::padd(internal::ploadt<Packet,Alignment>(a),b)); }
|
||||
template <int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
|
||||
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::padd(internal::ploadt<Packet, Alignment>(a), b));
|
||||
}
|
||||
};
|
||||
template<typename DstScalar,typename SrcScalar>
|
||||
struct functor_traits<add_assign_op<DstScalar,SrcScalar> > {
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<add_assign_op<DstScalar, SrcScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
|
||||
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasAdd
|
||||
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasAdd
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment with subtraction
|
||||
*
|
||||
*/
|
||||
template<typename DstScalar,typename SrcScalar> struct sub_assign_op {
|
||||
|
||||
* \brief Template functor for scalar/packet assignment with subtraction
|
||||
*
|
||||
*/
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct sub_assign_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a -= b; }
|
||||
|
||||
template<int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::psub(internal::ploadt<Packet,Alignment>(a),b)); }
|
||||
template <int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
|
||||
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::psub(internal::ploadt<Packet, Alignment>(a), b));
|
||||
}
|
||||
};
|
||||
template<typename DstScalar,typename SrcScalar>
|
||||
struct functor_traits<sub_assign_op<DstScalar,SrcScalar> > {
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<sub_assign_op<DstScalar, SrcScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::AddCost,
|
||||
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasSub
|
||||
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasSub
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment with multiplication
|
||||
*
|
||||
*/
|
||||
template<typename DstScalar, typename SrcScalar=DstScalar>
|
||||
* \brief Template functor for scalar/packet assignment with multiplication
|
||||
*
|
||||
*/
|
||||
template <typename DstScalar, typename SrcScalar = DstScalar>
|
||||
struct mul_assign_op {
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a *= b; }
|
||||
|
||||
template<int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pmul(internal::ploadt<Packet,Alignment>(a),b)); }
|
||||
template <int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
|
||||
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::pmul(internal::ploadt<Packet, Alignment>(a), b));
|
||||
}
|
||||
};
|
||||
template<typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<mul_assign_op<DstScalar,SrcScalar> > {
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<mul_assign_op<DstScalar, SrcScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
|
||||
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasMul
|
||||
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasMul
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment with diviving
|
||||
*
|
||||
*/
|
||||
template<typename DstScalar, typename SrcScalar=DstScalar> struct div_assign_op {
|
||||
|
||||
* \brief Template functor for scalar/packet assignment with diviving
|
||||
*
|
||||
*/
|
||||
template <typename DstScalar, typename SrcScalar = DstScalar>
|
||||
struct div_assign_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(DstScalar& a, const SrcScalar& b) const { a /= b; }
|
||||
|
||||
template<int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const
|
||||
{ internal::pstoret<DstScalar,Packet,Alignment>(a,internal::pdiv(internal::ploadt<Packet,Alignment>(a),b)); }
|
||||
template <int Alignment, typename Packet>
|
||||
EIGEN_STRONG_INLINE void assignPacket(DstScalar* a, const Packet& b) const {
|
||||
internal::pstoret<DstScalar, Packet, Alignment>(a, internal::pdiv(internal::ploadt<Packet, Alignment>(a), b));
|
||||
}
|
||||
};
|
||||
template<typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<div_assign_op<DstScalar,SrcScalar> > {
|
||||
template <typename DstScalar, typename SrcScalar>
|
||||
struct functor_traits<div_assign_op<DstScalar, SrcScalar> > {
|
||||
enum {
|
||||
Cost = NumTraits<DstScalar>::ReadCost + NumTraits<DstScalar>::MulCost,
|
||||
PacketAccess = is_same<DstScalar,SrcScalar>::value && packet_traits<DstScalar>::HasDiv
|
||||
PacketAccess = is_same<DstScalar, SrcScalar>::value && packet_traits<DstScalar>::HasDiv
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor for scalar/packet assignment with swapping
|
||||
*
|
||||
* It works as follow. For a non-vectorized evaluation loop, we have:
|
||||
* for(i) func(A.coeffRef(i), B.coeff(i));
|
||||
* where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
|
||||
* Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
|
||||
* B.coeff already returns a const reference to the underlying scalar value.
|
||||
*
|
||||
* The case of a vectorized loop is more tricky:
|
||||
* for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
|
||||
* Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
|
||||
* the actual alignment and Packet type.
|
||||
*
|
||||
*/
|
||||
template<typename Scalar> struct swap_assign_op {
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const
|
||||
{
|
||||
* \brief Template functor for scalar/packet assignment with swapping
|
||||
*
|
||||
* It works as follow. For a non-vectorized evaluation loop, we have:
|
||||
* for(i) func(A.coeffRef(i), B.coeff(i));
|
||||
* where B is a SwapWrapper expression. The trick is to make SwapWrapper::coeff behaves like a non-const coeffRef.
|
||||
* Actually, SwapWrapper might not even be needed since even if B is a plain expression, since it has to be writable
|
||||
* B.coeff already returns a const reference to the underlying scalar value.
|
||||
*
|
||||
* The case of a vectorized loop is more tricky:
|
||||
* for(i,j) func.assignPacket<A_Align>(&A.coeffRef(i,j), B.packet<B_Align>(i,j));
|
||||
* Here, B must be a SwapWrapper whose packet function actually returns a proxy object holding a Scalar*,
|
||||
* the actual alignment and Packet type.
|
||||
*
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct swap_assign_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void assignCoeff(Scalar& a, const Scalar& b) const {
|
||||
#ifdef EIGEN_GPUCC
|
||||
// FIXME is there some kind of cuda::swap?
|
||||
Scalar t=b; const_cast<Scalar&>(b)=a; a=t;
|
||||
Scalar t = b;
|
||||
const_cast<Scalar&>(b) = a;
|
||||
a = t;
|
||||
#else
|
||||
using std::swap;
|
||||
swap(a,const_cast<Scalar&>(b));
|
||||
swap(a, const_cast<Scalar&>(b));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
template<typename Scalar>
|
||||
template <typename Scalar>
|
||||
struct functor_traits<swap_assign_op<Scalar> > {
|
||||
enum {
|
||||
Cost = 3 * NumTraits<Scalar>::ReadCost,
|
||||
PacketAccess =
|
||||
#if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8,0,0) || EIGEN_COMP_CLANGAPPLE)
|
||||
// This is a partial workaround for a bug in clang generating bad code
|
||||
// when mixing 256/512 bits loads and 128 bits moves.
|
||||
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=40815
|
||||
PacketAccess =
|
||||
#if defined(EIGEN_VECTORIZE_AVX) && (EIGEN_CLANG_STRICT_LESS_THAN(8, 0, 0) || EIGEN_COMP_CLANGAPPLE)
|
||||
// This is a partial workaround for a bug in clang generating bad code
|
||||
// when mixing 256/512 bits loads and 128 bits moves.
|
||||
// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=1684
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=40815
|
||||
0
|
||||
#else
|
||||
packet_traits<Scalar>::Vectorizable
|
||||
#endif
|
||||
#else
|
||||
packet_traits<Scalar>::Vectorizable
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace internal
|
||||
|
||||
} // namespace Eigen
|
||||
} // namespace Eigen
|
||||
|
||||
#endif // EIGEN_ASSIGNMENT_FUNCTORS_H
|
||||
#endif // EIGEN_ASSIGNMENT_FUNCTORS_H
|
||||
|
||||
@@ -19,108 +19,114 @@ namespace internal {
|
||||
|
||||
//---------- associative binary functors ----------
|
||||
|
||||
template<typename Arg1, typename Arg2>
|
||||
struct binary_op_base
|
||||
{
|
||||
template <typename Arg1, typename Arg2>
|
||||
struct binary_op_base {
|
||||
typedef Arg1 first_argument_type;
|
||||
typedef Arg2 second_argument_type;
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the sum of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_sum_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_sum_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the sum of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, DenseBase::sum()
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_sum_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_sum_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_sum_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
scalar_sum_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::padd(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
|
||||
{ return internal::predux(a); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
|
||||
operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a + b;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::padd(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
|
||||
return internal::predux(a);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_sum_op<LhsScalar,RhsScalar> > {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_sum_op<LhsScalar, RhsScalar>> {
|
||||
enum {
|
||||
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2, // rough estimate!
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
|
||||
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2, // rough estimate!
|
||||
PacketAccess =
|
||||
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
|
||||
// TODO vectorize mixed sum
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a || b; }
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool, bool>::operator()(const bool& a, const bool& b) const {
|
||||
return a || b;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the product of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the product of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_product_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_product_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_product_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
scalar_product_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pmul(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
|
||||
{ return internal::predux_mul(a); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
|
||||
operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a * b;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::pmul(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
|
||||
return internal::predux_mul(a);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_product_op<LhsScalar, RhsScalar>> {
|
||||
enum {
|
||||
Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost))/2, // rough estimate!
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
|
||||
Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost)) / 2, // rough estimate!
|
||||
PacketAccess =
|
||||
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
|
||||
// TODO vectorize mixed product
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a && b; }
|
||||
|
||||
template <>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool, bool>::operator()(const bool& a,
|
||||
const bool& b) const {
|
||||
return a && b;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the conjugate product of two scalars
|
||||
*
|
||||
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_conj_product_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
* \brief Template functor to compute the conjugate product of two scalars
|
||||
*
|
||||
* This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x
|
||||
* * conj(y)
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_conj_product_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
enum { Conj = NumTraits<LhsScalar>::IsComplex };
|
||||
|
||||
enum {
|
||||
Conj = NumTraits<LhsScalar>::IsComplex
|
||||
};
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_conj_product_op>::ReturnType result_type;
|
||||
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return conj_helper<LhsScalar, RhsScalar, Conj, false>().pmul(a, b);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const
|
||||
{ return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return conj_helper<Packet, Packet, Conj, false>().pmul(a, b);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_conj_product_op<LhsScalar, RhsScalar>> {
|
||||
enum {
|
||||
Cost = NumTraits<LhsScalar>::MulCost,
|
||||
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
|
||||
@@ -128,65 +134,59 @@ struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the min of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
|
||||
struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
* \brief Template functor to compute the min of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
|
||||
struct scalar_min_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_min_op>::ReturnType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return internal::pmin<NaNPropagation>(a, b);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{
|
||||
return internal::pmin<NaNPropagation>(a,b);
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::pmin<NaNPropagation>(a, b);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
|
||||
{
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
|
||||
return internal::predux_min<NaNPropagation>(a);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
|
||||
struct functor_traits<scalar_min_op<LhsScalar,RhsScalar, NaNPropagation> > {
|
||||
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
|
||||
struct functor_traits<scalar_min_op<LhsScalar, RhsScalar, NaNPropagation>> {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
|
||||
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the max of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
|
||||
struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
|
||||
return internal::pmax<NaNPropagation>(a,b);
|
||||
* \brief Template functor to compute the max of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
|
||||
struct scalar_max_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_max_op>::ReturnType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return internal::pmax<NaNPropagation>(a, b);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{
|
||||
return internal::pmax<NaNPropagation>(a,b);
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::pmax<NaNPropagation>(a, b);
|
||||
}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
|
||||
{
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const {
|
||||
return internal::predux_max<NaNPropagation>(a);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
|
||||
struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
|
||||
template <typename LhsScalar, typename RhsScalar, int NaNPropagation>
|
||||
struct functor_traits<scalar_max_op<LhsScalar, RhsScalar, NaNPropagation>> {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
|
||||
PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
|
||||
};
|
||||
};
|
||||
@@ -195,8 +195,7 @@ struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
|
||||
* \brief Template functors for comparison of two scalars
|
||||
* \todo Implement packet-comparisons
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp,
|
||||
bool UseTypedComparators = false>
|
||||
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp, bool UseTypedComparators = false>
|
||||
struct scalar_cmp_op;
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp, bool UseTypedComparators>
|
||||
@@ -311,42 +310,36 @@ struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_NEQ, UseTypedComparators> : binar
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
|
||||
*
|
||||
* \sa MatrixBase::stableNorm(), class Redux
|
||||
*/
|
||||
template<typename Scalar>
|
||||
struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
|
||||
{
|
||||
* \brief Template functor to compute the hypot of two \b positive \b and \b real scalars
|
||||
*
|
||||
* \sa MatrixBase::stableNorm(), class Redux
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_hypot_op<Scalar, Scalar> : binary_op_base<Scalar, Scalar> {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(const Scalar& x, const Scalar& y) const {
|
||||
// This functor is used by hypotNorm only for which it is faster to first apply abs
|
||||
// on all coefficients prior to reduction through hypot.
|
||||
// This way we avoid calling abs on positive and real entries, and this also permits
|
||||
// to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
|
||||
// through the same functor...
|
||||
return internal::positive_real_hypot(x,y);
|
||||
return internal::positive_real_hypot(x, y);
|
||||
}
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
|
||||
enum
|
||||
{
|
||||
Cost = 3 * NumTraits<Scalar>::AddCost +
|
||||
2 * NumTraits<Scalar>::MulCost +
|
||||
2 * scalar_div_cost<Scalar,false>::value,
|
||||
template <typename Scalar>
|
||||
struct functor_traits<scalar_hypot_op<Scalar, Scalar>> {
|
||||
enum {
|
||||
Cost = 3 * NumTraits<Scalar>::AddCost + 2 * NumTraits<Scalar>::MulCost + 2 * scalar_div_cost<Scalar, false>::value,
|
||||
PacketAccess = false
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the pow of two scalars
|
||||
* See the specification of pow in https://en.cppreference.com/w/cpp/numeric/math/pow
|
||||
*/
|
||||
template<typename Scalar, typename Exponent>
|
||||
struct scalar_pow_op : binary_op_base<Scalar,Exponent>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the pow of two scalars
|
||||
* See the specification of pow in https://en.cppreference.com/w/cpp/numeric/math/pow
|
||||
*/
|
||||
template <typename Scalar, typename Exponent>
|
||||
struct scalar_pow_op : binary_op_base<Scalar, Exponent> {
|
||||
typedef typename ScalarBinaryOpTraits<Scalar, Exponent, scalar_pow_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_pow_op() {
|
||||
typedef Scalar LhsScalar;
|
||||
@@ -355,64 +348,62 @@ struct scalar_pow_op : binary_op_base<Scalar,Exponent>
|
||||
}
|
||||
#endif
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
|
||||
EIGEN_DEVICE_FUNC inline result_type operator()(const Scalar& a, const Exponent& b) const {
|
||||
return numext::pow(a, b);
|
||||
}
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{
|
||||
return generic_pow(a,b);
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return generic_pow(a, b);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, typename Exponent>
|
||||
struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
|
||||
template <typename Scalar, typename Exponent>
|
||||
struct functor_traits<scalar_pow_op<Scalar, Exponent>> {
|
||||
enum {
|
||||
Cost = 5 * NumTraits<Scalar>::MulCost,
|
||||
PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger &&
|
||||
packet_traits<Scalar>::HasExp && packet_traits<Scalar>::HasLog &&
|
||||
packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
|
||||
PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger && packet_traits<Scalar>::HasExp &&
|
||||
packet_traits<Scalar>::HasLog && packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
|
||||
// Temporarily disable packet access for half/bfloat16 until
|
||||
// accuracy is improved.
|
||||
!is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value
|
||||
)
|
||||
!is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value)
|
||||
};
|
||||
};
|
||||
|
||||
//---------- non associative binary functors ----------
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_difference_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::operator-
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_difference_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_difference_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_difference_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
scalar_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::psub(a,b); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
|
||||
operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a - b;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::psub(a, b);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_difference_op<LhsScalar, RhsScalar>> {
|
||||
enum {
|
||||
Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
|
||||
PacketAccess =
|
||||
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
|
||||
};
|
||||
};
|
||||
|
||||
template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
|
||||
struct maybe_raise_div_by_zero {
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Packet x) {
|
||||
EIGEN_UNUSED_VARIABLE(x);
|
||||
}
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void run(Packet x) { EIGEN_UNUSED_VARIABLE(x); }
|
||||
};
|
||||
|
||||
#ifndef EIGEN_GPU_COMPILE_PHASE
|
||||
@@ -431,40 +422,41 @@ struct maybe_raise_div_by_zero<Packet, true> {
|
||||
#endif
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the quotient of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator/()
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_quotient_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the quotient of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, Cwise::operator/()
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_quotient_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_quotient_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_quotient_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
scalar_quotient_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
|
||||
operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a / b;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
maybe_raise_div_by_zero<Packet>::run(b);
|
||||
return internal::pdiv(a,b);
|
||||
return internal::pdiv(a, b);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
|
||||
typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_quotient_op<LhsScalar, RhsScalar>> {
|
||||
typedef typename scalar_quotient_op<LhsScalar, RhsScalar>::result_type result_type;
|
||||
enum {
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
|
||||
Cost = scalar_div_cost<result_type,PacketAccess>::value
|
||||
PacketAccess =
|
||||
is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
|
||||
Cost = scalar_div_cost<result_type, PacketAccess>::value
|
||||
};
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the and of two scalars as if they were booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator&&
|
||||
*/
|
||||
* \brief Template functor to compute the and of two scalars as if they were booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator&&
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_and_op {
|
||||
using result_type = Scalar;
|
||||
@@ -489,10 +481,10 @@ struct functor_traits<scalar_boolean_and_op<Scalar>> {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the or of two scalars as if they were booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator||
|
||||
*/
|
||||
* \brief Template functor to compute the or of two scalars as if they were booleans
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator||
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_boolean_or_op {
|
||||
using result_type = Scalar;
|
||||
@@ -588,10 +580,10 @@ struct bitwise_binary_impl<Scalar, true> {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the bitwise and of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator&
|
||||
*/
|
||||
* \brief Template functor to compute the bitwise and of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator&
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_and_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
@@ -612,10 +604,10 @@ struct functor_traits<scalar_bitwise_and_op<Scalar>> {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the bitwise or of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator|
|
||||
*/
|
||||
* \brief Template functor to compute the bitwise or of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator|
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_or_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
@@ -636,10 +628,10 @@ struct functor_traits<scalar_bitwise_or_op<Scalar>> {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the bitwise xor of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator^
|
||||
*/
|
||||
* \brief Template functor to compute the bitwise xor of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, ArrayBase::operator^
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_xor_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
@@ -660,39 +652,39 @@ struct functor_traits<scalar_bitwise_xor_op<Scalar>> {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the absolute difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
|
||||
*/
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct scalar_absolute_difference_op : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_absolute_difference_op>::ReturnType result_type;
|
||||
* \brief Template functor to compute the absolute difference of two scalars
|
||||
*
|
||||
* \sa class CwiseBinaryOp, MatrixBase::absolute_difference
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_absolute_difference_op : binary_op_base<LhsScalar, RhsScalar> {
|
||||
typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_absolute_difference_op>::ReturnType result_type;
|
||||
#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
scalar_absolute_difference_op() {
|
||||
EIGEN_SCALAR_BINARY_OP_PLUGIN
|
||||
}
|
||||
scalar_absolute_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
|
||||
#endif
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
|
||||
{ return numext::absdiff(a,b); }
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pabsdiff(a,b); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type
|
||||
operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return numext::absdiff(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
return internal::pabsdiff(a, b);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_absolute_difference_op<LhsScalar,RhsScalar> > {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_absolute_difference_op<LhsScalar, RhsScalar>> {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
|
||||
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
|
||||
PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_atan2_op {
|
||||
using Scalar = LhsScalar;
|
||||
|
||||
static constexpr bool Enable = is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
|
||||
static constexpr bool Enable =
|
||||
is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
|
||||
EIGEN_STATIC_ASSERT(Enable, "LhsScalar and RhsScalar must be the same non-integer, non-complex type")
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& y, const Scalar& x) const {
|
||||
@@ -704,61 +696,68 @@ struct scalar_atan2_op {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename LhsScalar,typename RhsScalar>
|
||||
struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
|
||||
template <typename LhsScalar, typename RhsScalar>
|
||||
struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
|
||||
using Scalar = LhsScalar;
|
||||
enum {
|
||||
PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<Scalar>::HasATan && packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
|
||||
PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<Scalar>::HasATan &&
|
||||
packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
|
||||
Cost = int(scalar_div_cost<Scalar, PacketAccess>::value) + int(functor_traits<scalar_atan_op<Scalar>>::Cost)
|
||||
};
|
||||
};
|
||||
|
||||
//---------- binary functors bound to a constant, thus appearing as a unary functor ----------
|
||||
|
||||
// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
|
||||
// They are analogues to std::binder1st/binder2nd but with the following differences:
|
||||
// The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant
|
||||
// value. They are analogues to std::binder1st/binder2nd but with the following differences:
|
||||
// - they are compatible with packetOp
|
||||
// - they are portable across C++ versions (the std::binder* are deprecated in C++11)
|
||||
template<typename BinaryOp> struct bind1st_op : BinaryOp {
|
||||
|
||||
typedef typename BinaryOp::first_argument_type first_argument_type;
|
||||
template <typename BinaryOp>
|
||||
struct bind1st_op : BinaryOp {
|
||||
typedef typename BinaryOp::first_argument_type first_argument_type;
|
||||
typedef typename BinaryOp::second_argument_type second_argument_type;
|
||||
typedef typename BinaryOp::result_type result_type;
|
||||
typedef typename BinaryOp::result_type result_type;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit bind1st_op(const first_argument_type &val) : m_value(val) {}
|
||||
EIGEN_DEVICE_FUNC explicit bind1st_op(const first_argument_type& val) : m_value(val) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator()(const second_argument_type& b) const {
|
||||
return BinaryOp::operator()(m_value, b);
|
||||
}
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
|
||||
{ return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const {
|
||||
return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b);
|
||||
}
|
||||
|
||||
first_argument_type m_value;
|
||||
};
|
||||
template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
|
||||
template <typename BinaryOp>
|
||||
struct functor_traits<bind1st_op<BinaryOp>> : functor_traits<BinaryOp> {};
|
||||
|
||||
|
||||
template<typename BinaryOp> struct bind2nd_op : BinaryOp {
|
||||
|
||||
typedef typename BinaryOp::first_argument_type first_argument_type;
|
||||
template <typename BinaryOp>
|
||||
struct bind2nd_op : BinaryOp {
|
||||
typedef typename BinaryOp::first_argument_type first_argument_type;
|
||||
typedef typename BinaryOp::second_argument_type second_argument_type;
|
||||
typedef typename BinaryOp::result_type result_type;
|
||||
typedef typename BinaryOp::result_type result_type;
|
||||
|
||||
EIGEN_DEVICE_FUNC explicit bind2nd_op(const second_argument_type &val) : m_value(val) {}
|
||||
EIGEN_DEVICE_FUNC explicit bind2nd_op(const second_argument_type& val) : m_value(val) {}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator()(const first_argument_type& a) const {
|
||||
return BinaryOp::operator()(a, m_value);
|
||||
}
|
||||
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
|
||||
{ return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const {
|
||||
return BinaryOp::packetOp(a, internal::pset1<Packet>(m_value));
|
||||
}
|
||||
|
||||
second_argument_type m_value;
|
||||
};
|
||||
template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
|
||||
template <typename BinaryOp>
|
||||
struct functor_traits<bind2nd_op<BinaryOp>> : functor_traits<BinaryOp> {};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace Eigen
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_BINARY_FUNCTORS_H
|
||||
#endif // EIGEN_BINARY_FUNCTORS_H
|
||||
|
||||
@@ -17,67 +17,75 @@ namespace Eigen {
|
||||
|
||||
namespace internal {
|
||||
|
||||
template<typename Scalar>
|
||||
template <typename Scalar>
|
||||
struct scalar_constant_op {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
|
||||
template<typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) {}
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()() const { return m_other; }
|
||||
template <typename PacketType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const {
|
||||
return internal::pset1<PacketType>(m_other);
|
||||
}
|
||||
const Scalar m_other;
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_constant_op<Scalar> >
|
||||
{ enum { Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
|
||||
PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
|
||||
|
||||
template<typename Scalar> struct scalar_identity_op {
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType row, IndexType col) const { return row==col ? Scalar(1) : Scalar(0); }
|
||||
template <typename Scalar>
|
||||
struct functor_traits<scalar_constant_op<Scalar> > {
|
||||
enum {
|
||||
Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
|
||||
PacketAccess = packet_traits<Scalar>::Vectorizable,
|
||||
IsRepeatable = true
|
||||
};
|
||||
};
|
||||
template<typename Scalar>
|
||||
struct functor_traits<scalar_identity_op<Scalar> >
|
||||
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
|
||||
|
||||
template <typename Scalar, bool IsInteger> struct linspaced_op_impl;
|
||||
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,/*IsInteger*/false>
|
||||
{
|
||||
struct scalar_identity_op {
|
||||
template <typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType row, IndexType col) const {
|
||||
return row == col ? Scalar(1) : Scalar(0);
|
||||
}
|
||||
};
|
||||
template <typename Scalar>
|
||||
struct functor_traits<scalar_identity_op<Scalar> > {
|
||||
enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true };
|
||||
};
|
||||
|
||||
template <typename Scalar, bool IsInteger>
|
||||
struct linspaced_op_impl;
|
||||
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar, /*IsInteger*/ false> {
|
||||
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||
|
||||
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low), m_high(high), m_size1(num_steps==1 ? 1 : num_steps-1), m_step(num_steps==1 ? Scalar() : Scalar((high-low)/RealScalar(num_steps-1))),
|
||||
m_flip(numext::abs(high)<numext::abs(low))
|
||||
{}
|
||||
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps)
|
||||
: m_low(low),
|
||||
m_high(high),
|
||||
m_size1(num_steps == 1 ? 1 : num_steps - 1),
|
||||
m_step(num_steps == 1 ? Scalar() : Scalar((high - low) / RealScalar(num_steps - 1))),
|
||||
m_flip(numext::abs(high) < numext::abs(low)) {}
|
||||
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const {
|
||||
if(m_flip)
|
||||
return (i==0)? m_low : Scalar(m_high - RealScalar(m_size1-i)*m_step);
|
||||
template <typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
|
||||
if (m_flip)
|
||||
return (i == 0) ? m_low : Scalar(m_high - RealScalar(m_size1 - i) * m_step);
|
||||
else
|
||||
return (i==m_size1)? m_high : Scalar(m_low + RealScalar(i)*m_step);
|
||||
return (i == m_size1) ? m_high : Scalar(m_low + RealScalar(i) * m_step);
|
||||
}
|
||||
|
||||
template<typename Packet, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const
|
||||
{
|
||||
template <typename Packet, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const {
|
||||
// Principle:
|
||||
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
|
||||
if(m_flip)
|
||||
{
|
||||
Packet pi = plset<Packet>(Scalar(i-m_size1));
|
||||
if (m_flip) {
|
||||
Packet pi = plset<Packet>(Scalar(i - m_size1));
|
||||
Packet res = padd(pset1<Packet>(m_high), pmul(pset1<Packet>(m_step), pi));
|
||||
if (EIGEN_PREDICT_TRUE(i != 0)) return res;
|
||||
Packet mask = pcmp_lt(pset1<Packet>(0), plset<Packet>(0));
|
||||
return pselect<Packet>(mask, res, pset1<Packet>(m_low));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Packet pi = plset<Packet>(Scalar(i));
|
||||
Packet res = padd(pset1<Packet>(m_low), pmul(pset1<Packet>(m_step), pi));
|
||||
if(EIGEN_PREDICT_TRUE(i != m_size1-unpacket_traits<Packet>::size+1)) return res;
|
||||
Packet mask = pcmp_lt(plset<Packet>(0), pset1<Packet>(unpacket_traits<Packet>::size-1));
|
||||
if (EIGEN_PREDICT_TRUE(i != m_size1 - unpacket_traits<Packet>::size + 1)) return res;
|
||||
Packet mask = pcmp_lt(plset<Packet>(0), pset1<Packet>(unpacket_traits<Packet>::size - 1));
|
||||
return pselect<Packet>(mask, res, pset1<Packet>(m_high));
|
||||
}
|
||||
}
|
||||
@@ -90,21 +98,20 @@ struct linspaced_op_impl<Scalar,/*IsInteger*/false>
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct linspaced_op_impl<Scalar,/*IsInteger*/true>
|
||||
{
|
||||
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps) :
|
||||
m_low(low),
|
||||
m_multiplier((high-low)/convert_index<Scalar>(num_steps<=1 ? 1 : num_steps-1)),
|
||||
m_divisor(convert_index<Scalar>((high>=low?num_steps:-num_steps)+(high-low))/((numext::abs(high-low)+1)==0?1:(numext::abs(high-low)+1))),
|
||||
m_use_divisor(num_steps>1 && (numext::abs(high-low)+1)<num_steps)
|
||||
{}
|
||||
struct linspaced_op_impl<Scalar, /*IsInteger*/ true> {
|
||||
EIGEN_DEVICE_FUNC linspaced_op_impl(const Scalar& low, const Scalar& high, Index num_steps)
|
||||
: m_low(low),
|
||||
m_multiplier((high - low) / convert_index<Scalar>(num_steps <= 1 ? 1 : num_steps - 1)),
|
||||
m_divisor(convert_index<Scalar>((high >= low ? num_steps : -num_steps) + (high - low)) /
|
||||
((numext::abs(high - low) + 1) == 0 ? 1 : (numext::abs(high - low) + 1))),
|
||||
m_use_divisor(num_steps > 1 && (numext::abs(high - low) + 1) < num_steps) {}
|
||||
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
|
||||
const Scalar operator() (IndexType i) const
|
||||
{
|
||||
if(m_use_divisor) return m_low + convert_index<Scalar>(i)/m_divisor;
|
||||
else return m_low + convert_index<Scalar>(i)*m_multiplier;
|
||||
template <typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
|
||||
if (m_use_divisor)
|
||||
return m_low + convert_index<Scalar>(i) / m_divisor;
|
||||
else
|
||||
return m_low + convert_index<Scalar>(i) * m_multiplier;
|
||||
}
|
||||
|
||||
const Scalar m_low;
|
||||
@@ -118,32 +125,37 @@ struct linspaced_op_impl<Scalar,/*IsInteger*/true>
|
||||
// Forward declaration (we default to random access which does not really give
|
||||
// us a speed gain when using packet access but it allows to use the functor in
|
||||
// nested expressions).
|
||||
template <typename Scalar> struct linspaced_op;
|
||||
template <typename Scalar> struct functor_traits< linspaced_op<Scalar> >
|
||||
{
|
||||
enum
|
||||
{
|
||||
template <typename Scalar>
|
||||
struct linspaced_op;
|
||||
template <typename Scalar>
|
||||
struct functor_traits<linspaced_op<Scalar> > {
|
||||
enum {
|
||||
Cost = 1,
|
||||
PacketAccess = (!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasBlend,
|
||||
/*&& ((!NumTraits<Scalar>::IsInteger) || packet_traits<Scalar>::HasDiv),*/ // <- vectorization for integer is currently disabled
|
||||
PacketAccess =
|
||||
(!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasBlend,
|
||||
/*&& ((!NumTraits<Scalar>::IsInteger) || packet_traits<Scalar>::HasDiv),*/ // <- vectorization for integer is
|
||||
// currently disabled
|
||||
IsRepeatable = true
|
||||
};
|
||||
};
|
||||
template <typename Scalar> struct linspaced_op
|
||||
{
|
||||
template <typename Scalar>
|
||||
struct linspaced_op {
|
||||
EIGEN_DEVICE_FUNC linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
|
||||
: impl((num_steps==1 ? high : low),high,num_steps)
|
||||
{}
|
||||
: impl((num_steps == 1 ? high : low), high, num_steps) {}
|
||||
|
||||
template<typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (IndexType i) const { return impl(i); }
|
||||
template <typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator()(IndexType i) const {
|
||||
return impl(i);
|
||||
}
|
||||
|
||||
template<typename Packet,typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const { return impl.template packetOp<Packet>(i); }
|
||||
template <typename Packet, typename IndexType>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(IndexType i) const {
|
||||
return impl.template packetOp<Packet>(i);
|
||||
}
|
||||
|
||||
// This proxy object handles the actual required temporaries and the different
|
||||
// implementations (integer vs. floating point).
|
||||
const linspaced_op_impl<Scalar,NumTraits<Scalar>::IsInteger> impl;
|
||||
const linspaced_op_impl<Scalar, NumTraits<Scalar>::IsInteger> impl;
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
@@ -183,42 +195,69 @@ struct functor_traits<equalspaced_op<Scalar> > {
|
||||
// If it exposes an operator()(i,j), then we assume the i and j coefficients are required independently
|
||||
// and linear access is not possible. In all other cases, linear access is enabled.
|
||||
// Users should not have to deal with this structure.
|
||||
template<typename Functor> struct functor_has_linear_access { enum { ret = !has_binary_operator<Functor>::value }; };
|
||||
template <typename Functor>
|
||||
struct functor_has_linear_access {
|
||||
enum { ret = !has_binary_operator<Functor>::value };
|
||||
};
|
||||
|
||||
// For unreliable compilers, let's specialize the has_*ary_operator
|
||||
// helpers so that at least built-in nullary functors work fine.
|
||||
#if !( EIGEN_COMP_MSVC || EIGEN_COMP_GNUC || (EIGEN_COMP_ICC>=1600))
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_unary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<scalar_constant_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
#if !(EIGEN_COMP_MSVC || EIGEN_COMP_GNUC || (EIGEN_COMP_ICC >= 1600))
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_nullary_operator<scalar_constant_op<Scalar>, IndexType> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_unary_operator<scalar_constant_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_binary_operator<scalar_constant_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_unary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<scalar_identity_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_nullary_operator<scalar_identity_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_unary_operator<scalar_identity_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_binary_operator<scalar_identity_op<Scalar>, IndexType> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_unary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<linspaced_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_nullary_operator<linspaced_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_unary_operator<linspaced_op<Scalar>, IndexType> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_binary_operator<linspaced_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_nullary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 1}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_unary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template<typename Scalar,typename IndexType>
|
||||
struct has_binary_operator<scalar_random_op<Scalar>,IndexType> { enum { value = 0}; };
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_nullary_operator<scalar_random_op<Scalar>, IndexType> {
|
||||
enum { value = 1 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_unary_operator<scalar_random_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
template <typename Scalar, typename IndexType>
|
||||
struct has_binary_operator<scalar_random_op<Scalar>, IndexType> {
|
||||
enum { value = 0 };
|
||||
};
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_NULLARY_FUNCTORS_H
|
||||
#endif // EIGEN_NULLARY_FUNCTORS_H
|
||||
|
||||
@@ -18,101 +18,123 @@ namespace internal {
|
||||
|
||||
// default functor traits for STL functors:
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::multiplies<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::multiplies<T> > {
|
||||
enum { Cost = NumTraits<T>::MulCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::divides<T> >
|
||||
{ enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::divides<T> > {
|
||||
enum { Cost = NumTraits<T>::MulCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::plus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::plus<T> > {
|
||||
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::minus<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::minus<T> > {
|
||||
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::negate<T> >
|
||||
{ enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::negate<T> > {
|
||||
enum { Cost = NumTraits<T>::AddCost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_or<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::logical_or<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_and<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::logical_and<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::logical_not<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::logical_not<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::greater<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::greater<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::less<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::less<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::greater_equal<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::greater_equal<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::less_equal<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::less_equal<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::equal_to<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct functor_traits<std::not_equal_to<T> >
|
||||
{ enum { Cost = 1, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::not_equal_to<T> > {
|
||||
enum { Cost = 1, PacketAccess = false };
|
||||
};
|
||||
|
||||
#if (EIGEN_COMP_CXXVER < 17)
|
||||
// std::unary_negate is deprecated since c++17 and will be removed in c++20
|
||||
template<typename T>
|
||||
struct functor_traits<std::unary_negate<T> >
|
||||
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::unary_negate<T> > {
|
||||
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false };
|
||||
};
|
||||
|
||||
// std::binary_negate is deprecated since c++17 and will be removed in c++20
|
||||
template<typename T>
|
||||
struct functor_traits<std::binary_negate<T> >
|
||||
{ enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
|
||||
template <typename T>
|
||||
struct functor_traits<std::binary_negate<T> > {
|
||||
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false };
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef EIGEN_STDEXT_SUPPORT
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::project1st<T0,T1> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
template <typename T0, typename T1>
|
||||
struct functor_traits<std::project1st<T0, T1> > {
|
||||
enum { Cost = 0, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::project2nd<T0,T1> >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
template <typename T0, typename T1>
|
||||
struct functor_traits<std::project2nd<T0, T1> > {
|
||||
enum { Cost = 0, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::select2nd<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
template <typename T0, typename T1>
|
||||
struct functor_traits<std::select2nd<std::pair<T0, T1> > > {
|
||||
enum { Cost = 0, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::select1st<std::pair<T0,T1> > >
|
||||
{ enum { Cost = 0, PacketAccess = false }; };
|
||||
template <typename T0, typename T1>
|
||||
struct functor_traits<std::select1st<std::pair<T0, T1> > > {
|
||||
enum { Cost = 0, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T0,typename T1>
|
||||
struct functor_traits<std::unary_compose<T0,T1> >
|
||||
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
|
||||
template <typename T0, typename T1>
|
||||
struct functor_traits<std::unary_compose<T0, T1> > {
|
||||
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false };
|
||||
};
|
||||
|
||||
template<typename T0,typename T1,typename T2>
|
||||
struct functor_traits<std::binary_compose<T0,T1,T2> >
|
||||
{ enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
|
||||
template <typename T0, typename T1, typename T2>
|
||||
struct functor_traits<std::binary_compose<T0, T1, T2> > {
|
||||
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false };
|
||||
};
|
||||
|
||||
#endif // EIGEN_STDEXT_SUPPORT
|
||||
#endif // EIGEN_STDEXT_SUPPORT
|
||||
|
||||
// allow to add new functors and specializations of functor_traits from outside Eigen.
|
||||
// this macro is really needed because functor_traits must be specialized after it is declared but before it is used...
|
||||
@@ -120,8 +142,8 @@ struct functor_traits<std::binary_compose<T0,T1,T2> >
|
||||
#include EIGEN_FUNCTORS_PLUGIN
|
||||
#endif
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_STL_FUNCTORS_H
|
||||
#endif // EIGEN_STL_FUNCTORS_H
|
||||
|
||||
@@ -25,26 +25,28 @@ struct scalar_boolean_select_op {
|
||||
EIGEN_STATIC_ASSERT(ThenElseAreSame, THEN AND ELSE MUST BE SAME TYPE)
|
||||
using Scalar = ThenScalar;
|
||||
using result_type = Scalar;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const ThenScalar& a, const ElseScalar& b, const ConditionScalar& cond) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const ThenScalar& a, const ElseScalar& b,
|
||||
const ConditionScalar& cond) const {
|
||||
return cond == ConditionScalar(0) ? b : a;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b, const Packet& cond) const {
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b, const Packet& cond) const {
|
||||
return pselect(pcmp_eq(cond, pzero(cond)), b, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ThenScalar, typename ElseScalar, typename ConditionScalar>
|
||||
struct functor_traits<scalar_boolean_select_op<ThenScalar, ElseScalar, ConditionScalar>> {
|
||||
struct functor_traits<scalar_boolean_select_op<ThenScalar, ElseScalar, ConditionScalar>> {
|
||||
using Scalar = ThenScalar;
|
||||
enum {
|
||||
Cost = 1,
|
||||
PacketAccess = is_same<ThenScalar, ElseScalar>::value && is_same<ConditionScalar, Scalar>::value && packet_traits<Scalar>::HasCmp
|
||||
PacketAccess = is_same<ThenScalar, ElseScalar>::value && is_same<ConditionScalar, Scalar>::value &&
|
||||
packet_traits<Scalar>::HasCmp
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_TERNARY_FUNCTORS_H
|
||||
#endif // EIGEN_TERNARY_FUNCTORS_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user