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