Commit e7b3222cc5ce3ca2ef25287c8ef1feb2a00ebfc8

Authored by Jürgen Knödlseder
1 parent 36fdf237

Use test suite for unit testing.

Refactored the code to use the GTestSuite and GTestSuites classes for unit testing. The basic test fonctionnalities were kept.
test/test_GSymMatrix.cpp
1 /*************************************************************************** 1 /***************************************************************************
2 - * test_GSymMatrix.cpp - test GSymMatrix class * 2 + * test_GSymMatrix.cpp - Test symmetric matrix class *
3 * ----------------------------------------------------------------------- * 3 * ----------------------------------------------------------------------- *
4 - * copyright (C) 2006-2010 by Jurgen Knodlseder * 4 + * copyright (C) 2006-2012 by Juergen Knoedlseder *
5 * ----------------------------------------------------------------------- * 5 * ----------------------------------------------------------------------- *
6 * * 6 * *
7 * This program is free software: you can redistribute it and/or modify * 7 * This program is free software: you can redistribute it and/or modify *
@@ -20,18 +20,16 @@ @@ -20,18 +20,16 @@
20 ***************************************************************************/ 20 ***************************************************************************/
21 /** 21 /**
22 * @file test_GSymMatrix.cpp 22 * @file test_GSymMatrix.cpp
23 - * @brief Testing of GSymMatrix class  
24 - * @author J. Knodlseder 23 + * @brief Implementation of unit tests for symmetric matrices
  24 + * @author Juergen Knoedlseder
25 */ 25 */
26 26
27 /* __ Includes ___________________________________________________________ */ 27 /* __ Includes ___________________________________________________________ */
28 -#include <iostream> // cout, cerr  
29 -#include <stdexcept> // std::exception 28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
30 #include <cmath> 31 #include <cmath>
31 -#include "GammaLib.hpp"  
32 -  
33 -/* __ Namespaces _________________________________________________________ */  
34 -using namespace std; 32 +#include "test_GSymMatrix.hpp"
35 33
36 /* __ Globals ____________________________________________________________ */ 34 /* __ Globals ____________________________________________________________ */
37 double g_matrix[] = {4.0, 1.0, 2.0, 1.0, 5.0, 3.0, 2.0, 3.0, 6.0}; 35 double g_matrix[] = {4.0, 1.0, 2.0, 1.0, 5.0, 3.0, 2.0, 3.0, 6.0};
@@ -41,760 +39,632 @@ int g_cols = 3; @@ -41,760 +39,632 @@ int g_cols = 3;
41 39
42 40
43 /*************************************************************************** 41 /***************************************************************************
44 - * Set test matrix * 42 + * @brief Set test matrix
45 ***************************************************************************/ 43 ***************************************************************************/
46 -GSymMatrix set_matrix(void) 44 +GSymMatrix TestGSymMatrix::set_matrix(void) const
47 { 45 {
48 - try { 46 + // Allocate matrix
49 GSymMatrix matrix(g_rows,g_cols); 47 GSymMatrix matrix(g_rows,g_cols);
  48 +
  49 + // Set matrix values
50 for (int row = 0; row < g_rows; ++row) { 50 for (int row = 0; row < g_rows; ++row) {
51 - for (int col = 0; col < g_cols; ++col)  
52 - matrix(row,col) = g_matrix[col+row*g_cols]; 51 + for (int col = 0; col < g_cols; ++col) {
  52 + matrix(row,col) = g_matrix[col+row*g_cols];
  53 + }
53 } 54 }
  55 +
  56 + // Return matrix
54 return matrix; 57 return matrix;
55 - }  
56 - catch (exception &e) {  
57 - cout << "TEST ERROR: Unable to set test matrix." << endl;  
58 - throw;  
59 - }  
60 - return GSymMatrix(g_rows,g_cols);  
61 } 58 }
62 59
63 60
64 /*************************************************************************** 61 /***************************************************************************
65 - * Set test matrix with zero lines * 62 + * @brief Set test matrix with zero lines
66 ***************************************************************************/ 63 ***************************************************************************/
67 -GSymMatrix set_matrix_zero(void) 64 +GSymMatrix TestGSymMatrix::set_matrix_zero(void) const
68 { 65 {
69 - try { 66 + // Allocate matrix
70 GSymMatrix matrix(g_rows+1,g_cols+1); 67 GSymMatrix matrix(g_rows+1,g_cols+1);
  68 +
  69 + // Set matrix values
71 int i = 0; 70 int i = 0;
72 for (int row = 0; row < g_rows+1; ++row) { 71 for (int row = 0; row < g_rows+1; ++row) {
73 - if (row == 2) continue;  
74 - int j = 0;  
75 - for (int col = 0; col < g_cols+1; ++col) {  
76 - if (col == 2) continue;  
77 - matrix(row,col) = g_matrix[j+i*g_cols];  
78 - j++;  
79 - }  
80 - i++;  
81 - } 72 + if (row == 2) continue;
  73 + int j = 0;
  74 + for (int col = 0; col < g_cols+1; ++col) {
  75 + if (col == 2) continue;
  76 + matrix(row,col) = g_matrix[j+i*g_cols];
  77 + j++;
  78 + }
  79 + i++;
  80 + }
  81 +
  82 + // Return matrix
82 return matrix; 83 return matrix;
83 - }  
84 - catch (exception &e) {  
85 - cout << "TEST ERROR: Unable to set test matrix." << endl;  
86 - throw;  
87 - }  
88 - return GSymMatrix(g_rows+1,g_cols+1);  
89 } 84 }
90 85
91 86
92 /*************************************************************************** 87 /***************************************************************************
93 - * Set test vector * 88 + * @brief Set test vector
94 ***************************************************************************/ 89 ***************************************************************************/
95 -GVector set_vector(void) 90 +GVector TestGSymMatrix::set_vector(void) const
96 { 91 {
97 - try { 92 + // Allocate vector
98 GVector vector(g_cols); 93 GVector vector(g_cols);
99 - for (int col = 0; col < g_cols; ++col)  
100 - vector[col] = g_vector[col]; 94 +
  95 + // Set vector values
  96 + for (int col = 0; col < g_cols; ++col) {
  97 + vector[col] = g_vector[col];
  98 + }
  99 +
  100 + // Return vector
101 return vector; 101 return vector;
102 - }  
103 - catch (exception &e) {  
104 - cout << "TEST ERROR: Unable to set test vector." << endl;  
105 - throw;  
106 - }  
107 - return GVector(g_cols);  
108 } 102 }
109 103
110 104
111 /*************************************************************************** 105 /***************************************************************************
112 - * Check test matrix * 106 + * @brief Check if symmetric matrix corresponds to test matrix
  107 + *
  108 + * @param[in] matrix Symmetric matrix
  109 + * @param[in] scale scale factor (default: 1.0)
  110 + * @param[in] offset offset value (default: 0.0)
  111 + *
  112 + * Checks if a matrix corresponds to the test matrix. Optionally, the test
  113 + * matrix can be scaled and an offset can be added.
113 ***************************************************************************/ 114 ***************************************************************************/
114 -int check_matrix(const GSymMatrix& m, const double scale, const double add) 115 +bool TestGSymMatrix::check_matrix(const GSymMatrix& matrix,
  116 + const double& scale,
  117 + const double& offset) const
115 { 118 {
116 - int result = 1;  
117 - try { 119 + // Initialise check with true
  120 + bool result = true;
  121 +
  122 + // Compare all matrix elements
118 for (int row = 0; row < g_rows; ++row) { 123 for (int row = 0; row < g_rows; ++row) {
119 - for (int col = 0; col < g_cols; ++col) {  
120 - double value = g_matrix[col+row*g_cols] * scale + add;  
121 - if (abs(m(row,col)-value) > 1.0e-15) {  
122 - result = 0;  
123 - break;  
124 - }  
125 - } 124 + for (int col = 0; col < g_cols; ++col) {
  125 + double value = g_matrix[col+row*g_cols] * scale + offset;
  126 + if (std::abs(matrix(row,col)-value) > 1.0e-15) {
  127 + result = false;
  128 + break;
  129 + }
  130 + }
126 } 131 }
127 - }  
128 - catch (exception &e) {  
129 - cout << "TEST ERROR: Unable to check test matrix." << endl;  
130 - throw;  
131 - }  
132 - return result; 132 +
  133 + // Return result
  134 + return result;
133 } 135 }
134 136
135 137
136 /*************************************************************************** 138 /***************************************************************************
137 - * Check full test matrix * 139 + * @brief Check if general matrix corresponds to test matrix
  140 + *
  141 + * @param[in] matrix General matrix
  142 + * @param[in] scale scale factor (default: 1.0)
  143 + * @param[in] offset offset value (default: 0.0)
  144 + *
  145 + * Checks if a matrix corresponds to the test matrix. Optionally, the test
  146 + * matrix can be scaled and an offset can be added.
138 ***************************************************************************/ 147 ***************************************************************************/
139 -int check_matrix(const GMatrix& m, const double scale, const double add) 148 +bool TestGSymMatrix::check_matrix(const GMatrix& matrix,
  149 + const double& scale,
  150 + const double& offset) const
