mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-20 00:29:38 +08:00
Gub 1453: fix Map with non-default inner-stride but no outer-stride.
This commit is contained in:
parent
21d0a0bcf5
commit
e27f17bf5c
@ -42,7 +42,7 @@ template<typename MatrixType, int UpLo> struct LLT_Traits;
|
|||||||
* Output: \verbinclude LLT_example.out
|
* Output: \verbinclude LLT_example.out
|
||||||
*
|
*
|
||||||
* \b Performance: for best performance, it is recommended to use a column-major storage format
|
* \b Performance: for best performance, it is recommended to use a column-major storage format
|
||||||
* with the Lower triangular part (the default), or, equivalently, a row-major storage format,
|
* with the Lower triangular part (the default), or, equivalently, a row-major storage format
|
||||||
* with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization
|
* with the Upper triangular part. Otherwise, you might get a 20% slowdown for the full factorization
|
||||||
* step, and rank-updates can be up to 3 times slower.
|
* step, and rank-updates can be up to 3 times slower.
|
||||||
*
|
*
|
||||||
|
@ -20,11 +20,17 @@ struct traits<Map<PlainObjectType, MapOptions, StrideType> >
|
|||||||
{
|
{
|
||||||
typedef traits<PlainObjectType> TraitsBase;
|
typedef traits<PlainObjectType> TraitsBase;
|
||||||
enum {
|
enum {
|
||||||
|
PlainObjectTypeInnerSize = ((traits<PlainObjectType>::Flags&RowMajorBit)==RowMajorBit)
|
||||||
|
? PlainObjectType::ColsAtCompileTime
|
||||||
|
: PlainObjectType::RowsAtCompileTime,
|
||||||
|
|
||||||
InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
|
InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
|
||||||
? int(PlainObjectType::InnerStrideAtCompileTime)
|
? int(PlainObjectType::InnerStrideAtCompileTime)
|
||||||
: int(StrideType::InnerStrideAtCompileTime),
|
: int(StrideType::InnerStrideAtCompileTime),
|
||||||
OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
|
OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
|
||||||
? int(PlainObjectType::OuterStrideAtCompileTime)
|
? (InnerStrideAtCompileTime==Dynamic || PlainObjectTypeInnerSize==Dynamic
|
||||||
|
? Dynamic
|
||||||
|
: int(InnerStrideAtCompileTime) * int(PlainObjectTypeInnerSize))
|
||||||
: int(StrideType::OuterStrideAtCompileTime),
|
: int(StrideType::OuterStrideAtCompileTime),
|
||||||
Alignment = int(MapOptions)&int(AlignedMask),
|
Alignment = int(MapOptions)&int(AlignedMask),
|
||||||
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
Flags0 = TraitsBase::Flags & (~NestByRefBit),
|
||||||
@ -108,9 +114,10 @@ template<typename PlainObjectType, int MapOptions, typename StrideType> class Ma
|
|||||||
inline Index outerStride() const
|
inline Index outerStride() const
|
||||||
{
|
{
|
||||||
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||||
: IsVectorAtCompileTime ? this->size()
|
: internal::traits<Map>::OuterStrideAtCompileTime != Dynamic ? internal::traits<Map>::OuterStrideAtCompileTime
|
||||||
: int(Flags)&RowMajorBit ? this->cols()
|
: IsVectorAtCompileTime ? (this->size() * innerStride())
|
||||||
: this->rows();
|
: int(Flags)&RowMajorBit ? (this->cols() * innerStride())
|
||||||
|
: (this->rows() * innerStride());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructor in the fixed-size case.
|
/** Constructor in the fixed-size case.
|
||||||
|
@ -58,7 +58,7 @@ template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixTy
|
|||||||
MatrixType m = MatrixType::Random(rows,cols);
|
MatrixType m = MatrixType::Random(rows,cols);
|
||||||
Scalar s1 = internal::random<Scalar>();
|
Scalar s1 = internal::random<Scalar>();
|
||||||
|
|
||||||
Index arraysize = 2*(rows+4)*(cols+4);
|
Index arraysize = 4*(rows+4)*(cols+4);
|
||||||
|
|
||||||
Scalar* a_array1 = internal::aligned_new<Scalar>(arraysize+1);
|
Scalar* a_array1 = internal::aligned_new<Scalar>(arraysize+1);
|
||||||
Scalar* array1 = a_array1;
|
Scalar* array1 = a_array1;
|
||||||
@ -143,9 +143,62 @@ template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixTy
|
|||||||
VERIFY_IS_APPROX(map,s1*m);
|
VERIFY_IS_APPROX(map,s1*m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test inner stride and no outer stride
|
||||||
|
for(int k=0; k<2; ++k)
|
||||||
|
{
|
||||||
|
if(k==1 && (m.innerSize()*2)*m.outerSize() > maxsize2)
|
||||||
|
break;
|
||||||
|
Scalar* array = (k==0 ? array1 : array2);
|
||||||
|
|
||||||
|
Map<MatrixType, Alignment, InnerStride<Dynamic> > map(array, rows, cols, InnerStride<Dynamic>(2));
|
||||||
|
map = m;
|
||||||
|
VERIFY(map.outerStride() == map.innerSize()*2);
|
||||||
|
for(int i = 0; i < m.outerSize(); ++i)
|
||||||
|
for(int j = 0; j < m.innerSize(); ++j)
|
||||||
|
{
|
||||||
|
VERIFY(array[map.innerSize()*i*2+j*2] == m.coeffByOuterInner(i,j));
|
||||||
|
VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));
|
||||||
|
}
|
||||||
|
VERIFY_IS_APPROX(s1*map,s1*m);
|
||||||
|
map *= s1;
|
||||||
|
VERIFY_IS_APPROX(map,s1*m);
|
||||||
|
}
|
||||||
|
|
||||||
internal::aligned_delete(a_array1, arraysize+1);
|
internal::aligned_delete(a_array1, arraysize+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additional tests for inner-stride but no outer-stride
|
||||||
|
template<int>
|
||||||
|
void bug1453()
|
||||||
|
{
|
||||||
|
const int data[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31};
|
||||||
|
typedef Matrix<int,Dynamic,Dynamic,RowMajor> RowMatrixXi;
|
||||||
|
typedef Matrix<int,2,3,ColMajor> ColMatrix23i;
|
||||||
|
typedef Matrix<int,3,2,ColMajor> ColMatrix32i;
|
||||||
|
typedef Matrix<int,2,3,RowMajor> RowMatrix23i;
|
||||||
|
typedef Matrix<int,3,2,RowMajor> RowMatrix32i;
|
||||||
|
|
||||||
|
VERIFY_IS_APPROX(MatrixXi::Map(data, 2, 3, InnerStride<2>()), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(MatrixXi::Map(data, 2, 3, InnerStride<>(2)), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(MatrixXi::Map(data, 3, 2, InnerStride<2>()), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(MatrixXi::Map(data, 3, 2, InnerStride<>(2)), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
|
||||||
|
|
||||||
|
VERIFY_IS_APPROX(RowMatrixXi::Map(data, 2, 3, InnerStride<2>()), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrixXi::Map(data, 2, 3, InnerStride<>(2)), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrixXi::Map(data, 3, 2, InnerStride<2>()), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrixXi::Map(data, 3, 2, InnerStride<>(2)), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
|
||||||
|
|
||||||
|
VERIFY_IS_APPROX(ColMatrix23i::Map(data, InnerStride<2>()), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(ColMatrix23i::Map(data, InnerStride<>(2)), MatrixXi::Map(data, 2, 3, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(ColMatrix32i::Map(data, InnerStride<2>()), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(ColMatrix32i::Map(data, InnerStride<>(2)), MatrixXi::Map(data, 3, 2, Stride<6,2>()));
|
||||||
|
|
||||||
|
VERIFY_IS_APPROX(RowMatrix23i::Map(data, InnerStride<2>()), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrix23i::Map(data, InnerStride<>(2)), RowMatrixXi::Map(data, 2, 3, Stride<6,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrix32i::Map(data, InnerStride<2>()), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
|
||||||
|
VERIFY_IS_APPROX(RowMatrix32i::Map(data, InnerStride<>(2)), RowMatrixXi::Map(data, 3, 2, Stride<4,2>()));
|
||||||
|
}
|
||||||
|
|
||||||
void test_mapstride()
|
void test_mapstride()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < g_repeat; i++) {
|
for(int i = 0; i < g_repeat; i++) {
|
||||||
@ -175,6 +228,8 @@ void test_mapstride()
|
|||||||
CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
||||||
CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
||||||
CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );
|
||||||
|
|
||||||
|
CALL_SUBTEST_5( bug1453<0>() );
|
||||||
|
|
||||||
TEST_SET_BUT_UNUSED_VARIABLE(maxn);
|
TEST_SET_BUT_UNUSED_VARIABLE(maxn);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user