mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
vectorize comparisons and select by enabling typed comparisons
This commit is contained in:
committed by
Rasmus Munk Larsen
parent
2e9b945baf
commit
826627f653
@@ -567,18 +567,28 @@ template<typename Derived> class DenseBase
|
||||
static const RandomReturnType Random(Index size);
|
||||
static const RandomReturnType Random();
|
||||
|
||||
template<typename ThenDerived,typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
||||
select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
template <typename ThenDerived, typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
CwiseTernaryOp<internal::scalar_boolean_select_op<Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>,
|
||||
Derived, ThenDerived, ElseDerived>
|
||||
select(const DenseBase<ThenDerived>& thenMatrix, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
|
||||
template<typename ThenDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||
select(const DenseBase<ThenDerived>& thenMatrix, const typename ThenDerived::Scalar& elseScalar) const;
|
||||
template <typename ThenDerived>
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
CwiseTernaryOp<internal::scalar_boolean_select_op<Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ThenDerived>::Scalar>,
|
||||
Derived, ThenDerived, typename DenseBase<ThenDerived>::ConstantReturnType>
|
||||
select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
const typename DenseBase<ThenDerived>::Scalar& elseScalar) const;
|
||||
|
||||
template<typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||
select(const typename ElseDerived::Scalar& thenScalar, const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
template <typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC
|
||||
CwiseTernaryOp<internal::scalar_boolean_select_op<Scalar, typename DenseBase<ElseDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>,
|
||||
Derived, typename DenseBase<ElseDerived>::ConstantReturnType, ElseDerived>
|
||||
select(const typename DenseBase<ElseDerived>::Scalar& thenScalar,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const;
|
||||
|
||||
template<int p> RealScalar lpNorm() const;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ struct isApprox_selector
|
||||
{
|
||||
typename internal::nested_eval<Derived,2>::type nested(x);
|
||||
typename internal::nested_eval<OtherDerived,2>::type otherNested(y);
|
||||
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * numext::mini(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||
return (nested.matrix() - otherNested.matrix()).cwiseAbs2().sum() <= prec * prec * numext::mini(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -113,52 +113,63 @@ class Select : public internal::dense_xpr_base< Select<ConditionMatrixType, Then
|
||||
typename ElseMatrixType::Nested m_else;
|
||||
};
|
||||
|
||||
|
||||
/** \returns a matrix where each coefficient (i,j) is equal to \a thenMatrix(i,j)
|
||||
* if \c *this(i,j), and \a elseMatrix(i,j) otherwise.
|
||||
*
|
||||
* Example: \include MatrixBase_select.cpp
|
||||
* Output: \verbinclude MatrixBase_select.out
|
||||
*
|
||||
* \sa class Select
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename ThenDerived,typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived,ElseDerived>
|
||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const
|
||||
{
|
||||
return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived());
|
||||
* if \c *this(i,j) != Scalar(0), and \a elseMatrix(i,j) otherwise.
|
||||
*
|
||||
* Example: \include MatrixBase_select.cpp
|
||||
* Output: \verbinclude MatrixBase_select.out
|
||||
*
|
||||
* \sa DenseBase::bitwiseSelect(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&)
|
||||
*/
|
||||
template <typename Derived>
|
||||
template <typename ThenDerived, typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC CwiseTernaryOp<
|
||||
internal::scalar_boolean_select_op<typename DenseBase<Derived>::Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>,
|
||||
Derived, ThenDerived, ElseDerived>
|
||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, const DenseBase<ElseDerived>& elseMatrix) const {
|
||||
using Op = internal::scalar_boolean_select_op<Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>;
|
||||
return CwiseTernaryOp<Op, Derived, ThenDerived, ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived(),
|
||||
Op());
|
||||
}
|
||||
|
||||
/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
|
||||
* the \em else expression being a scalar value.
|
||||
*
|
||||
* \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename ThenDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType>
|
||||
* the \em else expression being a scalar value.
|
||||
*
|
||||
* \sa DenseBase::booleanSelect(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
|
||||
*/
|
||||
template <typename Derived>
|
||||
template <typename ThenDerived>
|
||||
inline EIGEN_DEVICE_FUNC CwiseTernaryOp<
|
||||
internal::scalar_boolean_select_op<typename DenseBase<Derived>::Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ThenDerived>::Scalar>,
|
||||
Derived, ThenDerived, typename DenseBase<ThenDerived>::ConstantReturnType>
|
||||
DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix,
|
||||
const typename ThenDerived::Scalar& elseScalar) const
|
||||
{
|
||||
return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>(
|
||||
derived(), thenMatrix.derived(), ThenDerived::Constant(rows(),cols(),elseScalar));
|
||||
const typename DenseBase<ThenDerived>::Scalar& elseScalar) const {
|
||||
using ElseConstantType = typename DenseBase<ThenDerived>::ConstantReturnType;
|
||||
using Op = internal::scalar_boolean_select_op<Scalar, typename DenseBase<ThenDerived>::Scalar,
|
||||
typename DenseBase<ThenDerived>::Scalar>;
|
||||
return CwiseTernaryOp<Op, Derived, ThenDerived, ElseConstantType>(derived(), thenMatrix.derived(),
|
||||
ElseConstantType(rows(), cols(), elseScalar), Op());
|
||||
}
|
||||
|
||||
/** Version of DenseBase::select(const DenseBase&, const DenseBase&) with
|
||||
* the \em then expression being a scalar value.
|
||||
*
|
||||
* \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
|
||||
*/
|
||||
template<typename Derived>
|
||||
template<typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived >
|
||||
DenseBase<Derived>::select(const typename ElseDerived::Scalar& thenScalar,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const
|
||||
{
|
||||
return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>(
|
||||
derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived());
|
||||
* the \em then expression being a scalar value.
|
||||
*
|
||||
* \sa DenseBase::booleanSelect(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select
|
||||
*/
|
||||
template <typename Derived>
|
||||
template <typename ElseDerived>
|
||||
inline EIGEN_DEVICE_FUNC CwiseTernaryOp<
|
||||
internal::scalar_boolean_select_op<typename DenseBase<Derived>::Scalar, typename DenseBase<ElseDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>,
|
||||
Derived, typename DenseBase<ElseDerived>::ConstantReturnType, ElseDerived>
|
||||
DenseBase<Derived>::select(const typename DenseBase<ElseDerived>::Scalar& thenScalar,
|
||||
const DenseBase<ElseDerived>& elseMatrix) const {
|
||||
using ThenConstantType = typename DenseBase<ElseDerived>::ConstantReturnType;
|
||||
using Op = internal::scalar_boolean_select_op<Scalar, typename DenseBase<ElseDerived>::Scalar,
|
||||
typename DenseBase<ElseDerived>::Scalar>;
|
||||
return CwiseTernaryOp<Op, Derived, ThenConstantType, ElseDerived>(
|
||||
derived(), ThenConstantType(rows(), cols(), thenScalar), elseMatrix.derived(), Op());
|
||||
}
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -191,91 +191,122 @@ struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functors for comparison of two scalars
|
||||
* \todo Implement packet-comparisons
|
||||
*/
|
||||
template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_op;
|
||||
* \brief Template functors for comparison of two scalars
|
||||
* \todo Implement packet-comparisons
|
||||
*/
|
||||
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp,
|
||||
bool UseTypedComparators = true>
|
||||
struct scalar_cmp_op;
|
||||
|
||||
template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
|
||||
struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
|
||||
template <typename LhsScalar, typename RhsScalar, ComparisonName cmp, bool UseTypedComparators>
|
||||
struct functor_traits<scalar_cmp_op<LhsScalar, RhsScalar, cmp, UseTypedComparators>> {
|
||||
enum {
|
||||
Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
|
||||
PacketAccess = is_same<LhsScalar, RhsScalar>::value &&
|
||||
packet_traits<LhsScalar>::HasCmp &&
|
||||
// Since return type is bool, we currently require the inputs
|
||||
// to be bool to enable packet access.
|
||||
is_same<LhsScalar, bool>::value
|
||||
Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
|
||||
PacketAccess = (UseTypedComparators || is_same<LhsScalar, bool>::value) && is_same<LhsScalar, RhsScalar>::value &&
|
||||
packet_traits<LhsScalar>::HasCmp
|
||||
};
|
||||
};
|
||||
|
||||
template<ComparisonName Cmp, typename LhsScalar, typename RhsScalar>
|
||||
struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
|
||||
typedef bool type;
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct typed_cmp_helper {
|
||||
static constexpr bool SameType = is_same<LhsScalar, RhsScalar>::value;
|
||||
static constexpr bool IsNumeric = is_arithmetic<typename NumTraits<LhsScalar>::Real>::value;
|
||||
static constexpr bool UseTyped = UseTypedComparators && SameType && IsNumeric;
|
||||
using type = typename conditional<UseTyped, LhsScalar, bool>::type;
|
||||
};
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
using cmp_return_t = typename typed_cmp_helper<LhsScalar, RhsScalar, UseTypedComparators>::type;
|
||||
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_eq(a,b); }
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_EQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a == b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pand(pcmp_eq(a, b), cst_one);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_lt(a,b); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a < b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pand(pcmp_lt(a, b), cst_one);
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_le(a,b); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a <= b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pand(cst_one, pcmp_le(a, b));
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_lt(b,a); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a > b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pand(cst_one, pcmp_lt(b, a));
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_le(b,a); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a >= b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pand(cst_one, pcmp_le(b, a));
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);}
|
||||
template<typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
|
||||
{ return internal::pcmp_eq(internal::por(internal::pcmp_le(a, b), internal::pcmp_le(b, a)), internal::pzero(a)); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_UNORD, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return !(a <= b || b <= a) ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pandnot(cst_one, por(pcmp_le(a, b), pcmp_le(b, a)));
|
||||
}
|
||||
};
|
||||
template<typename LhsScalar, typename RhsScalar>
|
||||
struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
|
||||
{
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool 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::pcmp_eq(internal::pcmp_eq(a, b), internal::pzero(a)); }
|
||||
|
||||
template <typename LhsScalar, typename RhsScalar, bool UseTypedComparators>
|
||||
struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_NEQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
|
||||
using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(const LhsScalar& a, const RhsScalar& b) const {
|
||||
return a != b ? result_type(1) : result_type(0);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
const Packet cst_one = pset1<Packet>(result_type(1));
|
||||
return pandnot(cst_one, pcmp_eq(a, b));
|
||||
}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
@@ -511,6 +542,50 @@ struct functor_traits<scalar_boolean_xor_op<Scalar>> {
|
||||
enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
|
||||
};
|
||||
|
||||
template <typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct bitwise_binary_impl {
|
||||
static constexpr size_t Size = sizeof(Scalar);
|
||||
using uint_t = typename numext::get_integer_by_size<Size>::unsigned_type;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(const Scalar& a, const Scalar& b) {
|
||||
uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
|
||||
uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
|
||||
uint_t result = a_as_uint & b_as_uint;
|
||||
return numext::bit_cast<Scalar, uint_t>(result);
|
||||
}
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(const Scalar& a, const Scalar& b) {
|
||||
uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
|
||||
uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
|
||||
uint_t result = a_as_uint | b_as_uint;
|
||||
return numext::bit_cast<Scalar, uint_t>(result);
|
||||
}
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(const Scalar& a, const Scalar& b) {
|
||||
uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
|
||||
uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
|
||||
uint_t result = a_as_uint ^ b_as_uint;
|
||||
return numext::bit_cast<Scalar, uint_t>(result);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct bitwise_binary_impl<Scalar, true> {
|
||||
using Real = typename NumTraits<Scalar>::Real;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(const Scalar& a, const Scalar& b) {
|
||||
Real real_result = bitwise_binary_impl<Real>::run_and(numext::real(a), numext::real(b));
|
||||
Real imag_result = bitwise_binary_impl<Real>::run_and(numext::imag(a), numext::imag(b));
|
||||
return Scalar(real_result, imag_result);
|
||||
}
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(const Scalar& a, const Scalar& b) {
|
||||
Real real_result = bitwise_binary_impl<Real>::run_or(numext::real(a), numext::real(b));
|
||||
Real imag_result = bitwise_binary_impl<Real>::run_or(numext::imag(a), numext::imag(b));
|
||||
return Scalar(real_result, imag_result);
|
||||
}
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(const Scalar& a, const Scalar& b) {
|
||||
Real real_result = bitwise_binary_impl<Real>::run_xor(numext::real(a), numext::real(b));
|
||||
Real imag_result = bitwise_binary_impl<Real>::run_xor(numext::imag(a), numext::imag(b));
|
||||
return Scalar(real_result, imag_result);
|
||||
}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the bitwise and of two scalars
|
||||
*
|
||||
@@ -518,15 +593,12 @@ struct functor_traits<scalar_boolean_xor_op<Scalar>> {
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_and_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization, BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES )
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
|
||||
using result_type = Scalar;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a, const Scalar& b) const {
|
||||
Scalar result;
|
||||
const uint8_t* a_bytes = reinterpret_cast<const uint8_t*>(&a);
|
||||
const uint8_t* b_bytes = reinterpret_cast<const uint8_t*>(&b);
|
||||
uint8_t* r_bytes = reinterpret_cast<uint8_t*>(&result);
|
||||
for (Index i = 0; i < sizeof(Scalar); i++) r_bytes[i] = a_bytes[i] & b_bytes[i];
|
||||
return result;
|
||||
return bitwise_binary_impl<Scalar>::run_and(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
@@ -545,15 +617,12 @@ struct functor_traits<scalar_bitwise_and_op<Scalar>> {
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_or_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization, BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
|
||||
using result_type = Scalar;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a, const Scalar& b) const {
|
||||
Scalar result;
|
||||
const uint8_t* a_bytes = reinterpret_cast<const uint8_t*>(&a);
|
||||
const uint8_t* b_bytes = reinterpret_cast<const uint8_t*>(&b);
|
||||
uint8_t* r_bytes = reinterpret_cast<uint8_t*>(&result);
|
||||
for (Index i = 0; i < sizeof(Scalar); i++) r_bytes[i] = a_bytes[i] | b_bytes[i];
|
||||
return result;
|
||||
return bitwise_binary_impl<Scalar>::run_or(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
@@ -572,15 +641,12 @@ struct functor_traits<scalar_bitwise_or_op<Scalar>> {
|
||||
*/
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_xor_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization, BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
|
||||
BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
|
||||
using result_type = Scalar;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a, const Scalar& b) const {
|
||||
Scalar result;
|
||||
const uint8_t* a_bytes = reinterpret_cast<const uint8_t*>(&a);
|
||||
const uint8_t* b_bytes = reinterpret_cast<const uint8_t*>(&b);
|
||||
uint8_t* r_bytes = reinterpret_cast<uint8_t*>(&result);
|
||||
for (Index i = 0; i < sizeof(Scalar); i++) r_bytes[i] = a_bytes[i] ^ b_bytes[i];
|
||||
return result;
|
||||
return bitwise_binary_impl<Scalar>::run_xor(a, b);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const {
|
||||
|
||||
@@ -18,7 +18,30 @@ namespace internal {
|
||||
|
||||
//---------- associative ternary functors ----------
|
||||
|
||||
template <typename ConditionScalar, typename ThenScalar, typename ElseScalar>
|
||||
struct scalar_boolean_select_op {
|
||||
static constexpr bool ThenElseAreSame = is_same<ThenScalar, ElseScalar>::value;
|
||||
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 ConditionScalar& cond, const ThenScalar& a,
|
||||
const ElseScalar& b) const {
|
||||
return cond == ConditionScalar(0) ? b : a;
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& cond, const Packet& a, const Packet& b) const {
|
||||
return pselect(pcmp_eq(cond, pzero(cond)), b, a);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ConditionScalar, typename ThenScalar, typename ElseScalar>
|
||||
struct functor_traits<scalar_boolean_select_op<ConditionScalar, ThenScalar, ElseScalar>> {
|
||||
using Scalar = ThenScalar;
|
||||
enum {
|
||||
Cost = 1,
|
||||
PacketAccess = is_same<ThenScalar, ElseScalar>::value && is_same<ConditionScalar, Scalar>::value && packet_traits<Scalar>::HasCmp
|
||||
};
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
||||
@@ -178,6 +178,13 @@ struct scalar_cast_op {
|
||||
typedef NewType result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct scalar_cast_op<Scalar, bool> {
|
||||
typedef bool result_type;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a) const { return a != Scalar(0); }
|
||||
};
|
||||
|
||||
template<typename Scalar, typename NewType>
|
||||
struct functor_traits<scalar_cast_op<Scalar,NewType> >
|
||||
{ enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
|
||||
@@ -942,6 +949,27 @@ struct functor_traits<scalar_boolean_not_op<Scalar>> {
|
||||
enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
|
||||
};
|
||||
|
||||
template <typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
|
||||
struct bitwise_unary_impl {
|
||||
static constexpr size_t Size = sizeof(Scalar);
|
||||
using uint_t = typename numext::get_integer_by_size<Size>::unsigned_type;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_not(const Scalar& a) {
|
||||
uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
|
||||
uint_t result = ~a_as_uint;
|
||||
return numext::bit_cast<Scalar, uint_t>(result);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Scalar>
|
||||
struct bitwise_unary_impl<Scalar, true> {
|
||||
using Real = typename NumTraits<Scalar>::Real;
|
||||
static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_not(const Scalar& a) {
|
||||
Real real_result = bitwise_unary_impl<Real>::run_not(numext::real(a));
|
||||
Real imag_result = bitwise_unary_impl<Real>::run_not(numext::imag(a));
|
||||
return Scalar(real_result, imag_result);
|
||||
}
|
||||
};
|
||||
|
||||
/** \internal
|
||||
* \brief Template functor to compute the bitwise not of a scalar
|
||||
*
|
||||
@@ -950,13 +978,10 @@ struct functor_traits<scalar_boolean_not_op<Scalar>> {
|
||||
template <typename Scalar>
|
||||
struct scalar_bitwise_not_op {
|
||||
EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization, BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
|
||||
EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
|
||||
using result_type = Scalar;
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& a) const {
|
||||
Scalar result;
|
||||
const uint8_t* a_bytes = reinterpret_cast<const uint8_t*>(&a);
|
||||
uint8_t* r_bytes = reinterpret_cast<uint8_t*>(&result);
|
||||
for (Index i = 0; i < sizeof(Scalar); i++) r_bytes[i] = ~a_bytes[i];
|
||||
return result;
|
||||
return bitwise_unary_impl<Scalar>::run_not(a);
|
||||
}
|
||||
template <typename Packet>
|
||||
EIGEN_STRONG_INLINE Packet packetOp(const Packet& a) const {
|
||||
|
||||
@@ -39,10 +39,10 @@ cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<std::equal_to<Scalar>, const Derived, const OtherDerived>
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>
|
||||
cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
|
||||
{
|
||||
return CwiseBinaryOp<std::equal_to<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_EQ>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise != operator of *this and \a other
|
||||
@@ -59,10 +59,46 @@ cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
|
||||
*/
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<std::not_equal_to<Scalar>, const Derived, const OtherDerived>
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>
|
||||
cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
|
||||
{
|
||||
return CwiseBinaryOp<std::not_equal_to<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise < operator of *this and \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>
|
||||
cwiseLesser(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const
|
||||
{
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise > operator of *this and \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>
|
||||
cwiseGreater(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const
|
||||
{
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise <= operator of *this and \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>
|
||||
cwiseLesserOrEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const
|
||||
{
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise >= operator of *this and \a other */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>
|
||||
cwiseGreaterOrEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived>& other) const
|
||||
{
|
||||
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise min of *this and \a other
|
||||
@@ -135,7 +171,12 @@ cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
|
||||
return CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
|
||||
}
|
||||
|
||||
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType;
|
||||
using CwiseScalarEqualReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType>;
|
||||
using CwiseScalarNotEqualReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>, const Derived, const ConstantReturnType>;
|
||||
using CwiseScalarLesserReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>, const Derived, const ConstantReturnType>;
|
||||
using CwiseScalarGreaterReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>, const Derived, const ConstantReturnType>;
|
||||
using CwiseScalarLesserOrEqualReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>, const Derived, const ConstantReturnType>;
|
||||
using CwiseScalarGreaterOrEqualReturnType = CwiseBinaryOp<internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>, const Derived, const ConstantReturnType>;
|
||||
|
||||
/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s
|
||||
*
|
||||
@@ -152,3 +193,54 @@ cwiseEqual(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>());
|
||||
}
|
||||
|
||||
|
||||
/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s
|
||||
*
|
||||
* \warning this performs an exact comparison, which is generally a bad idea with floating-point types.
|
||||
* In order to check for equality between two vectors or matrices with floating-point coefficients, it is
|
||||
* generally a far better idea to use a fuzzy comparison as provided by isApprox() and
|
||||
* isMuchSmallerThan().
|
||||
*
|
||||
* \sa cwiseEqual(const MatrixBase<OtherDerived> &) const
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseScalarNotEqualReturnType
|
||||
cwiseNotEqual(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarNotEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_NEQ>());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise < operator of \c *this and a scalar \a s */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseScalarLesserReturnType
|
||||
cwiseLesser(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarLesserReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LT>());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise > operator of \c *this and a scalar \a s */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseScalarGreaterReturnType
|
||||
cwiseGreater(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarGreaterReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GT>());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise <= operator of \c *this and a scalar \a s */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseScalarLesserOrEqualReturnType
|
||||
cwiseLesserOrEqual(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarLesserOrEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_LE>());
|
||||
}
|
||||
|
||||
/** \returns an expression of the coefficient-wise >= operator of \c *this and a scalar \a s */
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const CwiseScalarGreaterOrEqualReturnType
|
||||
cwiseGreaterOrEqual(const Scalar& s) const
|
||||
{
|
||||
return CwiseScalarGreaterOrEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar, Scalar, internal::cmp_GE>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user