mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-02-23 18:20:47 +08:00
Allow for negative strides.
Note that using a stride of -1 is still not possible because it would clash with the definition of Eigen::Dynamic. This fixes #747.
This commit is contained in:
parent
288d456c29
commit
0668c68b03
@ -26,7 +26,7 @@ namespace Eigen {
|
||||
*
|
||||
* The outer stride is the pointer increment between two consecutive rows of a row-major matrix or
|
||||
* between two consecutive columns of a column-major matrix.
|
||||
*
|
||||
*
|
||||
* These two values can be passed either at compile-time as template parameters, or at runtime as
|
||||
* arguments to the constructor.
|
||||
*
|
||||
@ -38,6 +38,10 @@ namespace Eigen {
|
||||
* \include Map_general_stride.cpp
|
||||
* Output: \verbinclude Map_general_stride.out
|
||||
*
|
||||
* Both strides can be negative, however, a negative stride of -1 cannot be specified at compiletime
|
||||
* because of the ambiguity with Dynamic which is defined to -1 (historically, negative strides were
|
||||
* not allowed).
|
||||
*
|
||||
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
|
||||
*/
|
||||
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
|
||||
@ -55,6 +59,8 @@ class Stride
|
||||
Stride()
|
||||
: m_outer(OuterStrideAtCompileTime), m_inner(InnerStrideAtCompileTime)
|
||||
{
|
||||
// FIXME: for Eigen 4 we should use DynamicIndex instead of Dynamic.
|
||||
// FIXME: for Eigen 4 we should also unify this API with fix<>
|
||||
eigen_assert(InnerStrideAtCompileTime != Dynamic && OuterStrideAtCompileTime != Dynamic);
|
||||
}
|
||||
|
||||
@ -63,7 +69,6 @@ class Stride
|
||||
Stride(Index outerStride, Index innerStride)
|
||||
: m_outer(outerStride), m_inner(innerStride)
|
||||
{
|
||||
eigen_assert(innerStride>=0 && outerStride>=0);
|
||||
}
|
||||
|
||||
/** Copy constructor */
|
||||
|
@ -162,6 +162,32 @@ template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixTy
|
||||
VERIFY_IS_APPROX(map,s1*m);
|
||||
}
|
||||
|
||||
// test negative strides
|
||||
{
|
||||
Matrix<Scalar,Dynamic,1>::Map(a_array1, arraysize+1).setRandom();
|
||||
Index outerstride = m.innerSize()+4;
|
||||
Scalar* array = array1;
|
||||
|
||||
{
|
||||
Map<MatrixType, Alignment, OuterStride<> > map1(array, rows, cols, OuterStride<>( outerstride));
|
||||
Map<MatrixType, Unaligned, OuterStride<> > map2(array+(m.outerSize()-1)*outerstride, rows, cols, OuterStride<>(-outerstride));
|
||||
if(MatrixType::IsRowMajor) VERIFY_IS_APPROX(map1.colwise().reverse(), map2);
|
||||
else VERIFY_IS_APPROX(map1.rowwise().reverse(), map2);
|
||||
}
|
||||
|
||||
{
|
||||
Map<MatrixType, Alignment, OuterStride<> > map1(array, rows, cols, OuterStride<>( outerstride));
|
||||
Map<MatrixType, Unaligned, Stride<Dynamic,Dynamic> > map2(array+(m.outerSize()-1)*outerstride+m.innerSize()-1, rows, cols, Stride<Dynamic,Dynamic>(-outerstride,-1));
|
||||
VERIFY_IS_APPROX(map1.reverse(), map2);
|
||||
}
|
||||
|
||||
{
|
||||
Map<MatrixType, Alignment, OuterStride<> > map1(array, rows, cols, OuterStride<>( outerstride));
|
||||
Map<MatrixType, Unaligned, Stride<Dynamic,-1> > map2(array+(m.outerSize()-1)*outerstride+m.innerSize()-1, rows, cols, Stride<Dynamic,-1>(-outerstride,-1));
|
||||
VERIFY_IS_APPROX(map1.reverse(), map2);
|
||||
}
|
||||
}
|
||||
|
||||
internal::aligned_delete(a_array1, arraysize+1);
|
||||
}
|
||||
|
||||
@ -200,7 +226,7 @@ void bug1453()
|
||||
EIGEN_DECLARE_TEST(mapstride)
|
||||
{
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
int maxn = 30;
|
||||
int maxn = 3;
|
||||
CALL_SUBTEST_1( map_class_vector<Aligned>(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_1( map_class_vector<Unaligned>(Matrix<float, 1, 1>()) );
|
||||
CALL_SUBTEST_2( map_class_vector<Aligned>(Vector4d()) );
|
||||
|
@ -93,6 +93,22 @@ template<typename MatrixType> void product_extra(const MatrixType& m)
|
||||
|
||||
VERIFY_IS_APPROX(m1.col(j2).adjoint() * m1.block(0,j,m1.rows(),c), m1.col(j2).adjoint().eval() * m1.block(0,j,m1.rows(),c).eval());
|
||||
VERIFY_IS_APPROX(m1.block(i,0,r,m1.cols()) * m1.row(i2).adjoint(), m1.block(i,0,r,m1.cols()).eval() * m1.row(i2).adjoint().eval());
|
||||
|
||||
// test negative strides
|
||||
{
|
||||
Map<MatrixType,Unaligned,Stride<Dynamic,Dynamic> > map1(&m1(rows-1,cols-1), rows, cols, Stride<Dynamic,Dynamic>(-m1.outerStride(),-1));
|
||||
Map<MatrixType,Unaligned,Stride<Dynamic,Dynamic> > map2(&m2(rows-1,cols-1), rows, cols, Stride<Dynamic,Dynamic>(-m2.outerStride(),-1));
|
||||
Map<RowVectorType,Unaligned,InnerStride<-1> > mapv1(&v1(v1.size()-1), v1.size(), InnerStride<-1>(-1));
|
||||
Map<ColVectorType,Unaligned,InnerStride<-1> > mapvc2(&vc2(vc2.size()-1), vc2.size(), InnerStride<-1>(-1));
|
||||
VERIFY_IS_APPROX(MatrixType(map1), m1.reverse());
|
||||
VERIFY_IS_APPROX(MatrixType(map2), m2.reverse());
|
||||
VERIFY_IS_APPROX(m3.noalias() = MatrixType(map1) * MatrixType(map2).adjoint(), m1.reverse() * m2.reverse().adjoint());
|
||||
VERIFY_IS_APPROX(m3.noalias() = map1 * map2.adjoint(), m1.reverse() * m2.reverse().adjoint());
|
||||
VERIFY_IS_APPROX(map1 * vc2, m1.reverse() * vc2);
|
||||
VERIFY_IS_APPROX(m1 * mapvc2, m1 * mapvc2);
|
||||
VERIFY_IS_APPROX(map1.adjoint() * v1.transpose(), m1.adjoint().reverse() * v1.transpose());
|
||||
VERIFY_IS_APPROX(m1.adjoint() * mapv1.transpose(), m1.adjoint() * v1.reverse().transpose());
|
||||
}
|
||||
|
||||
// regression test
|
||||
MatrixType tmp = m1 * m1.adjoint() * s1;
|
||||
|
Loading…
Reference in New Issue
Block a user