140 { 151 {
141 - int result = 1;  
142 - try { 152 + // Initialise check with true
  153 + bool result = true;
  154 +
  155 + // Compare all matrix elements
143 for (int row = 0; row < g_rows; ++row) { 156 for (int row = 0; row < g_rows; ++row) {
144 - for (int col = 0; col < g_cols; ++col) {  
145 - double value = g_matrix[col+row*g_cols] * scale + add;  
146 - if (m(row,col) != value) {  
147 - result = 0;  
148 - break;  
149 - }  
150 - } 157 + for (int col = 0; col < g_cols; ++col) {
  158 + double value = g_matrix[col+row*g_cols] * scale + offset;
  159 + if (std::abs(matrix(row,col)-value) > 1.0e-15) {
  160 + result = false;
  161 + break;
  162 + }
  163 + }
151 } 164 }
152 - }  
153 - catch (exception &e) {  
154 - cout << "TEST ERROR: Unable to check test matrix." << endl;  
155 - throw;  
156 - }  
157 - return result; 165 +
  166 + // Return result
  167 + return result;
158 } 168 }
159 169
160 170
161 /*************************************************************************** 171 /***************************************************************************
162 - * Check full test matrix (lower triangle) * 172 + * @brief Check lower triangle general matrix
  173 + *
  174 + * @param[in] matrix General matrix
  175 + * @param[in] scale scale factor (default: 1.0)
  176 + * @param[in] offset offset value (default: 0.0)
163 ***************************************************************************/ 177 ***************************************************************************/
164 -int check_matrix_lt(const GMatrix& m, const double scale, const double add) 178 +bool TestGSymMatrix::check_matrix_lt(const GMatrix& matrix,
  179 + const double& scale,
  180 + const double& offset) const
165 { 181 {
166 - int result = 1;  
167 - try { 182 + // Initialise check with true
  183 + bool result = true;
  184 +
  185 + // Compare all matrix elements
168 for (int row = 0; row < g_rows; ++row) { 186 for (int row = 0; row < g_rows; ++row) {
169 - for (int col = 0; col < g_cols; ++col) {  
170 - double value = (col <= row) ? g_matrix[col+row*g_cols] * scale + add : 0.0;  
171 - if (m(row,col) != value) {  
172 - result = 0;  
173 - break;  
174 - }  
175 - }  
176 - }  
177 - }  
178 - catch (exception &e) {  
179 - cout << "TEST ERROR: Unable to check test matrix." << endl;  
180 - throw;  
181 - }  
182 - return result; 187 + for (int col = 0; col < g_cols; ++col) {
  188 + double value = (col <= row) ?
  189 + g_matrix[col+row*g_cols] * scale + offset : 0.0;
  190 + if (matrix(row,col) != value) {
  191 + result = false;
  192 + break;
  193 + }
  194 + }
  195 + }
  196 +
  197 + // Return result
  198 + return result;
183 } 199 }
184 200
185 201
186 /*************************************************************************** 202 /***************************************************************************
187 - * Check full test matrix (upper triangle) * 203 + * @brief Check upper triangle general matrix
  204 + *
  205 + * @param[in] matrix General matrix
  206 + * @param[in] scale scale factor (default: 1.0)
  207 + * @param[in] offset offset value (default: 0.0)
188 ***************************************************************************/ 208 ***************************************************************************/
189 -int check_matrix_ut(const GMatrix& m, const double scale, const double add) 209 +bool TestGSymMatrix::check_matrix_ut(const GMatrix& matrix,
  210 + const double& scale,
  211 + const double& offset) const
190 { 212 {
191 - int result = 1;  
192 - try { 213 + // Initialise check with true
  214 + bool result = true;
  215 +
  216 + // Compare all matrix elements
193 for (int row = 0; row < g_rows; ++row) { 217 for (int row = 0; row < g_rows; ++row) {
194 - for (int col = 0; col < g_cols; ++col) {  
195 - double value = (col >= row) ? g_matrix[col+row*g_cols] * scale + add : 0.0;  
196 - if (m(row,col) != value) {  
197 - result = 0;  
198 - break;  
199 - }  
200 - }  
201 - }  
202 - }  
203 - catch (exception &e) {  
204 - cout << "TEST ERROR: Unable to check test matrix." << endl;  
205 - throw;  
206 - }  
207 - return result; 218 + for (int col = 0; col < g_cols; ++col) {
  219 + double value = (col >= row) ?
  220 + g_matrix[col+row*g_cols] * scale + offset : 0.0;
  221 + if (matrix(row,col) != value) {
  222 + result = false;
  223 + break;
  224 + }
  225 + }
  226 + }
  227 +
  228 + // Return result
  229 + return result;
208 } 230 }
209 231
210 232
211 -/***************************************************************************  
212 - * Check matrix*vector *  
213 - ***************************************************************************/  
214 -int check_matrix_vector(const GVector& v) 233 +/***********************************************************************//**
  234 + * @brief Set parameters and tests
  235 + **************************************************************************/
  236 +void TestGSymMatrix::set(void)
215 { 237 {
216 - int result = 1;  
217 - try {  
218 - for (int row = 0; row < v.size(); ++row) {  
219 - double value = 0.0;  
220 - for (int col = 0; col < g_cols; ++col)  
221 - value += g_matrix[col+row*g_cols] * g_vector[col];  
222 - if (v[row] != value) {  
223 - result = 0;  
224 - break;  
225 - }  
226 - }  
227 - }  
228 - catch (exception &e) {  
229 - cout << "TEST ERROR: Unable to check matrix*vector product." << endl;  
230 - throw;  
231 - }  
232 - return result; 238 + // Set test name
  239 + name("GSymMatrix");
  240 +
  241 + // Add tests
  242 + append(static_cast<pfunction>(&TestGSymMatrix::alloc_matrix), "Test matrix allocation");
  243 + append(static_cast<pfunction>(&TestGSymMatrix::assign_values), "Test value assignment");
  244 + append(static_cast<pfunction>(&TestGSymMatrix::copy_matrix), "Test matrix copying");
  245 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_operations), "Test matrix operations");
  246 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_arithmetics), "Test matrix arithmetics");
  247 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_functions), "Test matrix functions");
  248 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_compare), "Test matrix comparisons");
  249 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_cholesky), "Test matrix Cholesky decomposition");
  250 + append(static_cast<pfunction>(&TestGSymMatrix::matrix_print), "Test matrix printing");
  251 +
  252 + // Set members
  253 + m_test = set_matrix();
  254 + v_test = set_vector();
  255 + m_bigger = GSymMatrix(g_rows+1, g_cols+1);
  256 +
  257 + // Return
  258 + return;
