00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths
00026 #include "main.h"
00027
00028 template<typename MatrixType> void block(const MatrixType& m)
00029 {
00030 typedef typename MatrixType::Index Index;
00031 typedef typename MatrixType::Scalar Scalar;
00032 typedef typename MatrixType::RealScalar RealScalar;
00033 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
00034 typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
00035 typedef Matrix<Scalar, Dynamic, Dynamic> DynamicMatrixType;
00036 typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType;
00037
00038 Index rows = m.rows();
00039 Index cols = m.cols();
00040
00041 MatrixType m1 = MatrixType::Random(rows, cols),
00042 m1_copy = m1,
00043 m2 = MatrixType::Random(rows, cols),
00044 m3(rows, cols),
00045 mzero = MatrixType::Zero(rows, cols),
00046 ones = MatrixType::Ones(rows, cols);
00047 VectorType v1 = VectorType::Random(rows),
00048 v2 = VectorType::Random(rows),
00049 v3 = VectorType::Random(rows),
00050 vzero = VectorType::Zero(rows);
00051
00052 Scalar s1 = internal::random<Scalar>();
00053
00054 Index r1 = internal::random<Index>(0,rows-1);
00055 Index r2 = internal::random<Index>(r1,rows-1);
00056 Index c1 = internal::random<Index>(0,cols-1);
00057 Index c2 = internal::random<Index>(c1,cols-1);
00058
00059
00060 VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1));
00061
00062 m1 = m1_copy;
00063 m1.row(r1) += s1 * m1_copy.row(r2);
00064 VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + s1 * m1_copy.row(r2));
00065
00066 m1.row(r1).row(0) += s1 * m1_copy.row(r2);
00067 VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + Scalar(2) * s1 * m1_copy.row(r2));
00068 m1 = m1_copy;
00069 m1.col(c1) += s1 * m1_copy.col(c2);
00070 VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2));
00071 m1.col(c1).col(0) += s1 * m1_copy.col(c2);
00072 VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2));
00073
00074
00075 Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
00076
00077 RowVectorType br1(m1.block(r1,0,1,cols));
00078 VectorType bc1(m1.block(0,c1,rows,1));
00079 VERIFY_IS_EQUAL(b1, m1.block(r1,c1,1,1));
00080 VERIFY_IS_EQUAL(m1.row(r1), br1);
00081 VERIFY_IS_EQUAL(m1.col(c1), bc1);
00082
00083 m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);
00084 m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);
00085
00086 enum {
00087 BlockRows = 2,
00088 BlockCols = 5
00089 };
00090 if (rows>=5 && cols>=8)
00091 {
00092
00093 m1.template block<BlockRows,BlockCols>(1,1) *= s1;
00094
00095 m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2);
00096
00097 Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);
00098 VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols));
00099 }
00100
00101 if (rows>2)
00102 {
00103
00104 VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0,0,2,1));
00105 VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2));
00106 VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0,2));
00107 VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0));
00108 Index i = rows-2;
00109 VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i,0,2,1));
00110 VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2));
00111 VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i,2));
00112 VERIFY_IS_EQUAL(v1.template tail<2>(), v1.template segment<2>(i));
00113 i = internal::random<Index>(0,rows-2);
00114 VERIFY_IS_EQUAL(v1.segment(i,2), v1.template segment<2>(i));
00115 }
00116
00117
00118 VERIFY(internal::real(ones.col(c1).sum()) == RealScalar(rows));
00119 VERIFY(internal::real(ones.row(r1).sum()) == RealScalar(cols));
00120
00121 VERIFY(internal::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));
00122 VERIFY(internal::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));
00123
00124
00125
00126
00127 VERIFY_IS_EQUAL( (m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , (m1.block(r2,c2,rows-r2,cols-c2)) );
00128 VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );
00129 VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , (m1.col(c1).segment(r1,r2-r1+1)) );
00130 VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );
00131 VERIFY_IS_EQUAL( (m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );
00132
00133
00134 VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , ((m1+m2).block(r2,c2,rows-r2,cols-c2)) );
00135 VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );
00136 VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , ((m1+m2).col(c1).segment(r1,r2-r1+1)) );
00137 VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );
00138 VERIFY_IS_EQUAL( ((m1+m2).transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );
00139
00140
00141 DynamicMatrixType dm;
00142 DynamicVectorType dv;
00143 dm.setZero();
00144 dm = m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2);
00145 VERIFY_IS_EQUAL(dm, (m1.block(r2,c2,rows-r2,cols-c2)));
00146 dm.setZero();
00147 dv.setZero();
00148 dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0).transpose();
00149 dv = m1.row(r1).segment(c1,c2-c1+1);
00150 VERIFY_IS_EQUAL(dv, dm);
00151 dm.setZero();
00152 dv.setZero();
00153 dm = m1.col(c1).segment(r1,r2-r1+1);
00154 dv = m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0);
00155 VERIFY_IS_EQUAL(dv, dm);
00156 dm.setZero();
00157 dv.setZero();
00158 dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0);
00159 dv = m1.row(r1).segment(c1,c2-c1+1);
00160 VERIFY_IS_EQUAL(dv, dm);
00161 dm.setZero();
00162 dv.setZero();
00163 dm = m1.row(r1).segment(c1,c2-c1+1).transpose();
00164 dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);
00165 VERIFY_IS_EQUAL(dv, dm);
00166 }
00167
00168
00169 template<typename MatrixType>
00170 void compare_using_data_and_stride(const MatrixType& m)
00171 {
00172 typedef typename MatrixType::Index Index;
00173 Index rows = m.rows();
00174 Index cols = m.cols();
00175 Index size = m.size();
00176 Index innerStride = m.innerStride();
00177 Index outerStride = m.outerStride();
00178 Index rowStride = m.rowStride();
00179 Index colStride = m.colStride();
00180 const typename MatrixType::Scalar* data = m.data();
00181
00182 for(int j=0;j<cols;++j)
00183 for(int i=0;i<rows;++i)
00184 VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);
00185
00186 if(!MatrixType::IsVectorAtCompileTime)
00187 {
00188 for(int j=0;j<cols;++j)
00189 for(int i=0;i<rows;++i)
00190 VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)
00191 ? i*outerStride + j*innerStride
00192 : j*outerStride + i*innerStride]);
00193 }
00194
00195 if(MatrixType::IsVectorAtCompileTime)
00196 {
00197 VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));
00198 for (int i=0;i<size;++i)
00199 VERIFY(m.coeff(i) == data[i*innerStride]);
00200 }
00201 }
00202
00203 template<typename MatrixType>
00204 void data_and_stride(const MatrixType& m)
00205 {
00206 typedef typename MatrixType::Index Index;
00207 Index rows = m.rows();
00208 Index cols = m.cols();
00209
00210 Index r1 = internal::random<Index>(0,rows-1);
00211 Index r2 = internal::random<Index>(r1,rows-1);
00212 Index c1 = internal::random<Index>(0,cols-1);
00213 Index c2 = internal::random<Index>(c1,cols-1);
00214
00215 MatrixType m1 = MatrixType::Random(rows, cols);
00216 compare_using_data_and_stride(m1.block(r1, c1, r2-r1+1, c2-c1+1));
00217 compare_using_data_and_stride(m1.transpose().block(c1, r1, c2-c1+1, r2-r1+1));
00218 compare_using_data_and_stride(m1.row(r1));
00219 compare_using_data_and_stride(m1.col(c1));
00220 compare_using_data_and_stride(m1.row(r1).transpose());
00221 compare_using_data_and_stride(m1.col(c1).transpose());
00222 }
00223
00224 void test_block()
00225 {
00226 for(int i = 0; i < g_repeat; i++) {
00227 CALL_SUBTEST_1( block(Matrix<float, 1, 1>()) );
00228 CALL_SUBTEST_2( block(Matrix4d()) );
00229 CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
00230 CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
00231 CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
00232 CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
00233
00234 CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
00235
00236 #ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
00237 CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
00238 CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
00239 #endif
00240 }
00241 }