blob: d929b0883f72a059837d19acdc3b64e891be8038 [file] [log] [blame]
Benoit Jacobe445f502007-10-13 16:56:24 +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//
4// Copyright (C) 2006-2007 Benoit Jacob <jacob@math.jussieu.fr>
5//
6// Eigen is free software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the Free Software
8// Foundation; either version 2 or (at your option) any later version.
9//
10// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
11// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13// details.
14//
15// You should have received a copy of the GNU General Public License along
16// with Eigen; if not, write to the Free Software Foundation, Inc., 51
17// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// As a special exception, if other files instantiate templates or use macros
20// or functions from this file, or you compile this file and link it
21// with other works to produce a work based on this file, this file does not
22// by itself cause the resulting work to be covered by the GNU General Public
23// License. This exception does not invalidate any other reasons why a work
24// based on this file might be covered by the GNU General Public License.
25
26#include "main.h"
27
28template<typename MatrixType> void basicStuff(const MatrixType& m)
29{
Benoit Jacob5309ef52007-11-26 08:47:07 +000030 /* this test covers the following files:
31 1) Explicitly (see comments below):
32 Random.h Zero.h Identity.h Fuzzy.h Sum.h Difference.h
33 Opposite.h Product.h ScalarMultiple.h FromArray.h
34
35 2) Implicitly (the core stuff):
Benoit Jacob39f17762007-11-27 13:57:51 +000036 MatrixBase.h Matrix.h MatrixStorage.h CopyHelper.h MatrixRef.h
Benoit Jacob5309ef52007-11-26 08:47:07 +000037 NumTraits.h Util.h
38 */
39
Benoit Jacobe445f502007-10-13 16:56:24 +000040 typedef typename MatrixType::Scalar Scalar;
41 typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
42 int rows = m.rows();
43 int cols = m.cols();
44
Benoit Jacob5309ef52007-11-26 08:47:07 +000045 // this test relies a lot on Random.h, and there's not much more that we can do
46 // to test it, hence I consider that we will have tested Random.h
Benoit Jacobe445f502007-10-13 16:56:24 +000047 MatrixType m1 = MatrixType::random(rows, cols),
48 m2 = MatrixType::random(rows, cols),
Benoit Jacob5309ef52007-11-26 08:47:07 +000049 m3(rows, cols),
Benoit Jacob6c8f1592007-10-14 09:18:18 +000050 mzero = MatrixType::zero(rows, cols),
51 identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
Benoit Jacob3f979182007-10-14 10:01:25 +000052 ::identity(rows),
Benoit Jacob6c8f1592007-10-14 09:18:18 +000053 square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>
54 ::random(rows, rows);
55 VectorType v1 = VectorType::random(rows),
56 v2 = VectorType::random(rows),
57 vzero = VectorType::zero(rows);
Benoit Jacobe445f502007-10-13 16:56:24 +000058
59 Scalar s1 = NumTraits<Scalar>::random(),
60 s2 = NumTraits<Scalar>::random();
61
Benoit Jacob5309ef52007-11-26 08:47:07 +000062 // test Fuzzy.h and Zero.h.
Benoit Jacobe445f502007-10-13 16:56:24 +000063 QVERIFY(v1.isApprox(v1));
Benoit Jacob6c8f1592007-10-14 09:18:18 +000064 QVERIFY(!v1.isApprox(2*v1));
Benoit Jacob6c8f1592007-10-14 09:18:18 +000065 QVERIFY(vzero.isMuchSmallerThan(v1));
66 QVERIFY(vzero.isMuchSmallerThan(v1.norm()));
67 QVERIFY(!v1.isMuchSmallerThan(v1));
Benoit Jacob5309ef52007-11-26 08:47:07 +000068 QVERIFY(vzero.isApprox(v1-v1));
Benoit Jacobe445f502007-10-13 16:56:24 +000069 QVERIFY(m1.isApprox(m1));
Benoit Jacob6c8f1592007-10-14 09:18:18 +000070 QVERIFY(!m1.isApprox(2*m1));
71 QVERIFY(mzero.isMuchSmallerThan(m1));
72 QVERIFY(!m1.isMuchSmallerThan(m1));
Benoit Jacob6c8f1592007-10-14 09:18:18 +000073 QVERIFY(mzero.isApprox(m1-m1));
Benoit Jacobe445f502007-10-13 16:56:24 +000074
Benoit Jacob5309ef52007-11-26 08:47:07 +000075 // test the linear structure, i.e. the following files:
76 // Sum.h Difference.h Opposite.h ScalarMultiple.h
Benoit Jacobe445f502007-10-13 16:56:24 +000077 QVERIFY((m1+m1).isApprox(2 * m1));
Benoit Jacob5309ef52007-11-26 08:47:07 +000078 QVERIFY((m1+m2-m1).isApprox(m2));
79 QVERIFY((-m2+m1+m2).isApprox(m1));
Benoit Jacobe445f502007-10-13 16:56:24 +000080 QVERIFY((m1 * s1).isApprox(s1 * m1));
81 QVERIFY(((m1 + m2) * s1).isApprox(s1 * m1 + s1 * m2));
82 QVERIFY(((s1 + s2) * m1).isApprox(m1 * s1 + m1 * s2));
Benoit Jacob5309ef52007-11-26 08:47:07 +000083 QVERIFY(((m1 - m2) * s1).isApprox(s1 * m1 - s1 * m2));
84 QVERIFY(((s1 - s2) * m1).isApprox(m1 * s1 - m1 * s2));
85 QVERIFY(((-m1 + m2) * s1).isApprox(-s1 * m1 + s1 * m2));
86 QVERIFY(((-s1 + s2) * m1).isApprox(-m1 * s1 + m1 * s2));
Benoit Jacobe445f502007-10-13 16:56:24 +000087 m3 = m2;
88 QVERIFY((m3 += m1).isApprox(m1 + m2));
89 m3 = m2;
90 QVERIFY((m3 -= m1).isApprox(-m1 + m2));
91 m3 = m2;
92 QVERIFY((m3 *= s1).isApprox(s1 * m2));
93 m3 = m2;
94 if(NumTraits<Scalar>::HasFloatingPoint
95 && s1 != static_cast<Scalar>(0))
96 QVERIFY((m3 /= s1).isApprox(m2 / s1));
97
Benoit Jacob5309ef52007-11-26 08:47:07 +000098 // begin testing Product.h: only associativity for now
99 // (we use Transpose.h but this doesn't count as a test for it)
Benoit Jacobe445f502007-10-13 16:56:24 +0000100 QVERIFY(((m1 * m1.transpose()) * m2).isApprox(m1 * (m1.transpose() * m2)));
101 m3 = m1;
102 m3 *= (m1.transpose() * m2);
103 QVERIFY(m3.isApprox(m1 * (m1.transpose() * m2)));
104 QVERIFY(m3.isApprox(m1.lazyProduct(m1.transpose() * m2)));
Benoit Jacob5309ef52007-11-26 08:47:07 +0000105
106 // continue testing Product.h: distributivity
107 QVERIFY((square * (m1 + m2)).isApprox(square * m1 + square * m2));
108 QVERIFY((square * (m1 - m2)).isApprox(square * m1 - square * m2));
109
110 // continue testing Product.h: compatibility with ScalarMultiple.h
111 QVERIFY((s1 * (square * m1)).isApprox((s1 * square) * m1));
112 QVERIFY((s1 * (square * m1)).isApprox(square * (m1 * s1)));
113
Benoit Jacob2fdd0672007-11-28 15:34:40 +0000114 // continue testing Product.h: lazyProduct
115 QVERIFY(square.lazyProduct(m1).isApprox(square * m1));
116
Benoit Jacob5309ef52007-11-26 08:47:07 +0000117 // test Product.h together with Identity.h. This does test Identity.h.
Benoit Jacob6c8f1592007-10-14 09:18:18 +0000118 QVERIFY(m1.isApprox(identity * m1));
119 QVERIFY(v1.isApprox(identity * v1));
120
Benoit Jacob5309ef52007-11-26 08:47:07 +0000121 // test FromArray.h
Benoit Jacobf355ef22007-10-14 18:02:16 +0000122 Scalar* array1 = new Scalar[rows];
123 Scalar* array2 = new Scalar[rows];
124 Matrix<Scalar, Dynamic, 1>::fromArray(array1, rows) = Matrix<Scalar, Dynamic, 1>::random(rows);
Benoit Jacob5309ef52007-11-26 08:47:07 +0000125 Matrix<Scalar, Dynamic, 1>::fromArray(array2, rows)
126 = Matrix<Scalar, Dynamic, 1>::fromArray(array1, rows);
127 bool b = Matrix<Scalar, Dynamic, 1>::fromArray(array1, rows)
128 .isApprox(Matrix<Scalar, Dynamic, 1>::fromArray(array2, rows));
Benoit Jacobf355ef22007-10-14 18:02:16 +0000129 QVERIFY(b);
Benoit Jacob5309ef52007-11-26 08:47:07 +0000130 delete[] array1;
131 delete[] array2;
Benoit Jacobe445f502007-10-13 16:56:24 +0000132}
133
134void EigenTest::testBasicStuff()
135{
136 basicStuff(Matrix<float, 1, 1>());
Benoit Jacobe445f502007-10-13 16:56:24 +0000137 basicStuff(Matrix<complex<double>, 4, 4>());
138 basicStuff(MatrixXcf(3, 3));
139 basicStuff(MatrixXi(8, 12));
140 basicStuff(MatrixXd(20, 20));
141}