blob: cba88bda6313c299211b4b6ab95ec68f192664f1 [file] [log] [blame]
Benoit Jacob2b208142007-12-11 10:07:18 +00001// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra. Eigen itself is part of the KDE project.
3//
Benoit Jacob8ba30552008-01-07 09:34:21 +00004// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
Benoit Jacob2b208142007-12-11 10:07:18 +00005//
Benoit Jacob3698d8c2008-02-28 15:44:45 +00006// Eigen is free software; you can redistribute it and/or
7// modify it under the terms of the GNU Lesser General Public
Gael Guennebaud46885d32008-03-03 11:02:52 +00008// License as published by the Free Software Foundation; either
Benoit Jacob3698d8c2008-02-28 15:44:45 +00009// version 3 of the License, or (at your option) any later version.
10//
11// Alternatively, you can redistribute it and/or
12// modify it under the terms of the GNU General Public License as
Gael Guennebaud46885d32008-03-03 11:02:52 +000013// published by the Free Software Foundation; either version 2 of
Benoit Jacob3698d8c2008-02-28 15:44:45 +000014// the License, or (at your option) any later version.
Benoit Jacob2b208142007-12-11 10:07:18 +000015//
16// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
Benoit Jacob3698d8c2008-02-28 15:44:45 +000018// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19// GNU General Public License for more details.
Benoit Jacob2b208142007-12-11 10:07:18 +000020//
Gael Guennebaud46885d32008-03-03 11:02:52 +000021// You should have received a copy of the GNU Lesser General Public
Benoit Jacob3698d8c2008-02-28 15:44:45 +000022// License and a copy of the GNU General Public License along with
23// Eigen. If not, see <http://www.gnu.org/licenses/>.
Benoit Jacob2b208142007-12-11 10:07:18 +000024
25#include "main.h"
26
27namespace Eigen {
28
Gael Guennebaud25568922008-03-03 10:52:44 +000029// check minor separately in order to avoid the possible creation of a zero-sized
30// array. Comes from a compilation error with gcc-3.4 or gcc-4 with -ansi -pedantic.
31// Another solution would be to declare the array like this: T m_data[Size==0?1:Size]; in MatrixStorage
32// but this is probably not bad to raise such an error at compile time...
33template<typename Scalar, int _Rows, int _Cols> struct CheckMinor
34{
35 typedef Matrix<Scalar, _Rows, _Cols> MatrixType;
36 CheckMinor(MatrixType& m1, int r1, int c1)
37 {
38 int rows = m1.rows();
39 int cols = m1.cols();
40
41 Matrix<Scalar, Dynamic, Dynamic> mi = m1.minor(0,0).eval();
42 VERIFY_IS_APPROX(mi, m1.block(1,1,rows-1,cols-1));
43 mi = m1.minor(r1,c1);
44 VERIFY_IS_APPROX(mi.transpose(), m1.transpose().minor(c1,r1));
45 //check operator(), both constant and non-constant, on minor()
46 m1.minor(r1,c1)(0,0) = m1.minor(0,0)(0,0);
47 }
48};
49
50template<typename Scalar> struct CheckMinor<Scalar,1,1>
51{
52 typedef Matrix<Scalar, 1, 1> MatrixType;
53 CheckMinor(MatrixType&, int, int) {}
54};
55
Benoit Jacob2b208142007-12-11 10:07:18 +000056template<typename MatrixType> void submatrices(const MatrixType& m)
57{
58 /* this test covers the following files:
Benoit Jacobf12e9c52008-02-29 13:56:40 +000059 Row.h Column.h Block.h Minor.h DiagonalCoeffs.h
Benoit Jacob2b208142007-12-11 10:07:18 +000060 */
Benoit Jacob2b208142007-12-11 10:07:18 +000061 typedef typename MatrixType::Scalar Scalar;
Benoit Jacob2ee68a02008-03-12 17:17:36 +000062 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
63 typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
Benoit Jacob2b208142007-12-11 10:07:18 +000064 int rows = m.rows();
65 int cols = m.cols();
66
67 MatrixType m1 = MatrixType::random(rows, cols),
68 m2 = MatrixType::random(rows, cols),
69 m3(rows, cols),
70 mzero = MatrixType::zero(rows, cols),
Benoit Jacob2ee68a02008-03-12 17:17:36 +000071 identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
Benoit Jacobbcf7b292008-01-11 15:56:21 +000072 ::identity(rows, rows),
Benoit Jacob2ee68a02008-03-12 17:17:36 +000073 square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
Benoit Jacob2b208142007-12-11 10:07:18 +000074 ::random(rows, rows);
75 VectorType v1 = VectorType::random(rows),
76 v2 = VectorType::random(rows),
77 v3 = VectorType::random(rows),
78 vzero = VectorType::zero(rows);
79
Benoit Jacob69078862008-02-28 12:38:12 +000080 Scalar s1 = ei_random<Scalar>();
Gael Guennebaud46885d32008-03-03 11:02:52 +000081
Benoit Jacob69078862008-02-28 12:38:12 +000082 int r1 = ei_random<int>(0,rows-1);
83 int r2 = ei_random<int>(r1,rows-1);
84 int c1 = ei_random<int>(0,cols-1);
85 int c2 = ei_random<int>(c1,cols-1);
Gael Guennebaud46885d32008-03-03 11:02:52 +000086
Benoit Jacob2b208142007-12-11 10:07:18 +000087 //check row() and col()
88 VERIFY_IS_APPROX(m1.col(c1).transpose(), m1.transpose().row(c1));
89 VERIFY_IS_APPROX(square.row(r1).dot(m1.col(c1)), square.lazyProduct(m1.conjugate())(r1,c1));
90 //check operator(), both constant and non-constant, on row() and col()
91 m1.row(r1) += s1 * m1.row(r2);
92 m1.col(c1) += s1 * m1.col(c2);
Gael Guennebaud46885d32008-03-03 11:02:52 +000093
Benoit Jacob95dc68d2008-01-13 20:19:14 +000094 //check block()
Benoit Jacob2b208142007-12-11 10:07:18 +000095 Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
Benoit Jacob95dc68d2008-01-13 20:19:14 +000096 RowVectorType br1(m1.block(r1,0,1,cols));
97 VectorType bc1(m1.block(0,c1,rows,1));
98 VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1));
Benoit Jacob2b208142007-12-11 10:07:18 +000099 VERIFY_IS_APPROX(m1.row(r1), br1);
100 VERIFY_IS_APPROX(m1.col(c1), bc1);
Benoit Jacob95dc68d2008-01-13 20:19:14 +0000101 //check operator(), both constant and non-constant, on block()
102 m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);
103 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);
Benoit Jacob2b208142007-12-11 10:07:18 +0000104
105 //check minor()
Benoit Jacob2ee68a02008-03-12 17:17:36 +0000106 CheckMinor<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> checkminor(m1,r1,c1);
Benoit Jacob7c384752007-12-15 18:16:30 +0000107
108 //check diagonal()
109 VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());
110 m2.diagonal() = 2 * m1.diagonal();
111 m2.diagonal()[0] *= 3;
112 VERIFY_IS_APPROX(m2.diagonal()[0], static_cast<Scalar>(6) * m1.diagonal()[0]);
Benoit Jacob2b208142007-12-11 10:07:18 +0000113}
114
115void EigenTest::testSubmatrices()
116{
117 for(int i = 0; i < m_repeat; i++) {
118 submatrices(Matrix<float, 1, 1>());
119 submatrices(Matrix4d());
120 submatrices(MatrixXcf(3, 3));
121 submatrices(MatrixXi(8, 12));
122 submatrices(MatrixXcd(20, 20));
Gael Guennebaud46885d32008-03-03 11:02:52 +0000123
Benoit Jacobf12e9c52008-02-29 13:56:40 +0000124 // test fixed block() separately as it is a template method so doesn't support
Benoit Jacob2b208142007-12-11 10:07:18 +0000125 // being called as a member of a class that is itself a template parameter
126 // (at least as of g++ 4.2)
127 Matrix<float, 6, 8> m = Matrix<float, 6, 8>::random();
Benoit Jacob69078862008-02-28 12:38:12 +0000128 float s = ei_random<float>();
Benoit Jacobf12e9c52008-02-29 13:56:40 +0000129 // test fixed block() as lvalue
130 m.block<2,5>(1,1) *= s;
131 // test operator() on fixed block() both as constant and non-constant
132 m.block<2,5>(1,1)(0, 3) = m.block<2,5>(1,1)(1,2);
133 // check that fixed block() and block() agree
134 MatrixXf b = m.block<3,2>(3,3);
Benoit Jacob95dc68d2008-01-13 20:19:14 +0000135 VERIFY_IS_APPROX(b, m.block(3,3,3,2));
Benoit Jacob2b208142007-12-11 10:07:18 +0000136 }
137}
138
139} // namespace Eigen