233 } 259 }
234 260
235 261
236 -/***************************************************************************  
237 - * Check matrix*matrix * 262 +/***********************************************************************//**
  263 + * @brief Test matrix allocation
238 ***************************************************************************/ 264 ***************************************************************************/
239 -int check_matrix_matrix(const GSymMatrix& m) 265 +void TestGSymMatrix::alloc_matrix(void)
240 { 266 {
241 - if (m.rows() != g_rows || m.cols() != g_rows)  
242 - return 0;  
243 - int result = 1;  
244 - try {  
245 - for (int row = 0; row < m.rows(); ++row) {  
246 - for (int col = 0; col < m.cols(); ++col) {  
247 - double value = 0.0;  
248 - for (int i = 0; i < g_cols; ++i)  
249 - value += g_matrix[i+row*g_cols] * g_matrix[i+col*g_cols];  
250 - if (m(row,col) != value) {  
251 - result = 0;  
252 - break;  
253 - }  
254 - }  
255 - }  
256 - }  
257 - catch (exception &e) {  
258 - cout << "TEST ERROR: Unable to check matrix*matrix product." << endl;  
259 - throw;  
260 - }  
261 - return result; 267 + // Allocate zero matrix. The allocation should fail.
  268 + test_try("Allocate zero matrix");
  269 + try {
  270 + GSymMatrix test(0,0);
  271 + test_try_failure();
  272 + }
  273 + catch (GException::empty &e) {
  274 + test_try_success();
  275 + }
  276 + catch (std::exception &e) {
  277 + test_try_failure(e);
  278 + }
  279 +
  280 + // Return
  281 + return;
262 } 282 }
263 283
264 284
265 -/***************************************************************************  
266 - * Check matrix min * 285 +/***********************************************************************//**
  286 + * @brief Test value assignment
267 ***************************************************************************/ 287 ***************************************************************************/
268 -int check_matrix_min(const double min) 288 +void TestGSymMatrix::assign_values(void)
269 { 289 {
270 - double value = g_matrix[0];  
271 - for (int row = 0; row < g_rows; ++row) {  
272 - for (int col = 0; col < g_cols; ++col) {  
273 - if (g_matrix[col+row*g_cols] < value)  
274 - value = g_matrix[col+row*g_cols];  
275 - }  
276 - }  
277 - return (min == value);  
278 -} 290 + // Setup 3x3 matrix
  291 + GSymMatrix test(3,3);
  292 +
  293 + // Assignment individual values
  294 + for (int i = 0; i < 3; ++i) {
  295 + for (int k = 0; k < 3; ++k) {
  296 + double value = i*2.0 + k*2.0;
  297 + test(i,k) = value;
  298 + }
  299 + }
279 300
  301 + // Check assignment of individual values
  302 + for (int i = 0; i < 3; ++i) {
  303 + for (int k = 0; k < 3; ++k) {
  304 + double value = i*2.0 + k*2.0;
  305 + test_value(test(i,k), value, 1.0e-10, "Test matrix element assignment");
  306 + }
  307 + }
280 308
281 -/***************************************************************************  
282 - * Check matrix max *  
283 - ***************************************************************************/  
284 -int check_matrix_max(const double max)  
285 -{  
286 - double value = g_matrix[0];  
287 - for (int row = 0; row < g_rows; ++row) {  
288 - for (int col = 0; col < g_cols; ++col) {  
289 - if (g_matrix[col+row*g_cols] > value)  
290 - value = g_matrix[col+row*g_cols];  
291 - }  
292 - }  
293 - return (max == value); 309 + // Verify range checking
  310 + #ifdef G_RANGE_CHECK
  311 + test_try("Verify range checking");
  312 + try {
  313 + test(3,3) = 1.0;
  314 + test_try_failure();
  315 + }
  316 + catch (GException::out_of_range &e) {
  317 + test_try_success();
  318 + }
  319 + catch (std::exception &e) {
  320 + test_try_failure(e);
  321 + }
  322 + #endif
  323 +
  324 + // Return
  325 + return;
294 } 326 }
295 327
296 328
297 -/***************************************************************************  
298 - * Check matrix sum * 329 +/***********************************************************************//**
  330 + * @brief Test matrix copy
299 ***************************************************************************/ 331 ***************************************************************************/
300 -int check_matrix_sum(const double sum) 332 +void TestGSymMatrix::copy_matrix(void)
301 { 333 {
302 - double value = 0.0;  
303 - for (int row = 0; row < g_rows; ++row) {  
304 - for (int col = 0; col < g_cols; ++col)  
305 - value += g_matrix[col+row*g_cols];  
306 - }  
307 - return (sum == value); 334 + // Copy matrix
  335 + GSymMatrix test = m_test;
  336 +
  337 + // Test if original and compied matrices are correct
  338 + test_assert(check_matrix(m_test), "Test source matrix");
  339 + test_assert(check_matrix(test), "Test matrix copy operator", test.print());
  340 +
  341 + // Return
  342 + return;
308 } 343 }
309 344
310 345
311 -/***************************************************************************  
312 - * Test: Output * 346 +/***********************************************************************//**
  347 + * @brief Test matrix operations
  348 + *
  349 + * Tests matrix*vector and matrix*matrix multiplication operations.
313 ***************************************************************************/ 350 ***************************************************************************/
314 -void test_output(const GSymMatrix& m_test) 351 +void TestGSymMatrix::matrix_operations(void)
315 { 352 {
316 - cout << "Test GSymMatrix: Output test matrix: " << endl;  
317 - try {  
318 - cout << m_test << endl;  
319 - }  
320 - catch (exception &e) {  
321 - cout << endl << "TEST ERROR: Unable to output matrix." << endl;  
322 - cout << e.what() << endl;  
323 - throw;  
324 - }  
325 -} 353 + // Perform vector multiplication
  354 + GVector test1 = m_test * v_test;
  355 +
  356 + // Check if the result vector is as expected
  357 + bool result = true;
  358 + for (int row = 0; row < g_rows; ++row) {
  359 + double value = 0.0;
  360 + for (int col = 0; col < g_cols; ++col) {
  361 + value += g_matrix[col+row*g_cols] * g_vector[col];
  362 + }
  363 + if (test1[row] != value) {
  364 + result = false;
  365 + break;
  366 + }
  367 + }
326 368
  369 + // Test if original matrix and result vector are correct
  370 + test_assert(check_matrix(m_test), "Test source matrix");
  371 + test_assert(result, "Test matrix*vector multiplication", test1.print());
327 372
328 -/***************************************************************************  
329 - * Main test function *  
330 - ***************************************************************************/  
331 -int main(void)  
332 -{  
333 - // Dump header  
334 - cout << endl;  
335 - cout << "****************************" << endl;  
336 - cout << "* GSymMatrix class testing *" << endl;  
337 - cout << "****************************" << endl;  
338 -  
339 - // Set test matrix and vector  
340 - GSymMatrix m_test = set_matrix();  
341 - GVector v_test = set_vector();  
342 -  
343 - // Set bigger matrix (only used for collision, don't care about content)  
344 - GSymMatrix bigger(g_rows+1,g_cols+1);  
345 -  
346 - // Prepare result matrix  
347 - GSymMatrix result = m_test;  
348 -  
349 - // Execute the tests  
350 - test_output(m_test);  
351 -  
352 - // Test 1: Allocate zero matrix  
353 - try {  
354 - cout << "GSymMatrix - Test 1: Allocate zero matrix: ";  
355 - GSymMatrix test1(0,0);  
356 - }  
357 - catch (GException::empty &e) {  
358 - cout << "ok." << endl;  
359 - }  
360 - catch (exception &e) {  
361 - cout << endl << "TEST ERROR: Did not signal zero matrix allocation." << endl;  
362 - cout << e.what() << endl;  
363 - throw;  
364 - }  
365 -  
366 - // Test 2: Allocate too large matrix  
367 - /*  
368 - try {  
369 - cout << "GSymMatrix - Test 2: Allocate too large matrix: ";  
370 - GSymMatrix test2(100000000,100000000);  
371 - }  
372 - catch (bad_alloc &e) {  
373 - cout << "ok." << endl;  
374 - }  
375 - catch (exception &e) {  
376 - cout << endl << "TEST ERROR: Did not signal out of memory condition." << endl;  
377 - cout << e.what() << endl;  
378 - throw;  
379 - }  
380 - */  
381 -  
382 - // Test 3: Assign values  
383 - try {  
384 - cout << "GSymMatrix - Test 3: Assign matrix values: ";  
385 - //  
386 - GSymMatrix test3(3,3);  
387 - test3(1,1) = 1.0;  
388 - if (test3(0,0) != 0.0 || test3(1,0) != 0.0 || test3(2,0) != 0.0 ||  
389 - test3(0,1) != 0.0 || test3(1,1) != 1.0 || test3(2,1) != 0.0 ||  
390 - test3(0,2) != 0.0 || test3(1,2) != 0.0 || test3(2,2) != 0.0) {  
391 - cout << endl << "TEST ERROR: Unable to set matrix value." << endl;  
392 - cout << test3 << endl;  
393 - throw;  
394 - }  
395 - }  
396 - catch (exception &e) {  
397 - cout << e.what() << endl;  
398 - throw;  
399 - }  
400 - #if defined(G_RANGE_CHECK) 373 + // Test incompatible vector multiplication
  374 + test_try("Test incompatible matrix*vector multiplication");
401 try { 375 try {
402 - GSymMatrix test3(3,3);  
403 - test3(3,3) = 1.0; 376 + GVector test2 = m_bigger * v_test;
  377 + test_try_failure();
404 } 378 }
405 - catch (GException::out_of_range &e) { 379 + catch (GException::matrix_vector_mismatch &e) {
  380 + test_try_success();
406 } 381 }
407 - catch (exception &e) {  
408 - cout << e.what() << endl;  
409 - throw; 382 + catch (std::exception &e) {
  383 + test_try_failure(e);
410 } 384 }
411 - #endif  
412 - cout << "ok." << endl;  
413 -  
414 - // Test 4: Matrix copy constructor  
415 - try {  
416 - cout << "GSymMatrix - Test 4: Define matrix using copy constructor: ";  
417 - //  
418 - GSymMatrix test4 = m_test;  
419 - if (!check_matrix(test4, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
420 - cout << endl << "TEST ERROR: Corrupt copy constructor." << endl;  
421 - cout << test4 << endl;  
422 - throw;  
423 - }  
424 - }  
425 - catch (exception &e) {  
426 - cout << e.what() << endl;  
427 - throw;  
428 - }  
429 - cout << "ok." << endl;  
430 -  
431 - // Test 5: Matrix assignment  
432 - try {  
433 - cout << "GSymMatrix - Test 5: Matrix assignment: ";  
434 - //  
435 - // GSymMatrix = GSymMatrix  
436 - result = m_test;  
437 - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
438 - cout << endl << "TEST ERROR: Corrupt assignment." << endl;  
439 - cout << result << endl;  
440 - throw;  
441 - }  
442 - //  
443 - // GSymMatrix = GSymMatrix (bigger matrix)  
444 - result = bigger;  
445 - }  
446 - catch (exception &e) {  
447 - cout << e.what() << endl;  
448 - throw;  
449 - }  
450 - cout << "ok." << endl;  
451 -  
452 - // Test 6: Matrix*Vector multiplication  
453 - try {  
454 - cout << "GSymMatrix - Test 6: Matrix*Vector multiplication: ";  
455 - //  
456 - GVector v_test6 = m_test*v_test;  
457 - if (!check_matrix_vector(v_test6) || !check_matrix(m_test, 1.0, 0.0)) {  
458 - cout << endl << "TEST ERROR: Corrupt Matrix*Vector multiplication." << endl;  
459 - cout << v_test6 << endl;  
460 - throw;  
461 - }  
462 - }  
463 - catch (exception &e) {  
464 - cout << e.what() << endl;  
465 - throw;  
466 - }  
467 - try {  
468 - GVector v_test6 = bigger*v_test;  
469 - }  
470 - catch (GException::matrix_vector_mismatch &e) {  
471 - }  
472 - catch (exception &e) {  
473 - cout << e.what() << endl;  
474 - throw;  
475 - }  
476 - cout << "ok." << endl;  
477 -  
478 - // Test 7: Matrix*Matrix multiplication  
479 - try {  
480 - cout << "GSymMatrix - Test 7: Matrix*Matrix multiplication: ";  
481 - //  
482 - GSymMatrix m_test7 = m_test*m_test;  
483 - if (!check_matrix_matrix(m_test7) || !check_matrix(m_test, 1.0, 0.0)) {  
484 - cout << endl << "TEST ERROR: Corrupt Matrix*Matrix multiplication." << endl;  
485 - cout << m_test7 << endl;  
486 - throw;  
487 - }  
488 - }  
489 - catch (exception &e) {  
490 - cout << e.what() << endl;  
491 - throw;  
492 - }  
493 - try {  
494 - GSymMatrix m_test7 = m_test*bigger;  
495 - }  
496 - catch (GException::matrix_mismatch &e) {  
497 - }  
498 - catch (exception &e) {  
499 - cout << e.what() << endl;  
500 - throw;  
501 - }  
502 - try {  
503 - GSymMatrix m_test7 = bigger*m_test;  
504 - }  
505 - catch (GException::matrix_mismatch &e) {  
506 - }  
507 - catch (exception &e) {  
508 - cout << e.what() << endl;  
509 - throw;  
510 - }  
511 - cout << "ok." << endl;  
512 -  
513 - // Test 8: Assignment and arithmetics  
514 - try {  
515 - cout << "GSymMatrix - Test 8: Assignment and arithmetics: ";  
516 - // 385 +
  386 + // Test matrix multiplication
  387 + GSymMatrix test3 = m_test * m_test;
  388 +
  389 + // Check if the result matrix is as expected
  390 + result = true;
  391 + for (int row = 0; row < test3.rows(); ++row) {
  392 + for (int col = 0; col < test3.cols(); ++col) {
  393 + double value = 0.0;
  394 + for (int i = 0; i < g_cols; ++i) {
  395 + value += g_matrix[i+row*g_cols] * g_matrix[i+col*g_cols];
  396 + }
  397 + if (test3(row,col) != value) {
  398 + result = false;
  399 + break;
  400 + }
  401 + }
  402 + }
  403 +
  404 + // Test if original matrix and result matrix are correct
  405 + test_assert(check_matrix(m_test), "Test source matrix");
  406 + test_assert(result, "Test matrix multiplication", test3.print());
  407 + test_assert(test3.rows() == g_rows, "Test number of rows of result matrix");
  408 + test_assert(test3.cols() == g_cols, "Test number of columns of result matrix");
  409 +
  410 + // Test incompatible matrix multiplication
  411 + test_try("Test incompatible matrix multiplication");
  412 + try {
  413 + GSymMatrix test4 = m_test * m_bigger;
  414 + test_try_failure();
  415 + }
  416 + catch (GException::matrix_mismatch &e) {
  417 + test_try_success();
  418 + }
  419 + catch (std::exception &e) {
  420 + test_try_failure(e);
  421 + }
  422 +
  423 + // Test another incompatible matrix multiplication
  424 + test_try("Test incompatible matrix multiplication");
  425 + try {
  426 + GSymMatrix test5 = m_bigger * m_test;
  427 + test_try_failure();
  428 + }
  429 + catch (GException::matrix_mismatch &e) {
  430 + test_try_success();
  431 + }
  432 + catch (std::exception &e) {
  433 + test_try_failure(e);
  434 + }
  435 +
  436 + // Return
  437 + return;
  438 +}
  439 +
  440 +
  441 +/***********************************************************************//**
  442 + * @brief Test matrix arithmetics
  443 + *
  444 + * Tests matrix arithmetics.
  445 + ***************************************************************************/
  446 +void TestGSymMatrix::matrix_arithmetics(void)
  447 +{
517 // -GSymMatrix 448 // -GSymMatrix
518 - result = -m_test;  
519 - if (!check_matrix(result, -1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
520 - cout << endl << "TEST ERROR: Corrupt -GSymMatrix operator." << endl;  
521 - cout << result << endl;  
522 - throw;  
523 - }  
524 - // 449 + GSymMatrix test = -m_test;
  450 + test_assert(check_matrix(m_test), "Test source matrix");
  451 + test_assert(check_matrix(test, -1.0, 0.0), "Test -GSymMatrix",
  452 + test.print());
  453 +
525 // GSymMatrix += GSymMatrix 454 // GSymMatrix += GSymMatrix
526 - result = m_test;  
527 - result += m_test;  
528 - if (!check_matrix(result, 2.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
529 - cout << endl << "TEST ERROR: Corrupt GSymMatrix += GSymMatrix operator." << endl;  
530 - cout << result << endl;  
531 - throw;  
532 - }  
533 - // 455 + test = m_test;
  456 + test += m_test;
  457 + test_assert(check_matrix(m_test), "Test source matrix");
  458 + test_assert(check_matrix(test, 2.0, 0.0), "Test GSymMatrix += GSymMatrix",
  459 + test.print());
  460 +
534 // GSymMatrix -= GSymMatrix 461 // GSymMatrix -= GSymMatrix
535 - result = m_test;  
536 - result -= m_test;  
537 - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
538 - cout << endl << "TEST ERROR: Corrupt GSymMatrix -= GSymMatrix operator." << endl;  
539 - cout << result << endl;  
540 - throw;  
541 - }  
542 - // 462 + test = m_test;
  463 + test -= m_test;
  464 + test_assert(check_matrix(m_test), "Test source matrix");
  465 + test_assert(check_matrix(test, 0.0, 0.0), "Test GSymMatrix -= GSymMatrix",
  466 + test.print());
  467 +
543 // GSymMatrix *= 3.0 468 // GSymMatrix *= 3.0
544 - result = m_test;  
545 - result *= 3.0;  
546 - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
547 - cout << endl << "TEST ERROR: Corrupt GSymMatrix *= double operator." << endl;  
548 - cout << result << endl;  
549 - throw;  
550 - }  
551 - // 469 + test = m_test;
  470 + test *= 3.0;
  471 + test_assert(check_matrix(m_test), "Test source matrix");
  472 + test_assert(check_matrix(test, 3.0, 0.0), "Test GSymMatrix *= 3.0",
  473 + test.print());
  474 +
552 // GSymMatrix /= 3.0 475 // GSymMatrix /= 3.0
553 - result = m_test;  
554 - result /= 3.0;  
555 - if (!check_matrix(result, 1.0/3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
556 - cout << endl << "TEST ERROR: Corrupt GSymMatrix /= double operator." << endl;  
557 - cout << result << endl;  
558 - throw;  
559 - }  
560 - // 476 + test = m_test;
  477 + test /= 3.0;
  478 + test_assert(check_matrix(m_test), "Test source matrix");
  479 + test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSymMatrix /= 3.0",
  480 + test.print());
  481 +
561 // GSymMatrix + GSymMatrix 482 // GSymMatrix + GSymMatrix
562 - result = m_test + m_test;  
563 - if (!check_matrix(result, 2.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
564 - cout << endl << "TEST ERROR: Corrupt GSymMatrix + GSymMatrix operator." << endl;  
565 - cout << result << endl;  
566 - throw;  
567 - }  
568 - //  
569 - // GSymMatrix - GSymMatrix  
570 - result = m_test - m_test;  
571 - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
572 - cout << endl << "TEST ERROR: Corrupt GSymMatrix - GSymMatrix operator." << endl;  
573 - cout << result << endl;  
574 - throw;  
575 - }  
576 - // 483 + test = m_test + m_test;
  484 + test_assert(check_matrix(m_test), "Test source matrix");
  485 + test_assert(check_matrix(test, 2.0, 0.0), "Test GSymMatrix + GSymMatrix",
  486 + test.print());
  487 +
577 // GSymMatrix - GSymMatrix 488 // GSymMatrix - GSymMatrix
578 - result = m_test - m_test;  
579 - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
580 - cout << endl << "TEST ERROR: Corrupt GSymMatrix - GSymMatrix operator." << endl;  
581 - cout << result << endl;  
582 - throw;  
583 - }  
584 - // 489 + test = m_test - m_test;
  490 + test_assert(check_matrix(m_test), "Test source matrix");
  491 + test_assert(check_matrix(test, 0.0, 0.0), "Test GSymMatrix - GSymMatrix",
  492 + test.print());
  493 +
585 // GSymMatrix * 3.0 494 // GSymMatrix * 3.0
586 - result = m_test * 3.0;  
587 - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
588 - cout << endl << "TEST ERROR: Corrupt GSymMatrix * double operator." << endl;  
589 - cout << result << endl;  
590 - throw;  
591 - }  
592 - // 495 + test = m_test * 3.0;
  496 + test_assert(check_matrix(m_test), "Test source matrix");
  497 + test_assert(check_matrix(test, 3.0, 0.0), "Test GSymMatrix * 3.0",
  498 + test.print());
  499 +
593 // 3.0 * GSymMatrix 500 // 3.0 * GSymMatrix
594 - result = 3.0 * m_test;  
595 - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
596 - cout << endl << "TEST ERROR: Corrupt double * GSymMatrix operator." << endl;  
597 - cout << result << endl;  
598 - throw;  
599 - }  
600 - // 501 + test = 3.0 * m_test;
  502 + test_assert(check_matrix(m_test), "Test source matrix");
  503 + test_assert(check_matrix(test, 3.0, 0.0), "Test 3.0 * GSymMatrix",
  504 + test.print());
  505 +
