1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 template<int Alignment
,typename VectorType
> void map_class_vector(const VectorType
& m
)
14 typedef typename
VectorType::Index Index
;
15 typedef typename
VectorType::Scalar Scalar
;
17 Index size
= m
.size();
19 VectorType v
= VectorType::Random(size
);
21 Index arraysize
= 3*size
;
23 Scalar
* a_array
= internal::aligned_new
<Scalar
>(arraysize
+1);
24 Scalar
* array
= a_array
;
25 if(Alignment
!=Aligned
)
26 array
= (Scalar
*)(internal::IntPtr(a_array
) + (internal::packet_traits
<Scalar
>::AlignedOnScalar
?sizeof(Scalar
):sizeof(typename NumTraits
<Scalar
>::Real
)));
29 Map
<VectorType
, Alignment
, InnerStride
<3> > map(array
, size
);
31 for(int i
= 0; i
< size
; ++i
)
33 VERIFY(array
[3*i
] == v
[i
]);
34 VERIFY(map
[i
] == v
[i
]);
39 Map
<VectorType
, Unaligned
, InnerStride
<Dynamic
> > map(array
, size
, InnerStride
<Dynamic
>(2));
41 for(int i
= 0; i
< size
; ++i
)
43 VERIFY(array
[2*i
] == v
[i
]);
44 VERIFY(map
[i
] == v
[i
]);
48 internal::aligned_delete(a_array
, arraysize
+1);
51 template<int Alignment
,typename MatrixType
> void map_class_matrix(const MatrixType
& _m
)
53 typedef typename
MatrixType::Index Index
;
54 typedef typename
MatrixType::Scalar Scalar
;
56 Index rows
= _m
.rows(), cols
= _m
.cols();
58 MatrixType m
= MatrixType::Random(rows
,cols
);
59 Scalar s1
= internal::random
<Scalar
>();
61 Index arraysize
= 2*(rows
+4)*(cols
+4);
63 Scalar
* a_array1
= internal::aligned_new
<Scalar
>(arraysize
+1);
64 Scalar
* array1
= a_array1
;
65 if(Alignment
!=Aligned
)
66 array1
= (Scalar
*)(internal::IntPtr(a_array1
) + (internal::packet_traits
<Scalar
>::AlignedOnScalar
?sizeof(Scalar
):sizeof(typename NumTraits
<Scalar
>::Real
)));
69 Scalar
* array2
= a_array2
;
70 if(Alignment
!=Aligned
)
71 array2
= (Scalar
*)(internal::IntPtr(a_array2
) + (internal::packet_traits
<Scalar
>::AlignedOnScalar
?sizeof(Scalar
):sizeof(typename NumTraits
<Scalar
>::Real
)));
73 array2
= (Scalar
*)(((internal::UIntPtr(a_array2
)+EIGEN_MAX_ALIGN_BYTES
-1)/EIGEN_MAX_ALIGN_BYTES
)*EIGEN_MAX_ALIGN_BYTES
);
74 Index maxsize2
= a_array2
- array2
+ 256;
76 // test no inner stride and some dynamic outer stride
77 for(int k
=0; k
<2; ++k
)
79 if(k
==1 && (m
.innerSize()+1)*m
.outerSize() > maxsize2
)
81 Scalar
* array
= (k
==0 ? array1
: array2
);
83 Map
<MatrixType
, Alignment
, OuterStride
<Dynamic
> > map(array
, rows
, cols
, OuterStride
<Dynamic
>(m
.innerSize()+1));
85 VERIFY(map
.outerStride() == map
.innerSize()+1);
86 for(int i
= 0; i
< m
.outerSize(); ++i
)
87 for(int j
= 0; j
< m
.innerSize(); ++j
)
89 VERIFY(array
[map
.outerStride()*i
+j
] == m
.coeffByOuterInner(i
,j
));
90 VERIFY(map
.coeffByOuterInner(i
,j
) == m
.coeffByOuterInner(i
,j
));
92 VERIFY_IS_APPROX(s1
*map
,s1
*m
);
94 VERIFY_IS_APPROX(map
,s1
*m
);
97 // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices,
98 // this allows to hit the special case where it's vectorizable.
99 for(int k
=0; k
<2; ++k
)
101 if(k
==1 && (m
.innerSize()+4)*m
.outerSize() > maxsize2
)
103 Scalar
* array
= (k
==0 ? array1
: array2
);
106 InnerSize
= MatrixType::InnerSizeAtCompileTime
,
107 OuterStrideAtCompileTime
= InnerSize
==Dynamic
? Dynamic
: InnerSize
+4
109 Map
<MatrixType
, Alignment
, OuterStride
<OuterStrideAtCompileTime
> >
110 map(array
, rows
, cols
, OuterStride
<OuterStrideAtCompileTime
>(m
.innerSize()+4));
112 VERIFY(map
.outerStride() == map
.innerSize()+4);
113 for(int i
= 0; i
< m
.outerSize(); ++i
)
114 for(int j
= 0; j
< m
.innerSize(); ++j
)
116 VERIFY(array
[map
.outerStride()*i
+j
] == m
.coeffByOuterInner(i
,j
));
117 VERIFY(map
.coeffByOuterInner(i
,j
) == m
.coeffByOuterInner(i
,j
));
119 VERIFY_IS_APPROX(s1
*map
,s1
*m
);
121 VERIFY_IS_APPROX(map
,s1
*m
);
124 // test both inner stride and outer stride
125 for(int k
=0; k
<2; ++k
)
127 if(k
==1 && (2*m
.innerSize()+1)*(m
.outerSize()*2) > maxsize2
)
129 Scalar
* array
= (k
==0 ? array1
: array2
);
131 Map
<MatrixType
, Alignment
, Stride
<Dynamic
,Dynamic
> > map(array
, rows
, cols
, Stride
<Dynamic
,Dynamic
>(2*m
.innerSize()+1, 2));
133 VERIFY(map
.outerStride() == 2*map
.innerSize()+1);
134 VERIFY(map
.innerStride() == 2);
135 for(int i
= 0; i
< m
.outerSize(); ++i
)
136 for(int j
= 0; j
< m
.innerSize(); ++j
)
138 VERIFY(array
[map
.outerStride()*i
+map
.innerStride()*j
] == m
.coeffByOuterInner(i
,j
));
139 VERIFY(map
.coeffByOuterInner(i
,j
) == m
.coeffByOuterInner(i
,j
));
141 VERIFY_IS_APPROX(s1
*map
,s1
*m
);
143 VERIFY_IS_APPROX(map
,s1
*m
);
146 internal::aligned_delete(a_array1
, arraysize
+1);
149 void test_mapstride()
151 for(int i
= 0; i
< g_repeat
; i
++) {
153 CALL_SUBTEST_1( map_class_vector
<Aligned
>(Matrix
<float, 1, 1>()) );
154 CALL_SUBTEST_1( map_class_vector
<Unaligned
>(Matrix
<float, 1, 1>()) );
155 CALL_SUBTEST_2( map_class_vector
<Aligned
>(Vector4d()) );
156 CALL_SUBTEST_2( map_class_vector
<Unaligned
>(Vector4d()) );
157 CALL_SUBTEST_3( map_class_vector
<Aligned
>(RowVector4f()) );
158 CALL_SUBTEST_3( map_class_vector
<Unaligned
>(RowVector4f()) );
159 CALL_SUBTEST_4( map_class_vector
<Aligned
>(VectorXcf(internal::random
<int>(1,maxn
))) );
160 CALL_SUBTEST_4( map_class_vector
<Unaligned
>(VectorXcf(internal::random
<int>(1,maxn
))) );
161 CALL_SUBTEST_5( map_class_vector
<Aligned
>(VectorXi(internal::random
<int>(1,maxn
))) );
162 CALL_SUBTEST_5( map_class_vector
<Unaligned
>(VectorXi(internal::random
<int>(1,maxn
))) );
164 CALL_SUBTEST_1( map_class_matrix
<Aligned
>(Matrix
<float, 1, 1>()) );
165 CALL_SUBTEST_1( map_class_matrix
<Unaligned
>(Matrix
<float, 1, 1>()) );
166 CALL_SUBTEST_2( map_class_matrix
<Aligned
>(Matrix4d()) );
167 CALL_SUBTEST_2( map_class_matrix
<Unaligned
>(Matrix4d()) );
168 CALL_SUBTEST_3( map_class_matrix
<Aligned
>(Matrix
<float,3,5>()) );
169 CALL_SUBTEST_3( map_class_matrix
<Unaligned
>(Matrix
<float,3,5>()) );
170 CALL_SUBTEST_3( map_class_matrix
<Aligned
>(Matrix
<float,4,8>()) );
171 CALL_SUBTEST_3( map_class_matrix
<Unaligned
>(Matrix
<float,4,8>()) );
172 CALL_SUBTEST_4( map_class_matrix
<Aligned
>(MatrixXcf(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
173 CALL_SUBTEST_4( map_class_matrix
<Unaligned
>(MatrixXcf(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
174 CALL_SUBTEST_5( map_class_matrix
<Aligned
>(MatrixXi(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
175 CALL_SUBTEST_5( map_class_matrix
<Unaligned
>(MatrixXi(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
176 CALL_SUBTEST_6( map_class_matrix
<Aligned
>(MatrixXcd(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
177 CALL_SUBTEST_6( map_class_matrix
<Unaligned
>(MatrixXcd(internal::random
<int>(1,maxn
),internal::random
<int>(1,maxn
))) );
179 TEST_SET_BUT_UNUSED_VARIABLE(maxn
);