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