1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. Eigen itself is part of the KDE project. 3 // 4 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1 (at) gmail.com> 5 // 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/. 9 10 #include "main.h" 11 12 template<typename MatrixType> void basicStuff(const MatrixType& m) 13 { 14 typedef typename MatrixType::Scalar Scalar; 15 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType; 16 17 int rows = m.rows(); 18 int cols = m.cols(); 19 20 // this test relies a lot on Random.h, and there's not much more that we can do 21 // to test it, hence I consider that we will have tested Random.h 22 MatrixType m1 = MatrixType::Random(rows, cols), 23 m2 = MatrixType::Random(rows, cols), 24 m3(rows, cols), 25 mzero = MatrixType::Zero(rows, cols), 26 square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows); 27 VectorType v1 = VectorType::Random(rows), 28 vzero = VectorType::Zero(rows); 29 30 Scalar x = ei_random<Scalar>(); 31 32 int r = ei_random<int>(0, rows-1), 33 c = ei_random<int>(0, cols-1); 34 35 m1.coeffRef(r,c) = x; 36 VERIFY_IS_APPROX(x, m1.coeff(r,c)); 37 m1(r,c) = x; 38 VERIFY_IS_APPROX(x, m1(r,c)); 39 v1.coeffRef(r) = x; 40 VERIFY_IS_APPROX(x, v1.coeff(r)); 41 v1(r) = x; 42 VERIFY_IS_APPROX(x, v1(r)); 43 v1[r] = x; 44 VERIFY_IS_APPROX(x, v1[r]); 45 46 VERIFY_IS_APPROX( v1, v1); 47 VERIFY_IS_NOT_APPROX( v1, 2*v1); 48 VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1); 49 if(NumTraits<Scalar>::HasFloatingPoint) 50 VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1.norm()); 51 VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1, v1); 52 VERIFY_IS_APPROX( vzero, v1-v1); 53 VERIFY_IS_APPROX( m1, m1); 54 VERIFY_IS_NOT_APPROX( m1, 2*m1); 55 VERIFY_IS_MUCH_SMALLER_THAN( mzero, m1); 56 VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1, m1); 57 VERIFY_IS_APPROX( mzero, m1-m1); 58 59 // always test operator() on each read-only expression class, 60 // in order to check const-qualifiers. 61 // indeed, if an expression class (here Zero) is meant to be read-only, 62 // hence has no _write() method, the corresponding MatrixBase method (here zero()) 63 // should return a const-qualified object so that it is the const-qualified 64 // operator() that gets called, which in turn calls _read(). 65 VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1)); 66 67 // now test copying a row-vector into a (column-)vector and conversely. 68 square.col(r) = square.row(r).eval(); 69 Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows); 70 Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows); 71 rv = square.row(r); 72 cv = square.col(r); 73 VERIFY_IS_APPROX(rv, cv.transpose()); 74 75 if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic) 76 { 77 VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1))); 78 } 79 80 VERIFY_IS_APPROX(m3 = m1,m1); 81 MatrixType m4; 82 VERIFY_IS_APPROX(m4 = m1,m1); 83 84 // test swap 85 m3 = m1; 86 m1.swap(m2); 87 VERIFY_IS_APPROX(m3, m2); 88 if(rows*cols>=3) 89 { 90 VERIFY_IS_NOT_APPROX(m3, m1); 91 } 92 } 93 94 void test_eigen2_basicstuff() 95 { 96 for(int i = 0; i < g_repeat; i++) { 97 CALL_SUBTEST_1( basicStuff(Matrix<float, 1, 1>()) ); 98 CALL_SUBTEST_2( basicStuff(Matrix4d()) ); 99 CALL_SUBTEST_3( basicStuff(MatrixXcf(3, 3)) ); 100 CALL_SUBTEST_4( basicStuff(MatrixXi(8, 12)) ); 101 CALL_SUBTEST_5( basicStuff(MatrixXcd(20, 20)) ); 102 CALL_SUBTEST_6( basicStuff(Matrix<float, 100, 100>()) ); 103 CALL_SUBTEST_7( basicStuff(Matrix<long double,Dynamic,Dynamic>(10,10)) ); 104 } 105 } 106