mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-07-26 14:54:30 +08:00
Implement evaluators for Reverse.
This commit is contained in:
parent
bb2d70d211
commit
f924722f3b
@ -666,7 +666,7 @@ struct evaluator_impl<Replicate<XprType, RowFactor, ColFactor> >
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
typename evaluator<XprType>::type m_argImpl;
|
typename evaluator<XprType>::type m_argImpl;
|
||||||
Index m_rows;
|
Index m_rows; // TODO: Get rid of this if known at compile time
|
||||||
Index m_cols;
|
Index m_cols;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -787,6 +787,100 @@ struct evaluator_impl<ArrayWrapper<ArgType> >
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------- Reverse --------------------
|
||||||
|
|
||||||
|
// defined in Reverse.h:
|
||||||
|
template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond;
|
||||||
|
|
||||||
|
template<typename ArgType, int Direction>
|
||||||
|
struct evaluator_impl<Reverse<ArgType, Direction> >
|
||||||
|
{
|
||||||
|
typedef Reverse<ArgType, Direction> ReverseType;
|
||||||
|
|
||||||
|
evaluator_impl(const ReverseType& reverse)
|
||||||
|
: m_argImpl(reverse.nestedExpression()),
|
||||||
|
m_rows(reverse.nestedExpression().rows()),
|
||||||
|
m_cols(reverse.nestedExpression().cols())
|
||||||
|
{ }
|
||||||
|
|
||||||
|
typedef typename ReverseType::Index Index;
|
||||||
|
typedef typename ReverseType::Scalar Scalar;
|
||||||
|
typedef typename ReverseType::CoeffReturnType CoeffReturnType;
|
||||||
|
typedef typename ReverseType::PacketScalar PacketScalar;
|
||||||
|
typedef typename ReverseType::PacketReturnType PacketReturnType;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
PacketSize = internal::packet_traits<Scalar>::size,
|
||||||
|
IsRowMajor = ReverseType::IsRowMajor,
|
||||||
|
IsColMajor = !IsRowMajor,
|
||||||
|
ReverseRow = (Direction == Vertical) || (Direction == BothDirections),
|
||||||
|
ReverseCol = (Direction == Horizontal) || (Direction == BothDirections),
|
||||||
|
OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
|
||||||
|
OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1,
|
||||||
|
ReversePacket = (Direction == BothDirections)
|
||||||
|
|| ((Direction == Vertical) && IsColMajor)
|
||||||
|
|| ((Direction == Horizontal) && IsRowMajor)
|
||||||
|
};
|
||||||
|
typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
|
||||||
|
|
||||||
|
CoeffReturnType coeff(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return m_argImpl.coeff(ReverseRow ? m_rows - row - 1 : row,
|
||||||
|
ReverseCol ? m_cols - col - 1 : col);
|
||||||
|
}
|
||||||
|
|
||||||
|
CoeffReturnType coeff(Index index) const
|
||||||
|
{
|
||||||
|
return m_argImpl.coeff(m_rows * m_cols - index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scalar& coeffRef(Index row, Index col)
|
||||||
|
{
|
||||||
|
return m_argImpl.coeffRef(ReverseRow ? m_rows - row - 1 : row,
|
||||||
|
ReverseCol ? m_cols - col - 1 : col);
|
||||||
|
}
|
||||||
|
|
||||||
|
Scalar& coeffRef(Index index)
|
||||||
|
{
|
||||||
|
return m_argImpl.coeffRef(m_rows * m_cols - index - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
PacketScalar packet(Index row, Index col) const
|
||||||
|
{
|
||||||
|
return reverse_packet::run(m_argImpl.template packet<LoadMode>(
|
||||||
|
ReverseRow ? m_rows - row - OffsetRow : row,
|
||||||
|
ReverseCol ? m_cols - col - OffsetCol : col));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
PacketScalar packet(Index index) const
|
||||||
|
{
|
||||||
|
return preverse(m_argImpl.template packet<LoadMode>(m_rows * m_cols - index - PacketSize));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
void writePacket(Index row, Index col, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_argImpl.template writePacket<LoadMode>(
|
||||||
|
ReverseRow ? m_rows - row - OffsetRow : row,
|
||||||
|
ReverseCol ? m_cols - col - OffsetCol : col,
|
||||||
|
reverse_packet::run(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<int LoadMode>
|
||||||
|
void writePacket(Index index, const PacketScalar& x)
|
||||||
|
{
|
||||||
|
m_argImpl.template writePacket<LoadMode>(m_rows * m_cols - index - PacketSize, preverse(x));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typename evaluator<ArgType>::type m_argImpl;
|
||||||
|
Index m_rows; // TODO: Don't use if known at compile time or not needed
|
||||||
|
Index m_cols;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
#endif // EIGEN_COREEVALUATORS_H
|
#endif // EIGEN_COREEVALUATORS_H
|
||||||
|
@ -183,6 +183,12 @@ template<typename MatrixType, int Direction> class Reverse
|
|||||||
m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
|
m_matrix.const_cast_derived().template writePacket<LoadMode>(m_matrix.size() - index - PacketSize, internal::preverse(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const typename internal::remove_all<typename MatrixType::Nested>::type&
|
||||||
|
nestedExpression() const
|
||||||
|
{
|
||||||
|
return m_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
};
|
};
|
||||||
|
@ -192,4 +192,12 @@ void test_evaluators()
|
|||||||
VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
|
VERIFY_IS_APPROX(mat2, (arr1 * arr1).matrix());
|
||||||
arr2.matrix() = MatrixXd::Identity(6,6);
|
arr2.matrix() = MatrixXd::Identity(6,6);
|
||||||
VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
|
VERIFY_IS_APPROX(arr2, MatrixXd::Identity(6,6).array());
|
||||||
|
|
||||||
|
// test Reverse
|
||||||
|
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.reverse());
|
||||||
|
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.colwise().reverse());
|
||||||
|
VERIFY_IS_APPROX_EVALUATOR(arr2, arr1.rowwise().reverse());
|
||||||
|
|
||||||
|
arr2.reverse() = arr1;
|
||||||
|
VERIFY_IS_APPROX(arr2, arr1.reverse());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user