601 // GSymMatrix / 3.0 506 // GSymMatrix / 3.0
602 - result = m_test / 3.0;  
603 - if (!check_matrix(result, 1.0/3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
604 - cout << endl << "TEST ERROR: Corrupt GSymMatrix / double operator." << endl;  
605 - cout << result << endl;  
606 - throw;  
607 - }  
608 - }  
609 - catch (exception &e) {  
610 - cout << e.what() << endl;  
611 - throw;  
612 - }  
613 - try {  
614 - result = m_test;  
615 - result += bigger;  
616 - }  
617 - catch (GException::matrix_mismatch &e) {  
618 - }  
619 - catch (exception &e) {  
620 - cout << e.what() << endl;  
621 - throw;  
622 - }  
623 - cout << "ok." << endl;  
624 -  
625 - // Test 9: Matrix functions  
626 - try {  
627 - cout << "GSymMatrix - Test 9: Matrix functions: ";  
628 - // 507 + test = m_test / 3.0;
  508 + test_assert(check_matrix(m_test), "Test source matrix");
  509 + test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSymMatrix / 3.0",
  510 + test.print());
  511 +
  512 + // Test invalid matrix addition
  513 + test_try("Test invalid matrix addition");
  514 + try {
  515 + test = m_test;
  516 + test += m_bigger;
  517 + test_try_failure();
  518 + }
  519 + catch (GException::matrix_mismatch &e) {
  520 + test_try_success();
  521 + }
  522 + catch (std::exception &e) {
  523 + test_try_failure(e);
  524 + }
  525 +
  526 + // Return
  527 + return;
  528 +}
  529 +
  530 +
  531 +/***********************************************************************//**
  532 + * @brief Test matrix functions
  533 + *
  534 + * Tests matrix functions.
  535 + ***************************************************************************/
  536 +void TestGSymMatrix::matrix_functions(void)
  537 +{
  538 + // Minimum
629 double min = m_test.min(); 539 double min = m_test.min();
630 - if (!check_matrix_min(min)) {  
631 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.min() function." << endl;  
632 - cout << min << endl;  
633 - throw;  
634 - }  
635 - //  
636 - double max = m_test.max();  
637 - if (!check_matrix_max(max)) {  
638 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.max() function." << endl;  
639 - cout << min << endl;  
640 - throw;  
641 - }  
642 - //  
643 - double sum = m_test.sum();  
644 - if (!check_matrix_sum(sum)) {  
645 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.sum() function." << endl;  
646 - cout << sum << endl;  
647 - throw;  
648 - }  
649 - }  
650 - catch (exception &e) {  
651 - cout << e.what() << endl;  
652 - }  
653 - cout << "ok." << endl;  
654 -  
655 - // Test 10: Matrix comparison  
656 - try {  
657 - cout << "GSymMatrix - Test 10: Comparison: ";  
658 - //  
659 - if ((m_test == m_test) != 1) {  
660 - cout << endl << "TEST ERROR: Corrupt GSymMatrix == GSymMatrix operator." << endl;  
661 - throw;  
662 - }  
663 - //  
664 - GSymMatrix m_test10(g_rows,g_cols);  
665 - if ((m_test == m_test10) != 0) {  
666 - cout << endl << "TEST ERROR: Corrupt GSymMatrix == GSymMatrix operator." << endl;  
667 - throw;  
668 - }  
669 - //  
670 - if ((m_test == bigger) != 0) {  
671 - cout << endl << "TEST ERROR: Corrupt GSymMatrix == GSymMatrix operator." << endl;  
672 - throw;  
673 - }  
674 - //  
675 - if ((m_test != m_test) != 0) {  
676 - cout << endl << "TEST ERROR: Corrupt GSymMatrix != GSymMatrix operator." << endl;  
677 - throw;  
678 - }  
679 - //  
680 - if ((m_test != m_test10) != 1) {  
681 - cout << endl << "TEST ERROR: Corrupt GSymMatrix != GSymMatrix operator." << endl;  
682 - throw;  
683 - }  
684 - //  
685 - if ((m_test != bigger) != 1) {  
686 - cout << endl << "TEST ERROR: Corrupt GSymMatrix != GSymMatrix operator." << endl;  
687 - throw;  
688 - }  
689 - }  
690 - catch (exception &e) {  
691 - cout << e.what() << endl;  
692 - throw;  
693 - }  
694 - cout << "ok." << endl;  
695 -  
696 - // Test 11: Transformations  
697 - try {  
698 - cout << "GSymMatrix - Test 11: Transformations: ";  
699 - //  
700 - // transpose(GSymMatrix)  
701 - result = transpose(m_test);  
702 - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
703 - cout << endl << "TEST ERROR: Corrupt transpose(GSymMatrix) function." << endl;  
704 - cout << result << endl;  
705 - throw;  
706 - }  
707 - //  
708 - // GSymMatrix.transpose()  
709 - result = m_test;  
710 - result.transpose();  
711 - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
712 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.transpose() function." << endl;  
713 - cout << result << endl;  
714 - throw;  
715 - }  
716 - //  
717 - // convert_to_full()  
718 - GMatrix m_test11 = matrix(m_test);  
719 - if (!check_matrix(m_test11, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
720 - cout << endl << "TEST ERROR: Corrupt convert_to_full() operator." << endl;  
721 - cout << m_test11 << endl;  
722 - throw; 540 +
  541 + // Check mimimum
  542 + double value = g_matrix[0];
  543 + for (int row = 0; row < g_rows; ++row) {
  544 + for (int col = 0; col < g_cols; ++col) {
  545 + if (g_matrix[col+row*g_cols] < value) {
  546 + value = g_matrix[col+row*g_cols];
  547 + }
  548 + }
723 } 549 }
724 - //  
725 - // extract_lower_triangle()  
726 - m_test11 = m_test.extract_lower_triangle();  
727 - if (!check_matrix_lt(m_test11, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
728 - cout << endl << "TEST ERROR: Corrupt extract_lower_triangle() function." << endl;  
729 - cout << m_test11 << endl;  
730 - throw; 550 + test_value(min, value, 0.0, "Test minimum function");
  551 +
  552 + // Maximum
  553 + double max = m_test.max();
  554 +
  555 + // Check maximum
  556 + value = g_matrix[0];
  557 + for (int row = 0; row < g_rows; ++row) {
  558 + for (int col = 0; col < g_cols; ++col) {
  559 + if (g_matrix[col+row*g_cols] > value) {
  560 + value = g_matrix[col+row*g_cols];
  561 + }
  562 + }
731 } 563 }
732 - //  
733 - // extract_upper_triangle()  
734 - m_test11 = m_test.extract_upper_triangle();  
735 - if (!check_matrix_ut(m_test11, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {  
736 - cout << endl << "TEST ERROR: Corrupt extract_upper_triangle() function." << endl;  
737 - cout << m_test11 << endl;  
738 - throw; 564 + test_value(max, value, 0.0, "Test maximum function");
  565 +
  566 + // Sum
  567 + double sum = m_test.sum();
  568 +
  569 + // Check sum
  570 + value = 0.0;
  571 + for (int row = 0; row < g_rows; ++row) {
  572 + for (int col = 0; col < g_cols; ++col) {
  573 + value += g_matrix[col+row*g_cols];
  574 + }
739 } 575 }
  576 + test_value(sum, value, 1.0e-20, "Test sum function");
  577 +
  578 + // Transpose function
  579 + GSymMatrix test1 = transpose(m_test);
  580 + test_assert(check_matrix(m_test), "Test source matrix");
  581 + test_assert(check_matrix(test1, 1.0, 0.0), "Test transpose(GSymMatrix) function",
  582 + test1.print());
  583 +
  584 + // Transpose method
  585 + test1 = m_test;
  586 + test1.transpose();
  587 + test_assert(check_matrix(m_test), "Test source matrix");
  588 + test_assert(check_matrix(test1, 1.0, 0.0), "Test GSymMatrix.transpose() method",
  589 + test1.print());
  590 +
  591 + // Convert to general matrix
  592 + GMatrix test2 = GMatrix(m_test);
  593 + test_assert(check_matrix(m_test), "Test source matrix");
  594 + test_assert(check_matrix(test2, 1.0, 0.0), "Test GMatrix(GSymMatrix) constructor",
  595 + test2.print());
  596 +
  597 + // Extract lower triangle
  598 + test2 = m_test.extract_lower_triangle();
  599 + test_assert(check_matrix(m_test), "Test source matrix");
  600 + test_assert(check_matrix_lt(test2, 1.0, 0.0),
  601 + "Test GSymMatrix.extract_lower_triangle() method",
  602 + test2.print());
  603 +
  604 + // Extract upper triangle
  605 + test2 = m_test.extract_upper_triangle();
  606 + test_assert(check_matrix(m_test), "Test source matrix");
  607 + test_assert(check_matrix_ut(test2, 1.0, 0.0),
  608 + "Test GSymMatrix.extract_upper_triangle() method",
  609 + test2.print());
  610 +
  611 + // Return
  612 + return;
  613 +}
  614 +
  615 +
  616 +/***********************************************************************//**
  617 + * @brief Test matrix comparisons
  618 + ***************************************************************************/
  619 +void TestGSymMatrix::matrix_compare(void)
  620 +{
  621 + // Allocate an empty matrix
  622 + GSymMatrix empty(g_rows,g_cols);
  623 +
  624 + // Test operators
  625 + test_assert((m_test == m_test), "Test == operator");
  626 + test_assert(!(m_test == empty), "Test == operator");
  627 + test_assert(!(m_test == m_bigger), "Test == operator");
  628 + test_assert(!(m_test != m_test), "Test != operator");
  629 + test_assert((m_test != empty), "Test != operator");
  630 + test_assert((m_test != m_bigger), "Test != operator");
  631 +
  632 + // Return
  633 + return;
  634 +}
740 635
741 - }  
742 - catch (exception &e) {  
743 - cout << e.what() << endl;  
744 - throw;  
745 - }  
746 - cout << "ok." << endl;  
747 -  
748 - // Test 12: Perform Cholesky decomposition  
749 - try {  
750 - cout << "GSymMatrix - Test 12: Cholesky decomposition, solver and inverter: ";  
751 - // 636 +
  637 +/***********************************************************************//**
  638 + * @brief Test Cholesky decomposition
  639 + ***************************************************************************/
  640 +void TestGSymMatrix::matrix_cholesky(void)
  641 +{
752 // Test Cholesky decomposition 642 // Test Cholesky decomposition
753 GSymMatrix cd = cholesky_decompose(m_test); 643 GSymMatrix cd = cholesky_decompose(m_test);
754 GMatrix cd_lower = cd.extract_lower_triangle(); 644 GMatrix cd_lower = cd.extract_lower_triangle();
755 GMatrix cd_upper = transpose(cd_lower); 645 GMatrix cd_upper = transpose(cd_lower);
756 GMatrix cd_product = cd_lower * cd_upper; 646 GMatrix cd_product = cd_lower * cd_upper;
757 GMatrix cd_residuals = matrix(m_test) - cd_product; 647 GMatrix cd_residuals = matrix(m_test) - cd_product;
758 - //  
759 double res = (abs(cd_residuals)).max(); 648 double res = (abs(cd_residuals)).max();
760 - if (res < 1.0e-15)  
761 - cout << "Res(CD)=" << res << " ";  
762 - else {  
763 - cout << endl << "TEST ERROR: Corrupt cholesky_decompose(GSymMatrix) function." << endl;  
764 - cout << "Residual matrix (all elements should be zero):" << endl;  
765 - cout << cd_residuals << endl;  
766 - throw;  
767 - }  
768 - // 649 + test_value(res, 0.0, 1.0e-15, "Test cholesky_decompose() method");
  650 +
769 // Test compressed Cholesky decomposition 651 // Test compressed Cholesky decomposition
770 - GSymMatrix m_test_zero = set_matrix_zero();  
771 - GSymMatrix cd_zero = cholesky_decompose(m_test_zero); 652 + GSymMatrix test_zero = set_matrix_zero();
  653 + GSymMatrix cd_zero = cholesky_decompose(test_zero);
772 GMatrix cd_zero_lower = cd_zero.extract_lower_triangle(); 654 GMatrix cd_zero_lower = cd_zero.extract_lower_triangle();
773 GMatrix cd_zero_upper = transpose(cd_zero_lower); 655 GMatrix cd_zero_upper = transpose(cd_zero_lower);
774 GMatrix cd_zero_product = cd_zero_lower * cd_zero_upper; 656 GMatrix cd_zero_product = cd_zero_lower * cd_zero_upper;
775 - GMatrix cd_zero_residuals = matrix(m_test_zero) - cd_zero_product;  
776 - // 657 + GMatrix cd_zero_residuals = matrix(test_zero) - cd_zero_product;
777 res = (abs(cd_zero_residuals)).max(); 658 res = (abs(cd_zero_residuals)).max();
778 - if (res < 1.0e-15)  
779 - cout << "Res(CDZ)=" << res << " ";  
780 - else {  
781 - cout << endl << "TEST ERROR: Corrupt compressed cholesky_decompose(GSymMatrix) function." << endl;  
782 - cout << "Residual matrix (all elements should be zero):" << endl;  
783 - cout << cd_zero_residuals << endl;  
784 - throw;  
785 - }  
786 - // 659 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_decompose() method");
  660 +
787 // Test Cholesky inplace decomposition 661 // Test Cholesky inplace decomposition
788 - GSymMatrix m_test12 = m_test;  
789 - m_test12.cholesky_decompose();  
790 - GMatrix cd_lower2 = m_test12.extract_lower_triangle();  
791 - if (cd_lower2 != cd_lower) {  
792 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.cholesky_decompose() function." << endl;  
793 - cout << cd_lower2 << endl;  
794 - throw;  
795 - }  
796 - //  
797 - // Test Cholesky solver 662 + GSymMatrix test = m_test;
  663 + test.cholesky_decompose();
  664 + GMatrix cd_lower2 = test.extract_lower_triangle();
  665 + test_assert((cd_lower2 == cd_lower), "Test inplace cholesky_decompose() method");
  666 +
  667 + // Test Cholesky solver (first test)
798 GVector e0(g_rows); 668 GVector e0(g_rows);
799 GVector a0(g_rows); 669 GVector a0(g_rows);
800 e0[0] = 1.0; 670 e0[0] = 1.0;
@@ -805,15 +675,9 @@ int main(void) @@ -805,15 +675,9 @@ int main(void)
805 a0[2] = g_matrix[6]; 675 a0[2] = g_matrix[6];
806 GVector s0 = cd.cholesky_solver(a0) - e0; 676 GVector s0 = cd.cholesky_solver(a0) - e0;
807 res = max(abs(s0)); 677 res = max(abs(s0));
808 - if (res < 1.0e-15)  
809 - cout << "Res(S0)=" << res << " ";  
810 - else {  
811 - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;  
812 - cout << "Residual vector (all elements should be zero):" << endl;  
813 - cout << s0 << endl;  
814 - throw;  
815 - }  
816 - // 678 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method");
  679 +
  680 + // Test Cholesky solver (second test)
817 e0[0] = 0.0; 681 e0[0] = 0.0;
818 e0[1] = 1.0; 682 e0[1] = 1.0;
819 e0[2] = 0.0; 683 e0[2] = 0.0;
@@ -822,15 +686,9 @@ int main(void) @@ -822,15 +686,9 @@ int main(void)
822 a0[2] = g_matrix[7]; 686 a0[2] = g_matrix[7];
823 s0 = cd.cholesky_solver(a0) - e0; 687 s0 = cd.cholesky_solver(a0) - e0;
824 res = max(abs(s0)); 688 res = max(abs(s0));
825 - if (res < 1.0e-15)  
826 - cout << "Res(S1)=" << res << " ";  
827 - else {  
828 - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;  
829 - cout << "Residual vector (all elements should be zero):" << endl;  
830 - cout << s0 << endl;  
831 - throw;  
832 - }  
833 - // 689 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method");
  690 +
  691 + // Test Cholesky solver (third test)
834 e0[0] = 0.0; 692 e0[0] = 0.0;
835 e0[1] = 0.0; 693 e0[1] = 0.0;
836 e0[2] = 1.0; 694 e0[2] = 1.0;
@@ -839,16 +697,9 @@ int main(void) @@ -839,16 +697,9 @@ int main(void)
839 a0[2] = g_matrix[8]; 697 a0[2] = g_matrix[8];
840 s0 = cd.cholesky_solver(a0) - e0; 698 s0 = cd.cholesky_solver(a0) - e0;
841 res = max(abs(s0)); 699 res = max(abs(s0));
842 - if (res < 1.0e-15)  
843 - cout << "Res(S2)=" << res << " ";  
844 - else {  
845 - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;  
846 - cout << "Residual vector (all elements should be zero):" << endl;  
847 - cout << s0 << endl;  
848 - throw;  
849 - }  
850 - //  
851 - // Test compressed Cholesky solver 700 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method");
  701 +
  702 + // Test compressed Cholesky solver (first test)
852 e0 = GVector(g_rows+1); 703 e0 = GVector(g_rows+1);
853 a0 = GVector(g_rows+1); 704 a0 = GVector(g_rows+1);
854 e0[0] = 1.0; 705 e0[0] = 1.0;
@@ -861,15 +712,9 @@ int main(void) @@ -861,15 +712,9 @@ int main(void)
861 a0[3] = g_matrix[6]; 712 a0[3] = g_matrix[6];
862 s0 = cd_zero.cholesky_solver(a0) - e0; 713 s0 = cd_zero.cholesky_solver(a0) - e0;
863 res = max(abs(s0)); 714 res = max(abs(s0));
864 - if (res < 1.0e-15)  
865 - cout << "Res(S0Z)=" << res << " ";  
866 - else {  
867 - cout << endl << "TEST ERROR: Corrupt compressed cholesky_solver(GVector) function." << endl;  
868 - cout << "Residual vector (all elements should be zero):" << endl;  
869 - cout << s0 << endl;  
870 - throw;  
871 - }  
872 - // 715 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method");
  716 +
  717 + // Test compressed Cholesky solver (second test)
873 e0[0] = 0.0; 718 e0[0] = 0.0;
874 e0[1] = 1.0; 719 e0[1] = 1.0;
875 e0[2] = 0.0; 720 e0[2] = 0.0;
@@ -880,15 +725,9 @@ int main(void) @@ -880,15 +725,9 @@ int main(void)
880 a0[3] = g_matrix[7]; 725 a0[3] = g_matrix[7];
881 s0 = cd_zero.cholesky_solver(a0) - e0; 726 s0 = cd_zero.cholesky_solver(a0) - e0;
882 res = max(abs(s0)); 727 res = max(abs(s0));
883 - if (res < 1.0e-15)  
884 - cout << "Res(S1Z)=" << res << " ";  
885 - else {  
886 - cout << endl << "TEST ERROR: Corrupt compressed cholesky_solver(GVector) function." << endl;  
887 - cout << "Residual vector (all elements should be zero):" << endl;  
888 - cout << s0 << endl;  
889 - throw;  
890 - }  
891 - // 728 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method");
  729 +
  730 + // Test compressed Cholesky solver (third test)
892 e0[0] = 0.0; 731 e0[0] = 0.0;
893 e0[1] = 0.0; 732 e0[1] = 0.0;
894 e0[2] = 0.0; 733 e0[2] = 0.0;
@@ -899,58 +738,81 @@ int main(void) @@ -899,58 +738,81 @@ int main(void)
899 a0[3] = g_matrix[8]; 738 a0[3] = g_matrix[8];
900 s0 = cd_zero.cholesky_solver(a0) - e0; 739 s0 = cd_zero.cholesky_solver(a0) - e0;
901 res = max(abs(s0)); 740 res = max(abs(s0));
902 - if (res < 1.0e-15)  
903 - cout << "Res(S2Z)=" << res << " ";  
904 - else {  
905 - cout << endl << "TEST ERROR: Corrupt compressed cholesky_solver(GVector) function." << endl;  
906 - cout << "Residual vector (all elements should be zero):" << endl;  
907 - cout << s0 << endl;  
908 - throw;  
909 - }  
910 - // 741 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method");
  742 +
911 // Test Cholesky inverter 743 // Test Cholesky inverter
912 GSymMatrix unit(g_rows,g_cols); 744 GSymMatrix unit(g_rows,g_cols);
913 unit(0,0) = unit(1,1) = unit(2,2) = 1.0; 745 unit(0,0) = unit(1,1) = unit(2,2) = 1.0;
914 - GSymMatrix m_test12_inv = m_test;  
915 - m_test12_inv.cholesky_invert();  
916 - GSymMatrix ci_product = m_test * m_test12_inv; 746 + GSymMatrix test_inv = m_test;
  747 + test_inv.cholesky_invert();
  748 + GSymMatrix ci_product = m_test * test_inv;
917 GSymMatrix ci_residuals = ci_product - unit; 749 GSymMatrix ci_residuals = ci_product - unit;
918 - //  
919 res = (abs(ci_residuals)).max(); 750 res = (abs(ci_residuals)).max();
920 - if (res < 1.0e-15)  
921 - cout << "Res(CI)=" << res << " ";  
922 - else {  
923 - cout << endl << "TEST ERROR: Corrupt GSymMatrix.cholesky_invert() function." << endl;  
924 - cout << "Residual matrix (all elements should be zero):" << endl;  
925 - cout << ci_residuals << endl;  
926 - throw;  
927 - }  
928 - // 751 + test_value(res, 0.0, 1.0e-15, "Test cholesky_invert method");
  752 +
929 // Test Cholesky inverter for compressed matrix 753 // Test Cholesky inverter for compressed matrix
930 unit = GSymMatrix(4,4); 754 unit = GSymMatrix(4,4);
931 unit(0,0) = unit(1,1) = unit(3,3) = 1.0; 755 unit(0,0) = unit(1,1) = unit(3,3) = 1.0;
932 - GSymMatrix m_test12_zero_inv = m_test_zero;  
933 - m_test12_zero_inv.cholesky_invert();  
934 - GSymMatrix ciz_product = m_test_zero * m_test12_zero_inv; 756 + GSymMatrix test_zero_inv = test_zero;
  757 + test_zero_inv.cholesky_invert();
  758 + GSymMatrix ciz_product = test_zero * test_zero_inv;
935 GSymMatrix ciz_residuals = ciz_product - unit; 759 GSymMatrix ciz_residuals = ciz_product - unit;
936 - //  
937 res = (abs(ciz_residuals)).max(); 760 res = (abs(ciz_residuals)).max();
938 - if (res < 1.0e-15)  
939 - cout << "Res(CIZ)=" << res << " ";  
940 - else {  
941 - cout << endl << "TEST ERROR: Corrupt compressed GSymMatrix.cholesky_invert() function." << endl;  
942 - cout << "Residual matrix (all elements should be zero):" << endl;  
943 - cout << ciz_residuals << endl;  
944 - throw;  
945 - }  
946 - }  
947 - catch (exception &e) {  
948 - cout << e.what() << endl;  
949 - throw;  
950 - }  
951 - cout << "ok." << endl; 761 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_invert method");
  762 +
  763 + // Return
  764 + return;
  765 +}
  766 +
  767 +
  768 +/***************************************************************************
  769 + * @brief Test matrix printing
  770 + ***************************************************************************/
  771 +void TestGSymMatrix::matrix_print(void)
  772 +{
  773 + // Set reference
  774 + std::string reference;
  775 + reference.append("=== GSymMatrix ===\n");
  776 + reference.append(" Number of rows ............: 3\n");
  777 + reference.append(" Number of columns .........: 3\n");
  778 + reference.append(" Number of elements ........: 6\n");
  779 + reference.append(" Number of allocated cells .: 6\n");
  780 + reference.append(" 4, 1, 2\n");
  781 + reference.append(" 1, 5, 3\n");
  782 + reference.append(" 2, 3, 6");
  783 +
  784 + // Test the print method
  785 + std::string output = m_test.print();
  786 + test_assert((output == reference), "Test matrix printing", output);
  787 +
  788 + // Return
  789 + return;
  790 +}
  791 +
  792 +
  793 +/***************************************************************************
  794 + * @brief Main entry point for test executable
  795 + ***************************************************************************/
  796 +int main(void)
  797 +{
  798 + // Allocate test suit container
  799 + GTestSuites testsuites("GSymMatrix class testing");
  800 +
  801 + // Initially assume that we pass all tests
  802 + bool success = true;
  803 +
  804 + // Create a test suite
  805 + TestGSymMatrix test;
  806 +
  807 + // Append test suite to the container
  808 + testsuites.append(test);
  809 +
  810 + // Run the testsuites
  811 + success = testsuites.run();
952 812
953 - // Return  
954 - return 0; 813 + // Save test report
  814 + testsuites.save("reports/GSymMatrix.xml");
955 815
  816 + // Return success status
  817 + return (success ? 0 : 1);
956 } 818 }
test/test_GSymMatrix.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * test_GSymMatrix.hpp - Test symmetric matrix class *
  3 + * ----------------------------------------------------------------------- *
  4 + * copyright (C) 2012 by Juergen Knoedlseder *
  5 + * ----------------------------------------------------------------------- *
  6 + * *
  7 + * This program is free software: you can redistribute it and/or modify *
  8 + * it under the terms of the GNU General Public License as published by *
  9 + * the Free Software Foundation, either version 3 of the License, or *
  10 + * (at your option) any later version. *
  11 + * *
  12 + * This program is distributed in the hope that it will be useful, *
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  15 + * GNU General Public License for more details. *
  16 + * *
  17 + * You should have received a copy of the GNU General Public License *
  18 + * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  19 + * *
  20 + ***************************************************************************/
  21 +/**
  22 + * @file test_GSymMatrix.hpp
  23 + * @brief Definition of unit tests for symmetric matrices
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef TEST_GSYMMATRIX_HPP
  28 +#define TEST_GSYMMATRIX_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include "GammaLib.hpp"
  32 +
  33 +
  34 +/***********************************************************************//**
  35 + * @class TestGSymMatrix
  36 + *
  37 + * @brief Test suite for symmetric matrix class testing
  38 + *
  39 + * This test suite performs a unit test for the symmetrix matrix class. Tests
  40 + * that match logically are gathered in a number of class methods, and the
  41 + * class methods are executed when running the test.
  42 + ***************************************************************************/
  43 +class TestGSymMatrix : public GTestSuite {
  44 +
  45 +public:
  46 + // Constructors and destructors
  47 + TestGSymMatrix(void) : GTestSuite() {}
  48 + virtual ~TestGSymMatrix(void) {}
  49 +
  50 + // Methods
  51 + virtual void set(void);
  52 + void alloc_matrix(void);
  53 + void assign_values(void);
  54 + void copy_matrix(void);
  55 + void matrix_operations(void);
  56 + void matrix_arithmetics(void);
  57 + void matrix_functions(void);
  58 + void matrix_compare(void);
  59 + void matrix_cholesky(void);
  60 + void matrix_print(void);
  61 +
  62 +private:
  63 + // Private methods
  64 + GSymMatrix set_matrix(void) const;
  65 + GSymMatrix set_matrix_zero(void) const;
  66 + GVector set_vector(void) const;
  67 + bool check_matrix(const GSymMatrix& matrix,
  68 + const double& scale = 1.0,
  69 + const double& offset = 0.0) const;
  70 + bool check_matrix(const GMatrix& matrix,
  71 + const double& scale = 1.0,
  72 + const double& offset = 0.0) const;
  73 + bool check_matrix_lt(const GMatrix& matrix,
  74 + const double& scale,
  75 + const double& offset) const;
  76 + bool check_matrix_ut(const GMatrix& matrix,
  77 + const double& scale,
  78 + const double& offset) const;
  79 +
  80 + // Private members;
  81 + GSymMatrix m_test; //!< Test matrix
  82 + GSymMatrix m_bigger; //!< Bigger test matrix (for collisions)
  83 + GVector v_test; //!< Test vector
  84 +};
  85 +
  86 +#endif /* TEST_GSYMMATRIX_HPP */