Engauge Digitizer  2
TestMatrix.cpp
1 #include "Logger.h"
2 #include "MainWindow.h"
3 #include <qmath.h>
4 #include <QtTest/QtTest>
5 #include "Test/TestMatrix.h"
6 
7 QTEST_MAIN (TestMatrix)
8 
9 TestMatrix::TestMatrix(QObject *parent) :
10  QObject(parent)
11 {
12 }
13 
14 void TestMatrix::cleanupTestCase ()
15 {
16 }
17 
18 void TestMatrix::initTestCase ()
19 {
20  const QString NO_ERROR_REPORT_LOG_FILE;
21  const QString NO_REGRESSION_OPEN_FILE;
22  const bool NO_GNUPLOT_LOG_FILES = false;
23  const bool NO_REGRESSION_IMPORT = false;
24  const bool NO_RESET = false;
25  const bool DEBUG_FLAG = false;
26  const QStringList NO_LOAD_STARTUP_FILES;
27 
28  initializeLogging ("engauge_test",
29  "engauge_test.log",
30  DEBUG_FLAG);
31 
32  MainWindow w (NO_ERROR_REPORT_LOG_FILE,
33  NO_REGRESSION_OPEN_FILE,
34  NO_GNUPLOT_LOG_FILES,
35  NO_REGRESSION_IMPORT,
36  NO_RESET,
37  NO_LOAD_STARTUP_FILES);
38  w.show ();
39 }
40 
41 void TestMatrix::testDeterminant ()
42 {
43  Matrix m (3);
44  double a00 = 1, a01 = 2, a10 = 3, a11 = 4;
45 
46  m.set (0, 0, a00);
47  m.set (0, 1, a01);
48  m.set (1, 0, a10);
49  m.set (1, 1, a11);
50  QVERIFY ((m.determinant () == a00 * a11 - a01 * a10));
51 }
52 
53 void TestMatrix::testInverse ()
54 {
55  bool success = true;
56  int row, col;
57 
58  // Try 3x3 matrix. The 3 rows would be parallel if we had ((1,2,3),(4,5,6),(7,8,9)) which means there
59  // is no inverse so the last element is slightly tweaked
60  Matrix before (3);
61  int counter = 0;
62  for (row = 0; row < 3; row++) {
63  for (col = 0; col < 3; col++) {
64  before.set (row, col, ++counter);
65  }
66  }
67  before.set (2, 2, 10);
68 
69  Matrix after = before.inverse ();
70 
71  Matrix product = before * after;
72  Matrix identity (3);
73  for (row = 0; row < 3; row++) {
74  for (col = 0; col < 3; col++) {
75  if (qAbs (product.get (row, col) - identity.get (row, col)) > 0.00001) {
76  success = false;
77  break;
78  }
79  }
80  }
81 
82  QVERIFY (success);
83 }
84 
85 void TestMatrix::testInverse2 ()
86 {
87  bool success = true;
88  int row, col;
89 
90  // Try 2x2 matrix
91  Matrix before (2);
92  before.set (0, 0, 2);
93  before.set (0, 1, 1);
94  before.set (1, 0, 1);
95  before.set (1, 1, 1);
96 
97  Matrix after = before.inverse ();
98 
99  Matrix product = before * after;
100  Matrix identity (2);
101  for (row = 0; row < 2; row++) {
102  for (col = 0; col < 2; col++) {
103  if (qAbs (product.get (row, col) - identity.get (row, col)) > 0.00001) {
104  success = false;
105  break;
106  }
107  }
108  }
109 
110  QVERIFY (success);
111 }
112 
113 void TestMatrix::testMultiplyNonSquareMatrix ()
114 {
115  bool success = true;
116  int row, col;
117 
118  // Try 2x3 matrix with its own transpose
119  Matrix before (2, 3);
120  int counter = 0;
121  for (row = 0; row < 2; row++) {
122  for (col = 0; col < 3; col++) {
123  before.set (row, col, ++counter);
124  }
125  }
126 
127  // Multiply by its transpose
128  Matrix afterGot = before * before.transpose ();
129  Matrix afterWanted (2);
130 
131  if (afterGot.rows () == afterWanted.rows () &&
132  afterGot.cols () == afterWanted.cols ()) {
133 
134  afterWanted.set (0, 0, 1 * 1 + 2 * 2 + 3 * 3);
135  afterWanted.set (0, 1, 1 * 4 + 2 * 5 + 3 * 6);
136  afterWanted.set (1, 0, 4 * 1 + 5 * 2 + 6 * 3);
137  afterWanted.set (1, 1, 4 * 4 + 5 * 5 + 6 * 6);
138 
139  for (row = 0; row < 2; row++) {
140  for (col = 0; col < 2; col++) {
141  if (qAbs (afterWanted.get (row, col) - afterGot.get (row, col)) > 0.0001) {
142  success = false;
143  break;
144  }
145  }
146  }
147  } else {
148  success = false;
149  }
150 
151  QVERIFY (success);
152 }
153 
154 void TestMatrix::testMultiplyNonSquareMatrixAndVector ()
155 {
156  bool success = true;
157  int row, col;
158 
159  // Try 2x3 matrix and 3x1 vector
160  Matrix before (2, 3);
161  QVector<double> vec (3);
162  int counter = 0;
163  for (row = 0; row < 2; row++) {
164  for (col = 0; col < 3; col++) {
165  before.set (row, col, ++counter);
166  vec [col] = col + 1;
167  }
168  }
169 
170  // Multiply by itself
171  QVector<double> afterGot = before * vec;
172  QVector<double> afterWanted (2);
173 
174  if (afterGot.size () == afterWanted.size ()) {
175 
176  afterWanted [0] = 1 * 1 + 2 * 2 + 3 * 3;
177  afterWanted [1] = 4 * 1 + 5 * 2 + 6 * 3;
178 
179  for (row = 0; row < 2; row++) {
180  if (qAbs (afterWanted [row] - afterGot [row]) > 0.0001) {
181  success = false;
182  break;
183  }
184  }
185  } else {
186  success = false;
187  }
188 
189  QVERIFY (success);
190 }
191 
192 void TestMatrix::testMultiplySquareMatrix ()
193 {
194  bool success = true;
195  int row, col;
196 
197  // Try 3x3 matrix
198  Matrix before (3);
199  int counter = 0;
200  for (row = 0; row < 3; row++) {
201  for (col = 0; col < 3; col++) {
202  before.set (row, col, ++counter);
203  }
204  }
205 
206  // Multiply by itself
207  Matrix afterGot = before * before;
208  Matrix afterWanted (3);
209 
210  if (afterGot.rows() == afterWanted.rows() &&
211  afterGot.cols() == afterWanted.cols()) {
212 
213  afterWanted.set (0, 0, 1 * 1 + 2 * 4 + 3 * 7);
214  afterWanted.set (0, 1, 1 * 2 + 2 * 5 + 3 * 8);
215  afterWanted.set (0, 2, 1 * 3 + 2 * 6 + 3 * 9);
216  afterWanted.set (1, 0, 4 * 1 + 5 * 4 + 6 * 7);
217  afterWanted.set (1, 1, 4 * 2 + 5 * 5 + 6 * 8);
218  afterWanted.set (1, 2, 4 * 3 + 5 * 6 + 6 * 9);
219  afterWanted.set (2, 0, 7 * 1 + 8 * 4 + 9 * 7);
220  afterWanted.set (2, 1, 7 * 2 + 8 * 5 + 9 * 8);
221  afterWanted.set (2, 2, 7 * 3 + 8 * 6 + 9 * 9);
222 
223  for (row = 0; row < 3; row++) {
224  for (col = 0; col < 3; col++) {
225  if (qAbs (afterWanted.get (row, col) - afterGot.get (row, col)) > 0.0001) {
226  success = false;
227  break;
228  }
229  }
230  }
231  } else {
232  success = false;
233  }
234 
235  QVERIFY (success);
236 }
237 
238 void TestMatrix::testMultiplySquareMatrixAndVector ()
239 {
240  bool success = true;
241  int row, col;
242 
243  // Try 3x3 matrix and 3x1 vector
244  Matrix before (3);
245  QVector<double> vec (3);
246  int counter = 0;
247  for (row = 0; row < 3; row++) {
248  for (col = 0; col < 3; col++) {
249  before.set (row, col, ++counter);
250  }
251  vec [row] = row + 1;
252  }
253 
254  // Multiply by itself
255  QVector<double> afterGot = before * vec;
256  QVector<double> afterWanted (3);
257 
258  if (afterGot.size() == afterWanted.size()) {
259 
260  afterWanted [0] = 1 * 1 + 2 * 2 + 3 * 3;
261  afterWanted [1] = 4 * 1 + 5 * 2 + 6 * 3;
262  afterWanted [2] = 7 * 1 + 8 * 2 + 9 * 3;
263 
264  for (row = 0; row < 3; row++) {
265  if (qAbs (afterWanted [row] - afterGot [row]) > 0.0001) {
266  success = false;
267  break;
268  }
269  }
270  } else {
271  success = false;
272  }
273 
274  QVERIFY (success);
275 }
276 
277 void TestMatrix::testTranspose ()
278 {
279  bool success = true;
280  int row, col;
281 
282  // Try 3x3 matrix
283  Matrix before (3);
284  int counter = 0;
285  for (row = 0; row < 3; row++) {
286  for (col = 0; col < 3; col++) {
287  before.set (row, col, ++counter);
288  }
289  }
290 
291  Matrix after = before.transpose ();
292  for (row = 0; row < 3; row++) {
293  for (col = 0; col < 3; col++) {
294  if (before.get (row, col) != after.get (col, row)) {
295  success = false;
296  break;
297  }
298  }
299  }
300 
301  QVERIFY (success);
302 }
Matrix inverse() const
Return the inverse of this matrix.
Definition: Matrix.cpp:121
Matrix transpose() const
Return the transpose of the current matrix.
Definition: Matrix.cpp:410
double determinant() const
Return the determinant of this matrix.
Definition: Matrix.cpp:65
int cols() const
Width of matrix.
Definition: Matrix.cpp:60
Matrix class that supports arbitrary NxN size.
Definition: Matrix.h:14
Unit tests of matrix.
Definition: TestMatrix.h:8
int rows() const
Height of matrix.
Definition: Matrix.cpp:364
double get(int row, int col) const
Return (row, col) element.
Definition: Matrix.cpp:97
void set(int row, int col, double value)
Set (row, col) element.
Definition: Matrix.cpp:369
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:89