Add coeff-wise comparisons to scalar operators. You can now write:

mat.cwise() < 2
instead of:
   mat.cwise() < MatrixType::Constant(mat.rows(), mat.cols(), 2)
This commit is contained in:
Gael Guennebaud 2008-09-03 17:56:06 +00:00
parent 59dc1da5bf
commit e14aa8c8aa
3 changed files with 130 additions and 0 deletions

View File

@ -289,6 +289,103 @@ Cwise<ExpressionType>::operator!=(const MatrixBase<OtherDerived> &other) const
return EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)(_expression(), other.derived());
}
// comparisons to scalar value
/** \array_module
*
* \returns an expression of the coefficient-wise \< operator of *this and a scalar \a s
*
* \sa operator<(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
Cwise<ExpressionType>::operator<(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \<= operator of *this and a scalar \a s
*
* \sa operator<=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
Cwise<ExpressionType>::operator<=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \> operator of *this and a scalar \a s
*
* \sa operator>(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
Cwise<ExpressionType>::operator>(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise \>= operator of *this and a scalar \a s
*
* \sa operator>=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
Cwise<ExpressionType>::operator>=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise == operator of *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 MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* \sa operator==(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
Cwise<ExpressionType>::operator==(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
/** \array_module
*
* \returns an expression of the coefficient-wise != operator of *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 MatrixBase::isApprox() and
* MatrixBase::isMuchSmallerThan().
*
* \sa operator!=(const MatrixBase<OtherDerived> &) const
*/
template<typename ExpressionType>
inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
Cwise<ExpressionType>::operator!=(Scalar s) const
{
return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)(_expression(),
typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s));
}
// scalar addition
/** \array_module
*

View File

@ -36,6 +36,12 @@
#define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \
CwiseUnaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType>
/** \internal
* convenient macro to defined the return type of a cwise comparison to a scalar */
#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \
CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \
NestByValue<typename ExpressionType::ConstantReturnType> >
/** \class Cwise
*
* \brief Pseudo expression providing additional coefficient-wise operations
@ -128,6 +134,24 @@ template<typename ExpressionType> class Cwise
template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)
operator!=(const MatrixBase<OtherDerived>& other) const;
// comparisons to a scalar value
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)
operator<(Scalar s) const;
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)
operator<=(Scalar s) const;
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)
operator>(Scalar s) const;
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)
operator>=(Scalar s) const;
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)
operator==(Scalar s) const;
const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)
operator!=(Scalar s) const;
protected:
ExpressionTypeNested m_matrix;

View File

@ -89,6 +89,12 @@ template<typename MatrixType> void comparisons(const MatrixType& m)
VERIFY(! (m1.cwise() > m3).all() );
}
// comparisons to scalar
VERIFY( (m1.cwise() != (m1(r,c)+1) ).any() );
VERIFY( (m1.cwise() > (m1(r,c)-1) ).any() );
VERIFY( (m1.cwise() < (m1(r,c)+1) ).any() );
VERIFY( (m1.cwise() == m1(r,c) ).any() );
// test Select
VERIFY_IS_APPROX( (m1.cwise()<m2).select(m1,m2), m1.cwise().min(m2) );
VERIFY_IS_APPROX( (m1.cwise()>m2).select(m1,m2), m1.cwise().max(m2) );
@ -98,10 +104,13 @@ template<typename MatrixType> void comparisons(const MatrixType& m)
m3(i,j) = ei_abs(m1(i,j))<mid ? 0 : m1(i,j);
VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<MatrixType::Constant(rows,cols,mid))
.select(MatrixType::Zero(rows,cols),m1), m3);
// shorter versions:
VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<MatrixType::Constant(rows,cols,mid))
.select(0,m1), m3);
VERIFY_IS_APPROX( (m1.cwise().abs().cwise()>=MatrixType::Constant(rows,cols,mid))
.select(m1,0), m3);
// even shorter version:
VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<mid).select(0,m1), m3);
}
void test_array()