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