Commit 973bbf0b466cf93b8671dafedffb59fed43416f7

Authored by Jürgen Knödlseder
1 parent ada01abc

Use unit testsuite for testing.

Adapt the unit test for the usage of the new GammaLib test suite. Test reports are now reported in a JUnit compliant XML file.
test/test_GSparseMatrix.cpp
1 1 /***************************************************************************
2   - * test_GSparseMatrix.cpp - test GSparseMatrix class *
  2 + * test_GSparseMatrix.cpp - Test sparse matrix class *
3 3 * ----------------------------------------------------------------------- *
4   - * copyright (C) 2006-2011 by Jurgen Knodlseder *
  4 + * copyright (C) 2006-2012 by Juergen Knoedlseder *
5 5 * ----------------------------------------------------------------------- *
6 6 * *
7 7 * This program is free software: you can redistribute it and/or modify *
... ... @@ -20,23 +20,16 @@
20 20 ***************************************************************************/
21 21 /**
22 22 * @file test_GSparseMatrix.cpp
23   - * @brief Testing of GSparseMatrix class
24   - * @author J. Knodlseder
  23 + * @brief Implementation of unit tests for sparse matrices
  24 + * @author Juergen Knoedlseder
25 25 */
26 26  
27 27 /* __ Includes ___________________________________________________________ */
28   -#include <cstdlib>
  28 +#ifdef HAVE_CONFIG_H
  29 +#include <config.h>
  30 +#endif
29 31 #include <cmath>
30   -#include <iostream> // cout, cerr
31   -#include <stdexcept> // std::exception
32   -#include "GammaLib.hpp"
33   -
34   -/* __ Namespaces _________________________________________________________ */
35   -using namespace std;
36   -
37   -/* __ Definitions ________________________________________________________ */
38   -//#define DUMP_RESIDUALS // Dump residuals
39   -#define DUMP_TIMING // Dump timing
  32 +#include "test_GSparseMatrix.hpp"
40 33  
41 34 /* __ Globals ____________________________________________________________ */
42 35 double g_matrix[] = {1.0, 7.0, 3.0, 2.0, 4.0, 8.0, 5.0, 6.0, 9.0};
... ... @@ -49,1207 +42,1033 @@ int g_cols = 5;
49 42  
50 43  
51 44 /***************************************************************************
52   - * Set test matrix *
  45 + * @brief Set test matrix
53 46 ***************************************************************************/
54   -GSparseMatrix set_matrix(void)
  47 +GSparseMatrix TestGSparseMatrix::set_matrix(void) const
55 48 {
56   - try {
57   - GSparseMatrix matrix(g_rows,g_cols);
58   - for (int i = 0; i < g_elements; ++i)
59   - matrix(g_row[i],g_col[i]) = g_matrix[i];
60   - return matrix;
61   - }
62   - catch (exception &e) {
63   - cout << "TEST ERROR: Unable to set test matrix." << endl;
64   - throw;
65   - }
66   - return GSparseMatrix(g_rows,g_cols);
67   -}
  49 + // Allocate matrix
  50 + GSparseMatrix matrix(g_rows, g_cols);
68 51  
  52 + // Set matrix values
  53 + for (int i = 0; i < g_elements; ++i) {
  54 + matrix(g_row[i],g_col[i]) = g_matrix[i];
  55 + }
69 56  
70   -/***************************************************************************
71   - * Set test vector *
72   - ***************************************************************************/
73   -GVector set_vector(void)
74   -{
75   - try {
76   - GVector vector(g_cols);
77   - for (int col = 0; col < g_cols; ++col)
78   - vector[col] = g_vector[col];
79   - return vector;
80   - }
81   - catch (exception &e) {
82   - cout << "TEST ERROR: Unable to set test vector." << endl;
83   - throw;
84   - }
85   - return GVector(g_cols);
  57 + // Return matrix
  58 + return matrix;
86 59 }
87 60  
88 61  
89 62 /***************************************************************************
90   - * Check test matrix *
  63 + * @brief Set test matrix with zero lines
91 64 ***************************************************************************/
92   -int check_matrix(const GSparseMatrix& m, const double scale, const double add)
  65 +/*
  66 +GSparseMatrix TestGSparseMatrix::set_matrix_zero(void) const
93 67 {
94   - int result = 1;
95   - try {
96   - for (int row = 0; row < g_rows; ++row) {
97   - for (int col = 0; col < g_cols; ++col) {
98   - int i;
99   - double ref_value = add;
100   - for (i = 0; i < g_elements; ++i) {
101   - if (g_row[i] == row && g_col[i] == col) {
102   - ref_value = g_matrix[i] * scale + add;
103   - break;
104   - }
105   - }
106   - if (abs(m(row,col)-ref_value) > 1.0e-15) {
107   - result = 0;
108   - break;
109   - }
110   - }
111   - }
112   - }
113   - catch (exception &e) {
114   - cout << "TEST ERROR: Unable to check test matrix." << endl;
115   - throw;
116   - }
117   - return result;
118   -}
  68 + // Allocate matrix
  69 + GSparseMatrix matrix(g_rows+1,g_cols+1);
  70 +
  71 + // Set matrix values
  72 + int i = 0;
  73 + for (int row = 0; row < g_rows+1; ++row) {
  74 + if (row == 2) continue;
  75 + int j = 0;
  76 + for (int col = 0; col < g_cols+1; ++col) {
  77 + if (col == 2) continue;
  78 + matrix(row,col) = g_matrix[j+i*g_cols];
  79 + j++;
  80 + }
  81 + i++;
  82 + }
119 83  
  84 + // Return matrix
  85 + return matrix;
  86 +}
  87 +*/
120 88  
121 89 /***************************************************************************
122   - * Check matrix*vector *
  90 + * @brief Set test vector
123 91 ***************************************************************************/
124   -int check_matrix_vector(const GVector& v)
  92 +GVector TestGSparseMatrix::set_vector(void) const
125 93 {
126   - int result = 1;
127   - try {
128   - for (int row = 0; row < v.size(); ++row) {
129   - double value = 0.0;
130   - for (int col = 0; col < g_cols; ++col) {
131   - int i;
132   - double ref_value = 0.0;
133   - for (i = 0; i < g_elements; ++i) {
134   - if (g_row[i] == row && g_col[i] == col) {
135   - ref_value = g_matrix[i];
136   - break;
137   - }
138   - }
139   - value += ref_value * g_vector[col];
140   - }
141   - if (v[row] != value) {
142   - result = 0;
143   - break;
144   - }
  94 + // Allocate vector
  95 + GVector vector(g_cols);
  96 +
  97 + // Set vector values
  98 + for (int col = 0; col < g_cols; ++col) {
  99 + vector[col] = g_vector[col];
145 100 }
146   - }
147   - catch (exception &e) {
148   - cout << "TEST ERROR: Unable to check matrix*vector product." << endl;
149   - throw;
150   - }
151   - return result;
  101 +
  102 + // Return vector
  103 + return vector;
152 104 }
153 105  
154 106  
155 107 /***************************************************************************
156   - * Check matrix*matrix *
  108 + * @brief Check if matrix corresponds to test matrix
  109 + *
  110 + * @param[in] matrix Matrix.
  111 + * @param[in] scale scale factor (default: 1.0).
  112 + * @param[in] offset offset value (default: 0.0).
  113 + *
  114 + * Checks if a matrix corresponds to the test matrix. Optionally, the test
  115 + * matrix can be scaled and an offset can be added.
157 116 ***************************************************************************/
158   -int check_matrix_matrix(const GSparseMatrix& m)
  117 +bool TestGSparseMatrix::check_matrix(const GSparseMatrix& matrix,
  118 + const double& scale,
  119 + const double& offset) const
159 120 {
160   - if (m.rows() != g_rows || m.cols() != g_rows)
161   - return 0;
162   - int result = 1;
163   - try {
164   - for (int row = 0; row < m.rows(); ++row) {
165   - for (int col = 0; col < m.cols(); ++col) {
166   - double value = 0.0;
167   - for (int i = 0; i < g_cols; ++i) {
168   - int k;
169   - double ref_value_1 = 0.0;
170   - double ref_value_2 = 0.0;
171   - for (k = 0; k < g_elements; ++k) {
172   - if (g_row[k] == row && g_col[k] == i) {
173   - ref_value_1 = g_matrix[k];
174   - break;
175   - }
176   - }
177   - for (k = 0; k < g_elements; ++k) {
178   - if (g_row[k] == col && g_col[k] == i) {
179   - ref_value_2 = g_matrix[k];
180   - break;
181   - }
182   - }
183   - value += ref_value_1 * ref_value_2;
184   - }
185   -//cout << row << "," << col << ": " << abs(m(row,col)-value) << endl;
186   - if (m(row,col) != value) {
187   - result = 0;
188   - break;
189   - }
190   - }
191   - }
192   - }
193   - catch (exception &e) {
194   - cout << "TEST ERROR: Unable to check matrix*matrix product." << endl;
195   - throw;
196   - }
197   - return result;
  121 + // Initialise check with true
  122 + bool result = true;
  123 +
  124 + // Compare all matrix elements
  125 + for (int row = 0; row < g_rows; ++row) {
  126 + for (int col = 0; col < g_cols; ++col) {
  127 +
  128 + // Set reference value
  129 + double ref_value = offset;
  130 + for (int i = 0; i < g_elements; ++i) {
  131 + if (g_row[i] == row && g_col[i] == col) {
  132 + ref_value = g_matrix[i] * scale + offset;
  133 + break;
  134 + }
  135 + }
  136 +
  137 + // Check matrix
  138 + if (std::abs(matrix(row,col)-ref_value) > 1.0e-15) {
  139 + result = false;
  140 + break;
  141 + }
  142 +
  143 + } // endfor: looped over columns
  144 + } // endfor: looped over rows
  145 +
  146 + // Return result
  147 + return result;
198 148 }
199 149  
200 150  
201 151 /***************************************************************************
202   - * Check transposed test matrix *
  152 + * @brief Check if transposed matrix corresponds to test matrix
  153 + *
  154 + * @param[in] matrix Trasposed matrix.
  155 + * @param[in] scale scale factor (default: 1.0).
  156 + * @param[in] offset offset value (default: 0.0).
  157 + *
  158 + * Checks if a matrix corresponds to the test matrix. Optionally, the test
  159 + * matrix can be scaled and an offset can be added.
203 160 ***************************************************************************/
204   -int check_transpose_matrix(const GSparseMatrix& m, const double scale, const double add)
  161 +bool TestGSparseMatrix::check_matrix_trans(const GSparseMatrix& matrix,
  162 + const double& scale,
  163 + const double& offset) const
205 164 {
206   - int result = 1;
207   - try {
  165 + // Initialise check with true
  166 + bool result = true;
  167 +
  168 + // Compare all matrix elements
208 169 for (int row = 0; row < g_rows; ++row) {
209   - for (int col = 0; col < g_cols; ++col) {
210   - int i;
211   - double ref_value = 0.0;
212   - for (i = 0; i < g_elements; ++i) {
213   - if (g_row[i] == row && g_col[i] == col) {
214   - ref_value = g_matrix[i] * scale + add;
215   - break;
216   - }
217   - }
218   - if (abs(m(col,row)-ref_value) > 1.0e-15) {
219   - result = 0;
220   - break;
221   - }
222   - }
223   - }
224   - }
225   - catch (exception &e) {
226   - cout << "TEST ERROR: Unable to check test matrix." << endl;
227   - throw;
228   - }
229   - return result;
230   -}
  170 + for (int col = 0; col < g_cols; ++col) {
  171 +
  172 + // Set reference value
  173 + double ref_value = offset;
  174 + for (int i = 0; i < g_elements; ++i) {
  175 + if (g_row[i] == row && g_col[i] == col) {
  176 + ref_value = g_matrix[i] * scale + offset;
  177 + break;
  178 + }
  179 + }
231 180  
  181 + // Check matrix
  182 + if (std::abs(matrix(col,row)-ref_value) > 1.0e-15) {
  183 + result = false;
  184 + break;
  185 + }
  186 +
  187 + } // endfor: looped over columns
  188 + } // endfor: looped over rows
232 189  
233   -/***************************************************************************
234   - * Check matrix min *
235   - ***************************************************************************/
236   -int check_matrix_min(const double min)
237   -{
238   - double value = g_matrix[0];
239   - for (int i = 0; i < g_elements; ++i) {
240   - if (g_matrix[i] < value)
241   - value = g_matrix[i];
242   - }
243   -// return (min == value);
244   - return (min == 0.0);
  190 + // Return result
  191 + return result;
245 192 }
246 193  
247 194  
248 195 /***************************************************************************
249   - * Check matrix max *
  196 + * @brief Check lower triangle general matrix
  197 + *
  198 + * @param[in] matrix Matrix.
  199 + * @param[in] ref Reference matrix.
250 200 ***************************************************************************/
251   -int check_matrix_max(const double max)
  201 +bool TestGSparseMatrix::check_matrix_lt(const GSparseMatrix& matrix,
  202 + const GSparseMatrix& ref) const
252 203 {
253   - double value = g_matrix[0];
254   - for (int i = 0; i < g_elements; ++i) {
255   - if (g_matrix[i] > value)
256   - value = g_matrix[i];
257   - }
258   - return (max == value);
  204 + // Initialise check with true
  205 + bool result = true;
  206 +
  207 + // Compare all matrix elements
  208 + for (int row = 0; row < g_rows; ++row) {
  209 + for (int col = 0; col < g_cols; ++col) {
  210 +
  211 + // Set reference value
  212 + double ref_value = 0.0;
  213 + if (col <= row) {
  214 + for (int i = 0; i < g_elements; ++i) {
  215 + if (g_row[i] == row && g_col[i] == col) {
  216 + ref_value = g_matrix[i];
  217 + break;
  218 + }
  219 + }
  220 + }
  221 +
  222 + // Check matrix
  223 + if (std::abs(matrix(row,col)-ref_value) > 1.0e-15) {
  224 + result = false;
  225 + break;
  226 + }
  227 +
  228 + } // endfor: looped over columns
  229 + } // endfor: looped over rows
  230 +
  231 + // Return result
  232 + return result;
259 233 }
260 234  
261 235  
262 236 /***************************************************************************
263   - * Check matrix sum *
  237 + * @brief Check upper triangle general matrix
  238 + *
  239 + * @param[in] matrix Matrix.
  240 + * @param[in] ref Reference matrix.
264 241 ***************************************************************************/
265   -int check_matrix_sum(const double sum)
  242 +bool TestGSparseMatrix::check_matrix_ut(const GSparseMatrix& matrix,
  243 + const GSparseMatrix& ref) const
266 244 {
267   - double value = 0.0;
268   - for (int i = 0; i < g_elements; ++i)
269   - value += g_matrix[i];
270   - return (sum == value);
  245 + // Initialise check with true
  246 + bool result = true;
  247 +
  248 + // Compare all matrix elements
  249 + for (int row = 0; row < g_rows; ++row) {
  250 + for (int col = 0; col < g_cols; ++col) {
  251 +
  252 + // Set reference value
  253 + double ref_value = 0.0;
  254 + if (col >= row) {
  255 + for (int i = 0; i < g_elements; ++i) {
  256 + if (g_row[i] == row && g_col[i] == col) {
  257 + ref_value = g_matrix[i];
  258 + break;
  259 + }
  260 + }
  261 + }
  262 +
  263 + // Check matrix
  264 + if (std::abs(matrix(row,col)-ref_value) > 1.0e-15) {
  265 + result = false;
  266 + break;
  267 + }
  268 +
  269 + } // endfor: looped over columns
  270 + } // endfor: looped over rows
  271 +
  272 + // Return result
  273 + return result;
271 274 }
272 275  
273 276  
274   -/***************************************************************************
275   - * Test: Output *
276   - ***************************************************************************/
277   -void test_output(const GSparseMatrix& m_test)
  277 +/***********************************************************************//**
  278 + * @brief Set parameters and tests
  279 + **************************************************************************/
  280 +void TestGSparseMatrix::set(void)
278 281 {
279   - cout << "Test GSparseMatrix: Output test matrix: " << endl;
280   - try {
281   - cout << m_test << endl;
282   - }
283   - catch (exception &e) {
284   - cout << endl << "TEST ERROR: Unable to output matrix." << endl;
285   - cout << e.what() << endl;
286   - throw;
287   - }
  282 + // Set test name
  283 + name("GSparseMatrix");
  284 +
  285 + // Add tests
  286 + append(static_cast<pfunction>(&TestGSparseMatrix::alloc_matrix), "Test matrix allocation");
  287 + append(static_cast<pfunction>(&TestGSparseMatrix::assign_values), "Test value assignment");
  288 + append(static_cast<pfunction>(&TestGSparseMatrix::copy_matrix), "Test matrix copying");
  289 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_operations), "Test matrix operations");
  290 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_arithmetics), "Test matrix arithmetics");
  291 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_functions), "Test matrix functions");
  292 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_compare), "Test matrix comparisons");
  293 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_cholesky), "Test matrix Cholesky decomposition");
  294 + append(static_cast<pfunction>(&TestGSparseMatrix::matrix_print), "Test matrix printing");
  295 +
  296 + // Set members
  297 + m_test = set_matrix();
  298 + v_test = set_vector();
  299 + m_bigger = GSparseMatrix(g_rows+1, g_cols+1);
  300 +
  301 + // Return
  302 + return;
288 303 }
289 304  
290 305  
291   -/***************************************************************************
292   - * Test: Allocate zero matrix *
  306 +/***********************************************************************//**
  307 + * @brief Test matrix allocation
293 308 ***************************************************************************/
294   -void test_allocate(void)
  309 +void TestGSparseMatrix::alloc_matrix(void)
295 310 {
296   - cout << "Test GSparseMatrix: Allocate zero matrix: ";
297   - try {
298   - GSparseMatrix test(0,0);
299   - }
300   - catch (GException::empty &e) {
301   - cout << ". ok." << endl;
302   - }
303   - catch (exception &e) {
304   - cout << endl << "TEST ERROR: Did not signal zero matrix allocation." << endl;
305   - cout << e.what() << endl;
306   - throw;
307   - }
308   - cout << ". ok." << endl;
  311 + // Allocate zero matrix. The allocation should fail.
  312 + test_try("Allocate zero matrix");
  313 + try {
  314 + GSparseMatrix test(0,0);
  315 + test_try_failure("Expected GException::empty exception.");
  316 + }
  317 + catch (GException::empty &e) {
  318 + test_try_success();
  319 + }
  320 + catch (std::exception &e) {
  321 + test_try_failure(e);
  322 + }
  323 +
  324 + // Setup a symmetric sparse matrix
  325 + int size = 30;
  326 + GSparseMatrix symmetric(size,size);
  327 + for (int i = 0; i < size; i+=2) {
  328 + for (int j = 0; j < size; j+=2) {
  329 + symmetric(i,j) = 1.0+i+j;
  330 + }
  331 + }
  332 +
  333 + // Convert to GMatrix
  334 + test_try("Test symmetric GMatrix conversion");
  335 + try {
  336 + GMatrix cnv_matrix = GMatrix(symmetric);
  337 + GSparseMatrix back_matrix = GSparseMatrix(cnv_matrix);
  338 + test_assert((symmetric == back_matrix),
  339 + "Test symmetric GSparseMatrix <-> GMatrix conversion",
  340 + "Found:\n"+back_matrix.print()+"\nExpected:\n"+symmetric.print());
  341 + test_try_success();
  342 + }
  343 + catch (GException::empty &e) {
  344 + test_try_success();
  345 + }
  346 + catch (std::exception &e) {
  347 + test_try_failure(e);
  348 + }
  349 +
  350 + // Test GMatrix conversion
  351 + test_try("Test GMatrix conversion");
  352 + try {
  353 + GMatrix cnv_matrix = GMatrix(m_test);
  354 + GSparseMatrix back_matrix = GSparseMatrix(cnv_matrix);
  355 + test_assert((m_test == back_matrix),
  356 + "Test GSparseMatrix <-> GMatrix conversion",
  357 + "Found:\n"+back_matrix.print()+"\nExpected:\n"+m_test.print());
  358 + test_try_success();
  359 + }
  360 + catch (std::exception &e) {
  361 + test_try_failure(e);
  362 + }
  363 +
  364 + // Test GSparseMatrix <-> GSymMatrix conversion
  365 + test_try("Test GSymMatrix conversion");
  366 + try {
  367 + GSymMatrix cnv_sym = GSymMatrix(symmetric);
  368 + GSparseMatrix back_sym = GSparseMatrix(cnv_sym);
  369 + test_assert((symmetric == back_sym),
  370 + "Test GSparseMatrix <-> GSymMatrix conversion",
  371 + "Found:\n"+back_sym.print()+"\nExpected:\n"+symmetric.print());
  372 + test_try_success();
  373 + }
  374 + catch (std::exception &e) {
  375 + test_try_failure(e);
  376 + }
  377 +
  378 + // Test invalid GSparseMatrix <-> GSymMatrix conversion
  379 + test_try("Test invalid GSymMatrix conversion");
  380 + try {
  381 + GSymMatrix bad_sym = GSymMatrix(m_test);
  382 + test_try_failure("Expected GException::matrix_not_symmetric exception.");
  383 + }
  384 + catch (GException::matrix_not_symmetric &e) {
  385 + test_try_success();
  386 + }
  387 + catch (std::exception &e) {
  388 + test_try_failure(e);
  389 + }
  390 +
  391 + // Return
  392 + return;
309 393 }
310 394  
311 395  
312   -/***************************************************************************
313   - * Test: Assign values *
  396 +/***********************************************************************//**
  397 + * @brief Test value assignment
314 398 ***************************************************************************/
315   -void test_assign_values(const GSparseMatrix& m_test)
  399 +void TestGSparseMatrix::assign_values(void)
316 400 {
317   - //
318   - cout << "Test GSparseMatrix: Assign matrix values: ";
319   - try {
320   - //
  401 + // Setup 3x3 matrix
321 402 GSparseMatrix test(3,3);
322   - test(1,1) = 1.0;
323   - if (test(0,0) != 0.0 || test(1,0) != 0.0 || test(2,0) != 0.0 ||
324   - test(0,1) != 0.0 || test(1,1) != 1.0 || test(2,1) != 0.0 ||
325   - test(0,2) != 0.0 || test(1,2) != 0.0 || test(2,2) != 0.0) {
326   - cout << endl << "TEST ERROR: Unable to set matrix values." << endl;
327   - cout << test << endl;
328   - throw;
329   - }
330   - cout << ".";
331   - //
332   - GSparseMatrix result = m_test;
333   - result(0,0) = 0.0;
334   - result(0,0) = 1.0;
335   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
336   - cout << endl << "TEST ERROR: Bad M(row,col) assignment." << endl;
337   - cout << "result:" << endl << result << endl;
338   - cout << "m_test:" << endl << m_test << endl;
339   - throw;
340   - }
341   - cout << ".";
342   - //
343   - result = m_test;
344   - result(0,0) = 0.0;
345   - result(0,4) = 0.0;
346   - result(0,0) = 1.0;
347   - result(0,4) = 0.0;
348   - result(0,4) = 7.0;
349   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
350   - cout << endl << "TEST ERROR: Bad M(row,col) assignment." << endl;
351   - cout << "result:" << endl << result << endl;
352   - cout << "m_test:" << endl << m_test << endl;
353   - throw;
354   - }
355   - cout << ".";
356   - //
357   - result = m_test;
358   - result(0,1) = 2.0;
359   - result(0,2) = 2.0;
360   - result(0,3) = 2.0;
361   - result(0,1) = 0.0;
362   - result(0,2) = 0.0;
363   - result(0,3) = 0.0;
364   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
365   - cout << endl << "TEST ERROR: Bad M(row,col) assignment." << endl;
366   - cout << "result:" << endl << result << endl;
367   - cout << "m_test:" << endl << m_test << endl;
368   - throw;
369   - }
370   - cout << ".";
371   - //
372   - result.clear();
373   - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
374   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.clear()." << endl;
375   - cout << "result:" << endl << result << endl;
376   - cout << "m_test:" << endl << m_test << endl;
377   - throw;
378   - }
379   - cout << ".";
380   - }
381   - catch (exception &e) {
382   - cout << e.what() << endl;
383   - throw;
384   - }
385   - #if defined(G_RANGE_CHECK)
  403 +
  404 + // Assignment individual values
  405 + for (int i = 0; i < 3; ++i) {
  406 + for (int k = 0; k < 3; ++k) {
  407 + double value = i*2.0 + k*2.0;
  408 + test(i,k) = value;
  409 + }
  410 + }
  411 +
  412 + // Check assignment of individual values
  413 + for (int i = 0; i < 3; ++i) {
  414 + for (int k = 0; k < 3; ++k) {
  415 + double value = i*2.0 + k*2.0;
  416 + test_value(test(i,k), value, 1.0e-10, "Test matrix element assignment");
  417 + }
  418 + }
  419 +
  420 + // Verify range checking
  421 + #ifdef G_RANGE_CHECK
  422 + test_try("Verify range checking");
386 423 try {
387   - GSparseMatrix test(3,3);
388 424 test(3,3) = 1.0;
  425 + test_try_failure("Expected GException::out_of_range exception.");
389 426 }
390 427 catch (GException::out_of_range &e) {
  428 + test_try_success();
391 429 }
392   - catch (exception &e) {
393   - cout << e.what() << endl;
394   - throw;
  430 + catch (std::exception &e) {
  431 + test_try_failure(e);
395 432 }
396   - cout << ".";
397 433 #endif
398   - //
399   - // Insert column into 10 x 10 matrix using matrix stack and the
400   - // compressed vector format
401   - try {
402   - //
403   - // Set-up sparse matrix for adding
  434 +
  435 + // Setup 10x10 matrix and keep for reference
404 436 GSparseMatrix sparse(10,10);
405   - for (int i = 3; i < 5; ++i)
406   - sparse(i,i) = 5.0;
  437 + for (int i = 3; i < 5; ++i) {
  438 + sparse(i,i) = 5.0;
  439 + }
  440 + GSparseMatrix initial = sparse;
407 441 GSparseMatrix reference = sparse;
408   - //
409   - // Initialise vector for column adding
410   - GVector column(10);
411   - //
412   - // Initialise matrix stack
  442 +
  443 + // Insert column into 10 x 10 matrix using large matrix stack and the
  444 + // add_col(GVector) method
413 445 sparse.stack_init(100,50);
414   - //
415   - // Fill matrix using add_col
  446 + GVector column(10);
416 447 for (int j = 0; j < 10; ++j) {
417   - //
418   - // Set column index
419   - int col = int(0.8 * j + 0.5); // This allows that some columns are twice
420   - if (col > 9) col -= 10; // This avoids overflow
421   - //
422   - // Set-up vector
423   - int i_min = (j < 2) ? 0 : j-2;
424   - int i_max = (j > 8) ? 10 : j+2;
425   - column = 0.0;
426   - for (int i = i_min; i < i_max; ++i) {
427   - column[i] = (i+1)*1;
428   - reference(i,col) += column[i];
429   - }
430   - //
431   - // Add vector
432   - sparse.add_col(column, col);
  448 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  449 + if (col > 9) col -= 10; // This avoids overflow
  450 + int i_min = (j < 2) ? 0 : j-2;
  451 + int i_max = (j > 8) ? 10 : j+2;
  452 + column = 0.0;
  453 + for (int i = i_min; i < i_max; ++i) {
  454 + column[i] = (i+1)*1;
  455 + reference(i,col) += column[i];
  456 + }
  457 + sparse.add_col(column, col);
433 458 }
434   - //
435   - // Destroy stack
436 459 sparse.stack_destroy();
437   - if (sparse != reference) {
438   - cout << endl << "TEST ERROR: Corrupt add_col function (vector version)." << endl;
439   - cout << "Sparse " << sparse << endl;
440   - cout << "Reference " << reference << endl;
441   - throw;
  460 + test_assert((sparse == reference),
  461 + "Test stack fill with large stack using add_col(GVector) method",
  462 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  463 +
  464 + // Insert column into 10 x 10 matrix using small matrix stack and the
  465 + // add_col(GVector) method
  466 + sparse = initial;
  467 + sparse.stack_init(100,3);
  468 + for (int j = 0; j < 10; ++j) {
  469 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  470 + if (col > 9) col -= 10; // This avoids overflow
  471 + int i_min = (j < 2) ? 0 : j-2;
  472 + int i_max = (j > 8) ? 10 : j+2;
  473 + column = 0.0;
  474 + for (int i = i_min; i < i_max; ++i) {
  475 + column[i] = (i+1)*1;
  476 + }
  477 + sparse.add_col(column, col);
442 478 }
443   - }
444   - catch (exception &e) {
445   - cout << e.what() << endl;
446   - throw;
447   - }
448   - //
449   - // Insert column into 10 x 10 matrix using matrix stack and the
450   - // compressed vector format
451   - try {
452   - //
453   - // Set-up sparse matrix for adding
454   - GSparseMatrix sparse(10,10);
455   - sparse.clear();
456   - for (int i = 3; i < 5; ++i)
457   - sparse(i,i) = 5.0;
458   - GSparseMatrix reference = sparse;
459   - //
460   - // Set-up workspace for column adding
461   - double* wrk_data = new double[10];
462   - int* wrk_row = new int[10];
463   - //
464   - // Initialise matrix stack
465   - sparse.stack_init(100,50);
466   - //
467   - // Fill matrix using add_col
  479 + sparse.stack_destroy();
  480 + test_assert((sparse == reference),
  481 + "Test stack fill with small stack using add_col(GVector) method",
  482 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  483 +
  484 + // Insert column into 10 x 10 matrix using tiny matrix stack and the
  485 + // add_col(GVector) method
  486 + sparse = initial;
  487 + sparse.stack_init(8,3);
468 488 for (int j = 0; j < 10; ++j) {
469   - //
470   - // Set column index
471   - int col = int(0.8 * j + 0.5); // This allows that some columns are twice
472   - if (col > 9) col -= 10; // This avoids overflow
473   - //
474   - // Set-up vector
475   - int inx = 0;
476   - int i_min = (j < 2) ? 0 : j-2;
477   - int i_max = (j > 8) ? 10 : j+2;
478   - for (int i = i_min; i < i_max; ++i) {
479   - wrk_data[inx] = (i+1)*1;
480   - wrk_row[inx] = i;
481   - reference(i,col) += wrk_data[inx];
482   - inx++;
483   - }
484   - //
485   - // Add vector
486   - sparse.add_col(wrk_data, wrk_row, inx, col);
  489 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  490 + if (col > 9) col -= 10; // This avoids overflow
  491 + int i_min = (j < 2) ? 0 : j-2;
  492 + int i_max = (j > 8) ? 10 : j+2;
  493 + column = 0.0;
  494 + for (int i = i_min; i < i_max; ++i) {
  495 + column[i] = (i+1)*1;
  496 + }
  497 + sparse.add_col(column, col);
487 498 }
488   - //
489   - // Destroy stack
490 499 sparse.stack_destroy();
491   - if (sparse != reference) {
492   - cout << endl << "TEST ERROR: Corrupt add_col function (compressed array version)." << endl;
493   - cout << "Sparse " << sparse << endl;
494   - cout << "Reference " << reference << endl;
495   - throw;
  500 + test_assert((sparse == reference),
  501 + "Test stack fill with tiny stack using add_col(GVector) method",
  502 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  503 +
  504 + // Insert column into 10 x 10 matrix using no matrix stack and the
  505 + // add_col(GVector) method
  506 + sparse = initial;
  507 + for (int j = 0; j < 10; ++j) {
  508 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  509 + if (col > 9) col -= 10; // This avoids overflow
  510 + int i_min = (j < 2) ? 0 : j-2;
  511 + int i_max = (j > 8) ? 10 : j+2;
  512 + column = 0.0;
  513 + for (int i = i_min; i < i_max; ++i) {
  514 + column[i] = (i+1)*1;
  515 + }
  516 + sparse.add_col(column, col);
496 517 }
497   - //
  518 + sparse.stack_destroy();
  519 + test_assert((sparse == reference),
  520 + "Test fill using add_col(GVector) method",
  521 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  522 +
  523 + // Set-up workspace for compressed column adding
  524 + double* wrk_data = new double[10];
  525 + int* wrk_row = new int[10];
  526 +
  527 + // Compressed tests
  528 + test_try("Verify compressed column add_col() method");
  529 + try {
  530 +
  531 + // Insert column into 10 x 10 matrix using large matrix stack and the
  532 + // compressed column add_col() method
  533 + sparse = initial;
  534 + reference = initial;
  535 + sparse.stack_init(100,50);
  536 + for (int j = 0; j < 10; ++j) {
  537 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  538 + if (col > 9) col -= 10; // This avoids overflow
  539 + int inx = 0;
  540 + int i_min = (j < 3) ? 0 : j-3;
  541 + int i_max = (j > 8) ? 10 : j+2;
  542 + for (int i = i_min; i < i_max; ++i) {
  543 + wrk_data[inx] = (i+1)*3.7;
  544 + wrk_row[inx] = i;
  545 + reference(i,col) += wrk_data[inx];
  546 + inx++;
  547 + }
  548 + sparse.add_col(wrk_data, wrk_row, inx, col);
  549 + }
  550 + sparse.stack_destroy();
  551 + test_assert((sparse == reference),
  552 + "Test stack fill with large stack using compressed add_col() method",
  553 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  554 +
  555 + // Insert column into 10 x 10 matrix using small matrix stack and the
  556 + // compressed column add_col() method
  557 + sparse = initial;
  558 + sparse.stack_init(100,2);
  559 + for (int j = 0; j < 10; ++j) {
  560 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  561 + if (col > 9) col -= 10; // This avoids overflow
  562 + int inx = 0;
  563 + int i_min = (j < 3) ? 0 : j-3;
  564 + int i_max = (j > 8) ? 10 : j+2;
  565 + for (int i = i_min; i < i_max; ++i) {
  566 + wrk_data[inx] = (i+1)*3.7;
  567 + wrk_row[inx] = i;
  568 + inx++;
  569 + }
  570 + sparse.add_col(wrk_data, wrk_row, inx, col);
  571 + }
  572 + sparse.stack_destroy();
  573 + test_assert((sparse == reference),
  574 + "Test stack fill with small stack using compressed add_col() method",
  575 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  576 +
  577 + // Insert column into 10 x 10 matrix using tiny matrix stack and the
  578 + // compressed column add_col() method
  579 + sparse = initial;
  580 + sparse.stack_init(3,2);
  581 + for (int j = 0; j < 10; ++j) {
  582 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  583 + if (col > 9) col -= 10; // This avoids overflow
  584 + int inx = 0;
  585 + int i_min = (j < 3) ? 0 : j-3;
  586 + int i_max = (j > 8) ? 10 : j+2;
  587 + for (int i = i_min; i < i_max; ++i) {
  588 + wrk_data[inx] = (i+1)*3.7;
  589 + wrk_row[inx] = i;
  590 + inx++;
  591 + }
  592 + sparse.add_col(wrk_data, wrk_row, inx, col);
  593 + }
  594 + sparse.stack_destroy();
  595 + test_assert((sparse == reference),
  596 + "Test stack fill with tiny stack using compressed add_col() method",
  597 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  598 +
  599 + // Insert column into 10 x 10 matrix using no matrix stack and the
  600 + // compressed column add_col() method
  601 + sparse = initial;
  602 + for (int j = 0; j < 10; ++j) {
  603 + int col = int(0.8 * j + 0.5); // This allows that some columns are twice
  604 + if (col > 9) col -= 10; // This avoids overflow
  605 + int inx = 0;
  606 + int i_min = (j < 3) ? 0 : j-3;
  607 + int i_max = (j > 8) ? 10 : j+2;
  608 + for (int i = i_min; i < i_max; ++i) {
  609 + wrk_data[inx] = (i+1)*3.7;
  610 + wrk_row[inx] = i;
  611 + inx++;
  612 + }
  613 + sparse.add_col(wrk_data, wrk_row, inx, col);
  614 + }
  615 + sparse.stack_destroy();
  616 + test_assert((sparse == reference),
  617 + "Test fill using compressed add_col() method",
  618 + "Found:\n"+sparse.print()+"\nExpected:\n"+reference.print());
  619 +
  620 + // Signal success
  621 + test_try_success();
  622 + }
  623 + catch (std::exception &e) {
  624 + test_try_failure(e);
  625 + }
  626 +
498 627 // Free workspace
499 628 delete [] wrk_data;
500 629 delete [] wrk_row;
501   - }
502   - catch (exception &e) {
503   - cout << e.what() << endl;
504   - throw;
505   - }
506   - cout << " ok." << endl;
  630 +
  631 + // Return
  632 + return;
507 633 }
508 634  
509 635  
510   -/***************************************************************************
511   - * Test: Matrix copy constructor *
  636 +/***********************************************************************//**
  637 + * @brief Test matrix copy
512 638 ***************************************************************************/
513   -void test_copy_constructor(const GSparseMatrix& m_test)
  639 +void TestGSparseMatrix::copy_matrix(void)
514 640 {
515   - cout << "Test GSparseMatrix: Define matrix using copy constructor: ";
516   - try {
517   - //
  641 + // Copy matrix
518 642 GSparseMatrix test = m_test;
519   - if (!check_matrix(test, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
520   - cout << endl << "TEST ERROR: Corrupt copy constructor." << endl;
521   - cout << test << endl;
522   - throw;
523   - }
524   - }
525   - catch (exception &e) {
526   - cout << e.what() << endl;
527   - throw;
528   - }
529   - cout << ". ok." << endl;
  643 +
  644 + // Test if original and compied matrices are correct
  645 + test_assert(check_matrix(m_test), "Test source matrix");
  646 + test_assert(check_matrix(test), "Test matrix copy operator",
  647 + "Found:\n"+test.print()+"\nExpected:\n"+m_test.print());
  648 +
  649 + // Return
  650 + return;
530 651 }
531 652  
532 653  
533   -/***************************************************************************
534   - * Test: Matrix assignment *
  654 +/***********************************************************************//**
  655 + * @brief Test matrix operations
  656 + *
  657 + * Tests matrix*vector and matrix*matrix multiplication operations.
535 658 ***************************************************************************/
536   -void test_assign_matrix(const GSparseMatrix& m_test)
  659 +void TestGSparseMatrix::matrix_operations(void)
537 660 {
538   - cout << "Test GSparseMatrix: Matrix assignment: ";
539   - try {
540   - //
541   - // GSparseMatrix = GSparseMatrix
542   - GSparseMatrix result(1,1);
543   - result = m_test;
544   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
545   - cout << endl << "TEST ERROR: Corrupt assignment." << endl;
546   - cout << result << endl;
547   - throw;
548   - }
549   - cout << ".";
550   - //
551   - // GSparseMatrix = GSparseMatrix (bigger matrix)
552   - GSparseMatrix bigger(1000,1000);
553   - for (int i = 0; i < 1000; ++i)
554   - bigger(i,i) = (i+1)*1.1;
555   - result = bigger;
556   - cout << ".";
557   - }
558   - catch (exception &e) {
559   - cout << e.what() << endl;
560   - throw;
561   - }
562   - cout << " ok." << endl;
563   -}
  661 + // Perform vector multiplication
  662 + GVector test1 = m_test * v_test;
564 663  
  664 + // Check result
  665 + GVector ref1(g_rows);
  666 + for (int i = 0; i < g_elements; ++i) {
  667 + ref1[g_row[i]] += g_matrix[i] * v_test[g_col[i]];
  668 + }
  669 + bool result = true;
  670 + for (int i = 0; i < g_rows; ++i) {
  671 + if (ref1[i] != test1[i]) {
  672 + result = false;
  673 + break;
  674 + }
  675 + }
565 676  
566   -/***************************************************************************
567   - * Test: Matrix transpose *
568   - ***************************************************************************/
569   -void test_transpose(const GSparseMatrix& m_test)
570   -{
571   - cout << "Test GSparseMatrix: Matrix transpose: ";
572   - try {
573   - //
574   - // transpose(GSparseMatrix)
575   - GSparseMatrix result(1,1);
576   - result = transpose(m_test);
577   - if (!check_transpose_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
578   - cout << endl << "TEST ERROR: Corrupt transpose(GSparseMatrix) function." << endl;
579   - cout << result << endl;
580   - throw;
581   - }
582   - cout << ".";
583   - //
584   - // GSparseMatrix.transpose()
585   - result = m_test;
586   - result.transpose();
587   - if (!check_transpose_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
588   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.transpose() function." << endl;
589   - cout << result << endl;
590   - throw;
591   - }
592   - cout << ".";
593   - }
594   - catch (exception &e) {
595   - cout << e.what() << endl;
596   - throw;
597   - }
598   - cout << " ok." << endl;
599   -}
  677 + // Test if original matrix and result vector are correct
  678 + test_assert(check_matrix(m_test), "Test source matrix");
  679 + test_assert(result, "Test matrix*vector multiplication",
  680 + "Found:\n"+test1.print()+"\nExpected:\n"+ref1.print());
600 681  
  682 + // Test incompatible vector multiplication
  683 + test_try("Test incompatible matrix*vector multiplication");
  684 + try {
  685 + GVector test2 = m_bigger * v_test;
  686 + test_try_failure("Expected GException::matrix_vector_mismatch exception.");
  687 + }
  688 + catch (GException::matrix_vector_mismatch &e) {
  689 + test_try_success();
  690 + }
  691 + catch (std::exception &e) {
  692 + test_try_failure(e);
  693 + }
  694 +
  695 + // Test matrix multiplication
  696 + GSparseMatrix test3 = m_test * transpose(m_test);
601 697  
602   -/***************************************************************************
603   - * Test: Matrix*Vector multiplication *
604   - ***************************************************************************/
605   -void test_matrix_vector(const GSparseMatrix& m_test, const GVector& v_test)
606   -{
607   - cout << "Test GSparseMatrix: Matrix*Vector multiplication: ";
608   - try {
609   - //
610   - GVector test = m_test*v_test;
611   - if (!check_matrix_vector(test) || !check_matrix(m_test, 1.0, 0.0)) {
612   - cout << endl << "TEST ERROR: Corrupt Matrix*Vector multiplication." << endl;
613   - cout << test << endl;
614   - throw;
615   - }
616   - }
617   - catch (exception &e) {
618   - cout << e.what() << endl;
619   - throw;
620   - }
621   - cout << ".";
622   - try {
623   - GSparseMatrix bigger(1000,1000);
624   - for (int i = 0; i < 1000; ++i)
625   - bigger(i,i) = (i+1)*1.1;
626   - GVector test = bigger*v_test;
627   - }
628   - catch (GException::matrix_vector_mismatch &e) {
629   - }
630   - catch (exception &e) {
631   - cout << e.what() << endl;
632   - throw;
633   - }
634   - cout << ". ok." << endl;
635   -}
  698 + // Check if the result matrix is as expected
  699 + GSparseMatrix ref3(g_rows, g_rows);
  700 + for (int row = 0; row < g_rows; ++row) {
  701 + for (int col = 0; col < g_rows; ++col) {
  702 + double value = 0.0;
  703 + for (int i = 0; i < g_cols; ++i) {
  704 + double ref_value_1 = 0.0;
  705 + double ref_value_2 = 0.0;
  706 + for (int k = 0; k < g_elements; ++k) {
  707 + if (g_row[k] == row && g_col[k] == i) {
  708 + ref_value_1 = g_matrix[k];
  709 + break;
  710 + }
  711 + }
  712 + for (int k = 0; k < g_elements; ++k) {
  713 + if (g_row[k] == col && g_col[k] == i) {
  714 + ref_value_2 = g_matrix[k];
  715 + break;
  716 + }
  717 + }
  718 + value += ref_value_1 * ref_value_2;
  719 + }
  720 + ref3(row,col) = value;
  721 + if (test3(row,col) != value) {
  722 + result = false;
  723 + break;
  724 + }
  725 + }
  726 + }
636 727  
  728 + // Test if original matrix and result matrix are correct
  729 + test_assert(check_matrix(m_test), "Test source matrix");
  730 + test_assert(result, "Test matrix multiplication",
  731 + "Found:\n"+test3.print()+"\nExpected:\n"+ref3.print());
  732 + test_value(test3.rows(), g_rows, "Test number of rows of result matrix");
  733 + test_value(test3.cols(), g_rows, "Test number of columns of result matrix");
637 734  
638   -/***************************************************************************
639   - * Test: Matrix*Vector multiplication *
640   - ***************************************************************************/
641   -void test_matrix_matrix(const GSparseMatrix& m_test)
642   -{
643   - cout << "Test GSparseMatrix: Matrix*Matrix multiplication: ";
644   - try {
645   - //
646   - GSparseMatrix test = m_test * transpose(m_test);
647   - if (!check_matrix_matrix(test) || !check_matrix(m_test, 1.0, 0.0)) {
648   - cout << endl << "TEST ERROR: Corrupt Matrix*Matrix multiplication." << endl;
649   - cout << "test:" << endl << test << endl;
650   - cout << "m_test:" << endl << m_test << endl;
651   - throw;
652   - }
653   - cout << ".";
654   - //
655   - GSparseMatrix bigger(1000,1000);
656   - for (int i = 0; i < 1000; ++i)
657   - bigger(i,i) = (i+1)*1.1;
  735 + // Test incompatible matrix multiplication
  736 + test_try("Test incompatible matrix multiplication");
658 737 try {
659   - GSparseMatrix test = m_test * bigger;
  738 + GSparseMatrix test4 = m_bigger * m_test;
  739 + test_try_failure("Expected GException::matrix_mismatch exception.");
660 740 }
661 741 catch (GException::matrix_mismatch &e) {
662   - cout << ".";
  742 + test_try_success();
663 743 }
664   - catch (exception &e) {
665   - cout << e.what() << endl;
666   - throw;
  744 + catch (std::exception &e) {
  745 + test_try_failure(e);
667 746 }
668   - //
  747 +
  748 + // Test another incompatible matrix multiplication
  749 + test_try("Test incompatible matrix multiplication");
669 750 try {
670   - GSparseMatrix test7 = bigger * m_test;
  751 + GSparseMatrix test5 = m_bigger * m_test;
  752 + test_try_failure("Expected GException::matrix_mismatch exception.");
671 753 }
672 754 catch (GException::matrix_mismatch &e) {
673   - cout << ".";
  755 + test_try_success();
674 756 }
675   - catch (exception &e) {
676   - cout << e.what() << endl;
677   - throw;
  757 + catch (std::exception &e) {
  758 + test_try_failure(e);
678 759 }
679   - }
680   - catch (exception &e) {
681   - cout << e.what() << endl;
682   - throw;
683   - }
684   - cout << " ok." << endl;
  760 +
  761 + // Return
  762 + return;
685 763 }
686 764  
687 765  
688   -/***************************************************************************
689   - * Test: Arithmetics *
  766 +/***********************************************************************//**
  767 + * @brief Test matrix arithmetics
  768 + *
  769 + * Tests matrix arithmetics.
690 770 ***************************************************************************/
691   -void test_arithmetics(const GSparseMatrix& m_test)
  771 +void TestGSparseMatrix::matrix_arithmetics(void)
692 772 {
693   - cout << "Test GSparseMatrix: Arithmetics: ";
694   - try {
695   - //
696 773 // -GSparseMatrix
697   - GSparseMatrix result(1,1);
698   - result = -m_test;
699   - if (!check_matrix(result, -1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
700   - cout << endl << "TEST ERROR: Corrupt -GSparseMatrix operator." << endl;
701   - cout << "result " << result << endl;
702   - cout << "m_test " << m_test << endl;
703   - throw;
704   - }
705   - cout << ".";
706   - //
707   - // abs(GSparseMatrix)
708   - result = abs(m_test);
709   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
710   - cout << endl << "TEST ERROR: Corrupt abs(GSparseMatrix) function." << endl;
711   - cout << "result " << result << endl;
712   - cout << "m_test " << m_test << endl;
713   - throw;
714   - }
715   - cout << ".";
716   - //
  774 + GSparseMatrix test = -m_test;
  775 + test_assert(check_matrix(m_test), "Test source matrix");
  776 + test_assert(check_matrix(test, -1.0, 0.0), "Test -GSparseMatrix",
  777 + "Unexpected result matrix:\n"+test.print());
  778 +
717 779 // GSparseMatrix += GSparseMatrix
718   - result = m_test;
719   - result += m_test;
720   - if (!check_matrix(result, 2.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
721   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix += GSparseMatrix operator." << endl;
722   - cout << "result " << result << endl;
723   - cout << "m_test " << m_test << endl;
724   - throw;
725   - }
726   - cout << ".";
727   - //
  780 + test = m_test;
  781 + test += m_test;
  782 + test_assert(check_matrix(m_test), "Test source matrix");
  783 + test_assert(check_matrix(test, 2.0, 0.0), "Test GSparseMatrix += GSparseMatrix",
  784 + "Unexpected result matrix:\n"+test.print());
  785 +
728 786 // GSparseMatrix -= GSparseMatrix
729   - result = m_test;
730   - result -= m_test;
731   - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
732   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix -= GSparseMatrix operator." << endl;
733   - cout << "result " << result << endl;
734   - cout << "m_test " << m_test << endl;
735   - throw;
736   - }
737   - cout << ".";
738   - //
  787 + test = m_test;
  788 + test -= m_test;
  789 + test_assert(check_matrix(m_test), "Test source matrix");
  790 + test_assert(check_matrix(test, 0.0, 0.0), "Test GSparseMatrix -= GSparseMatrix",
  791 + "Unexpected result matrix:\n"+test.print());
  792 +
739 793 // GSparseMatrix *= 3.0
740   - result = m_test;
741   - result *= 3.0;
742   - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
743   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix *= double operator." << endl;
744   - cout << "result " << result << endl;
745   - cout << "m_test " << m_test << endl;
746   - throw;
747   - }
748   - cout << ".";
749   - //
  794 + test = m_test;
  795 + test *= 3.0;
  796 + test_assert(check_matrix(m_test), "Test source matrix");
  797 + test_assert(check_matrix(test, 3.0, 0.0), "Test GSparseMatrix *= 3.0",
  798 + "Unexpected result matrix:\n"+test.print());
  799 +
750 800 // GSparseMatrix /= 3.0
751   - result = m_test;
752   - result /= 3.0;
753   - if (!check_matrix(result, 1.0/3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
754   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix /= double operator." << endl;
755   - cout << "result " << result << endl;
756   - cout << "m_test " << m_test << endl;
757   - throw;
758   - }
759   - cout << ".";
760   - //
  801 + test = m_test;
  802 + test /= 3.0;
  803 + test_assert(check_matrix(m_test), "Test source matrix");
  804 + test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSparseMatrix /= 3.0",
  805 + "Unexpected result matrix:\n"+test.print());
  806 +
761 807 // GSparseMatrix + GSparseMatrix
762   - result = m_test + m_test;
763   - if (!check_matrix(result, 2.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
764   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix + GSparseMatrix operator." << endl;
765   - cout << "result " << result << endl;
766   - cout << "m_test " << m_test << endl;
767   - throw;
768   - }
769   - cout << ".";
770   - //
771   - // GSparseMatrix - GSparseMatrix
772   - result = m_test - m_test;
773   - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
774   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix - GSparseMatrix operator." << endl;
775   - cout << "result " << result << endl;
776   - cout << "m_test " << m_test << endl;
777   - throw;
778   - }
779   - cout << ".";
780   - //
  808 + test = m_test + m_test;
  809 + test_assert(check_matrix(m_test), "Test source matrix");
  810 + test_assert(check_matrix(test, 2.0, 0.0), "Test GSparseMatrix + GSparseMatrix",
  811 + "Unexpected result matrix:\n"+test.print());
  812 +
781 813 // GSparseMatrix - GSparseMatrix
782   - result = m_test - m_test;
783   - if (!check_matrix(result, 0.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
784   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix - GSparseMatrix operator." << endl;
785   - cout << "result " << result << endl;
786   - cout << "m_test " << m_test << endl;
787   - throw;
788   - }
789   - cout << ".";
790   - //
  814 + test = m_test - m_test;
  815 + test_assert(check_matrix(m_test), "Test source matrix");
  816 + test_assert(check_matrix(test, 0.0, 0.0), "Test GSparseMatrix - GSparseMatrix",
  817 + "Unexpected result matrix:\n"+test.print());
  818 +
791 819 // GSparseMatrix * 3.0
792   - result = m_test * 3.0;
793   - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
794   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix * double operator." << endl;
795   - cout << "result " << result << endl;
796   - cout << "m_test " << m_test << endl;
797   - throw;
798   - }
799   - cout << ".";
800   - //
801   - // GSparseMatrix * -7.12
802   - result = m_test * -7.12;
803   - if (!check_matrix(result, -7.12, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
804   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix * double operator." << endl;
805   - cout << "result " << result << endl;
806   - cout << "m_test " << m_test << endl;
807   - throw;
808   - }
809   - cout << ".";
810   - //
  820 + test = m_test * 3.0;
  821 + test_assert(check_matrix(m_test), "Test source matrix");
  822 + test_assert(check_matrix(test, 3.0, 0.0), "Test GSparseMatrix * 3.0",
  823 + "Unexpected result matrix:\n"+test.print());
  824 +
811 825 // 3.0 * GSparseMatrix
812   - result = 3.0 * m_test;
813   - if (!check_matrix(result, 3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
814   - cout << endl << "TEST ERROR: Corrupt double * GSparseMatrix operator." << endl;
815   - cout << "result " << result << endl;
816   - cout << "m_test " << m_test << endl;
817   - throw;
818   - }
819   - cout << ".";
820   - //
  826 + test = 3.0 * m_test;
  827 + test_assert(check_matrix(m_test), "Test source matrix");
  828 + test_assert(check_matrix(test, 3.0, 0.0), "Test 3.0 * GSparseMatrix",
  829 + "Unexpected result matrix:\n"+test.print());
  830 +
821 831 // GSparseMatrix / 3.0
822   - result = m_test / 3.0;
823   - if (!check_matrix(result, 1.0/3.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
824   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix / double operator." << endl;
825   - cout << "result " << result << endl;
826   - cout << "m_test " << m_test << endl;
827   - throw;
828   - }
829   - cout << ".";
830   - //
831   - // GSparseMatrix / 0.0
832   - double zero = 0.0;
833   - result = m_test / zero;
834   - if (!check_matrix(result, 1.0/zero, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
835   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix / 0.0." << endl;
836   - cout << "result " << result << endl;
837   - cout << "m_test " << m_test << endl;
838   - throw;
839   - cout << ".";
840   - }
841   - //
842   - // GSparseMatrix.add_col()
843   - result = m_test;
844   - GVector v_add(g_rows);
845   - for (int i = 0; i < g_rows; ++i)
846   - v_add[i] = 7.0;
847   - for (int col = 0; col < g_cols; ++col)
848   - result.add_col(v_add, col);
849   - if (!check_matrix(result, 1.0, 7.0) || !check_matrix(m_test, 1.0, 0.0)) {
850   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.add_col(+v)." << endl;
851   - cout << "result " << result << endl;
852   - cout << "m_test " << m_test << endl;
853   - throw;
854   - }
855   - cout << ".";
856   - //
857   - // GSparseMatrix.add_col()
858   - for (int col = 0; col < g_cols; ++col)
859   - result.add_col(-v_add, col);
860   - if (!check_matrix(result, 1.0, 0.0) || !check_matrix(m_test, 1.0, 0.0)) {
861   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.add_col(-v)." << endl;
862   - cout << "result " << result << endl;
863   - cout << "m_test " << m_test << endl;
864   - throw;
865   - }
866   - cout << ".";
867   - //
868   - // GSparseMatrix.add_col() using a compressed array
869   - GSparseMatrix compare = m_test;
870   - GVector v_sparse(g_rows);
871   - for (int i = 0; i < g_rows; i += 2) // Build vector for comparison
872   - v_sparse[i] = 7.0;
873   - for (int col = 0; col < g_cols; ++col)
874   - compare.add_col(v_sparse, col);
875   - result = m_test;
876   - double* values = new double[g_rows];
877   - int* rows = new int[g_rows];
878   - int number = 0;
879   - for (int i = 0; i < g_rows; i += 2, ++number) {
880   - values[number] = 7.0;
881   - rows[number] = i;
882   - }
883   - for (int col = 0; col < g_cols; ++col)
884   - result.add_col(values, rows, number, col);
885   - delete [] values;
886   - delete [] rows;
887   - if (result != compare) {
888   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.add_col(compressed array)." << endl;
889   - cout << "m_test " << m_test << endl;
890   - for (int i = 0; i < g_rows; ++i) {
891   - for (int j = 0; j < g_cols; ++j) {
892   - std::cout << " " << m_test(i,j);
893   - }
894   - std::cout << std::endl;
895   - }
896   - cout << "result " << result << endl;
897   - for (int i = 0; i < g_rows; ++i) {
898   - for (int j = 0; j < g_cols; ++j) {
899   - std::cout << " " << result(i,j);
900   - }
901   - std::cout << std::endl;
902   - }
903   - cout << "compare " << compare << endl;
904   - for (int i = 0; i < g_rows; ++i) {
905   - for (int j = 0; j < g_cols; ++j) {
906   - std::cout << " " << compare(i,j);
907   - }
908   - std::cout << std::endl;
909   - }
910   - throw;
911   - }
912   - cout << ".";
913   - }
914   - catch (exception &e) {
915   - cout << e.what() << endl;
916   - throw;
917   - }
918   - try {
919   - GSparseMatrix bigger(1000,1000);
920   - GSparseMatrix result(1,1);
921   - for (int i = 0; i < 1000; ++i)
922   - bigger(i,i) = (i+1)*1.1;
923   - result = m_test;
924   - result += bigger;
925   - }
926   - catch (GException::matrix_mismatch &e) {
927   - cout << ".";
928   - }
929   - catch (exception &e) {
930   - cout << e.what() << endl;
931   - throw;
932   - }
933   - cout << " ok." << endl;
934   -}
  832 + test = m_test / 3.0;
  833 + test_assert(check_matrix(m_test), "Test source matrix");
  834 + test_assert(check_matrix(test, 1.0/3.0, 0.0), "Test GSparseMatrix / 3.0",
  835 + "Unexpected result matrix:\n"+test.print());
935 836  
  837 + // Test invalid matrix addition
  838 + test_try("Test invalid matrix addition");
  839 + try {
  840 + test = m_test;
  841 + test += m_bigger;
  842 + test_try_failure("Expected GException::matrix_mismatch exception.");
  843 + }
  844 + catch (GException::matrix_mismatch &e) {
  845 + test_try_success();
  846 + }
  847 + catch (std::exception &e) {
  848 + test_try_failure(e);
  849 + }
936 850  
937   -/***************************************************************************
938   - * Test: Matrix functions *
939   - ***************************************************************************/
940   -void test_functions(const GSparseMatrix& m_test)
941   -{
942   - cout << "Test GSparseMatrix: Matrix functions: ";
943   - try {
944   - //
945   - double min = m_test.min();
946   - if (!check_matrix_min(min)) {
947   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.min() function." << endl;
948   - cout << "min:" << min << endl;
949   - throw;
950   - }
951   - cout << ".";
952   - //
953   - double max = m_test.max();
954   - if (!check_matrix_max(max)) {
955   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.max() function." << endl;
956   - cout << "max:" << max << endl;
957   - throw;
958   - }
959   - cout << ".";
960   - //
961   - double sum = m_test.sum();
962   - if (!check_matrix_sum(sum)) {
963   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.sum() function." << endl;
964   - cout << "sum:" << sum << endl;
965   - throw;
966   - }
967   - cout << ".";
968   - }
969   - catch (exception &e) {
970   - cout << e.what() << endl;
971   - }
972   - cout << " ok." << endl;
  851 + // Return
  852 + return;
973 853 }
974 854  
975 855  
976   -/***************************************************************************
977   - * Test: Matrix comparison *
  856 +/***********************************************************************//**
  857 + * @brief Test matrix functions
  858 + *
  859 + * Tests matrix functions.
978 860 ***************************************************************************/
979   -void test_comparison(const GSparseMatrix& m_test)
  861 +void TestGSparseMatrix::matrix_functions(void)
980 862 {
981   - cout << "Test GSparseMatrix: Comparison: ";
982   - try {
983   - GSparseMatrix bigger(1000,1000);
984   - for (int i = 0; i < 1000; ++i)
985   - bigger(i,i) = (i+1)*1.1;
986   - //
987   - if ((m_test == m_test) != 1) {
988   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix == GSparseMatrix operator." << endl;
989   - throw;
990   - }
991   - cout << ".";
992   - //
993   - GSparseMatrix test(g_rows,g_cols);
994   - if ((m_test == test) != 0) {
995   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix == GSparseMatrix operator." << endl;
996   - throw;
997   - }
998   - cout << ".";
999   - //
1000   - if ((m_test == bigger) != 0) {
1001   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix == GSparseMatrix operator." << endl;
1002   - throw;
1003   - }
1004   - cout << ".";
1005   - //
1006   - if ((m_test != m_test) != 0) {
1007   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix != GSparseMatrix operator." << endl;
1008   - throw;
1009   - }
1010   - cout << ".";
1011   - //
1012   - if ((m_test != test) != 1) {
1013   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix != GSparseMatrix operator." << endl;
1014   - throw;
1015   - }
1016   - cout << ".";
1017   - //
1018   - if ((m_test != bigger) != 1) {
1019   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix != GSparseMatrix operator." << endl;
1020   - throw;
1021   - }
1022   - cout << ".";
1023   - }
1024   - catch (exception &e) {
1025   - cout << e.what() << endl;
1026   - throw;
1027   - }
1028   - cout << " ok." << endl;
1029   -}
  863 + // Minimum
  864 + double min = m_test.min();
1030 865  
  866 + // Check mimimum
  867 + double value = g_matrix[0];
  868 + for (int row = 0; row < g_rows; ++row) {
  869 + for (int col = 0; col < g_cols; ++col) {
  870 + if (g_matrix[col+row*g_cols] < value) {
  871 + value = g_matrix[col+row*g_cols];
  872 + }
  873 + }
  874 + }
  875 + test_value(min, value, 0.0, "Test minimum function");
1031 876  
1032   -/***************************************************************************
1033   - * Test: Conversion between matrix types *
1034   - ***************************************************************************/
1035   -void test_conversion(void)
1036   -{
1037   - // Dump header
1038   - std::cout << "Test GSparseMatrix: Matrix conversions: ";
  877 + // Maximum
  878 + double max = m_test.max();
1039 879  
1040   - // Test 1
1041   - try {
1042   - //
1043   - // Setup a symmetric sparse matrix
1044   - int num = 10;
1045   - GSparseMatrix sparse(num,num);
1046   - for (int i = 0; i < num; ++i)
1047   - sparse(i,i) = (i+1);
1048   - for (int j = 1; j < num; ++j) {
1049   - sparse(0,j) = (j+1);
1050   - sparse(j,0) = (j+1);
1051   - }
1052   - std::cout << ".";
1053   - //
1054   - // Convert GSparseMatrix matrix into GSymMatrix object
1055   -// GSymMatrix converted = sym_matrix(sparse);
1056   - GSymMatrix converted = GSymMatrix(sparse);
1057   - std::cout << ".";
1058   - //
1059   - // Convert GSymMatrix back to GSparseMatrix matrix
1060   - GSparseMatrix back_convert = GSparseMatrix(converted);
1061   - std::cout << ".";
1062   - //
1063   - // Compare back converted matrix to original one. They should be identical
1064   - if (sparse != back_convert) {
1065   - std::cout << std::endl
1066   - << "TEST ERROR: Unable to convert matrixes (symmetric)."
1067   - << std::endl;
1068   - std::cout << "Original matrix " << sparse << std::endl;
1069   - std::cout << "GSymMatrix matrix " << converted << std::endl;
1070   - std::cout << "Back converted matrix " << back_convert << std::endl;
1071   - throw;
1072   - }
1073   - //
1074   - // Determine the fill of the matrix. It should be 0.28
1075   - double fill = back_convert.fill();
1076   - if (abs(fill-0.28) > 1.0e-15) {
1077   - cout << endl << "TEST ERROR: Bad fill " << fill << " determined (expected 1.0)." <<
1078   - endl;
1079   - throw;
1080   - }
1081   - cout << ".";
1082   - //
1083   - // Extract lower triangle and check values
1084   - #if 0
1085   - GMatrix lower = sparse.extract_lower_triangle();
1086   - int ok = 1;
1087   - for (int j = 1; j < num; ++j) {
1088   - for (int i = 0; i < j; ++i) {
1089   - if (lower(i,j) != 0.0)
1090   - ok = 0;
1091   - }
1092   - }
1093   - for (int j = 0; j < num; ++j) {
1094   - for (int i = j; i < num; ++i) {
1095   - if (lower(i,j) != sparse(i,j))
1096   - ok = 0;
1097   - }
  880 + // Check maximum
  881 + value = g_matrix[0];
  882 + for (int row = 0; row < g_rows; ++row) {
  883 + for (int col = 0; col < g_cols; ++col) {
  884 + if (g_matrix[col+row*g_cols] > value) {
  885 + value = g_matrix[col+row*g_cols];
  886 + }
  887 + }
1098 888 }
1099   - if (!ok) {
1100   - cout << endl << "TEST ERROR: Corrupt extract_lower_triangle." << endl;
1101   - cout << "Original matrix " << sparse << endl;
1102   - cout << "Lower triangle matrix " << lower << endl;
1103   - throw;
  889 + test_value(max, value, 0.0, "Test maximum function");
  890 +
  891 + // Sum
  892 + double sum = m_test.sum();
  893 +
  894 + // Check sum
  895 + value = 0.0;
  896 + for (int row = 0; row < g_rows; ++row) {
  897 + for (int col = 0; col < g_cols; ++col) {
  898 + value += g_matrix[col+row*g_cols];
  899 + }
1104 900 }
1105   - cout << ".";
1106   - //
1107   - // Extract upper triangle and check values
1108   - GMatrix upper = sparse.extract_upper_triangle();
1109   - ok = 1;
1110   - for (int j = 0; j < num; ++j) {
1111   - for (int i = j+1; i < num; ++i) {
1112   - if (upper(i,j) != 0.0)
1113   - ok = 0;
1114   - }
  901 + test_value(sum, value, 1.0e-20, "Test sum function");
  902 +
  903 + // Transpose function
  904 + GSparseMatrix test1 = transpose(m_test);
  905 + test_assert(check_matrix(m_test), "Test source matrix");
  906 + test_assert(check_matrix_trans(test1, 1.0, 0.0),
  907 + "Test transpose(GSparseMatrix) function",
  908 + "Unexpected transposed matrix:\n"+test1.print());
  909 +
  910 + // Transpose method
  911 + test1 = m_test;
  912 + test1.transpose();
  913 + test_assert(check_matrix(m_test), "Test source matrix");
  914 + test_assert(check_matrix_trans(test1, 1.0, 0.0),
  915 + "Test GSparseMatrix.transpose() method",
  916 + "Unexpected transposed matrix:\n"+test1.print());
  917 +
  918 + // Convert to general matrix
  919 + GSparseMatrix test2 = GSparseMatrix(m_test);
  920 + test_assert(check_matrix(m_test), "Test source matrix");
  921 + test_assert(check_matrix(test2, 1.0, 0.0),
  922 + "Test GSparseMatrix(GSparseMatrix) constructor",
  923 + "Unexpected GSparseMatrix:\n"+test2.print());
  924 +
  925 + // Try extracting of lower triangle
  926 + /*
  927 + test_try("Try extracting of lower triangle");
  928 + try {
  929 + test2 = m_test.extract_lower_triangle();
  930 + test_try_failure("Expected GException::matrix_not_square exception.");
1115 931 }
1116   - for (int j = 0; j < num; ++j) {
1117   - for (int i = 0; i <= j; ++i) {
1118   - if (upper(i,j) != sparse(i,j))
1119   - ok = 0;
1120   - }
  932 + catch (GException::matrix_not_square &e) {
  933 + test_try_success();
1121 934 }
1122   - if (!ok) {
1123   - cout << endl << "TEST ERROR: Corrupt extract_upper_triangle." << endl;
1124   - cout << "Original matrix " << sparse << endl;
1125   - cout << "Upper triangle matrix " << upper << endl;
1126   - throw;
  935 + catch (std::exception &e) {
  936 + test_try_failure(e);
1127 937 }
1128   - cout << ".";
1129   - #endif
1130   - //
1131   - // Now make the matrix unsymmetric
1132   - sparse(0,num-1) = 1000.0;
1133   - //
1134   - // Try converting now into GSymMatrix object (this should fail)
  938 + */
  939 +
  940 + // Try extracting of upper triangle
  941 + /*
  942 + test_try("Try extracting of lower triangle");
1135 943 try {
1136   - converted = GSymMatrix(sparse);
1137   - cout << endl << "TEST ERROR: Sparse->Sym conversion should have failed." << endl;
1138   - throw;
1139   - }
1140   - catch (GException::matrix_not_symmetric &e) {
1141   - cout << ".";
  944 + test2 = m_test.extract_upper_triangle();
  945 + test_try_failure("Expected GException::matrix_not_square exception.");
1142 946 }
1143   - catch (exception &e) {
1144   - cout << e.what() << endl;
1145   - throw;
  947 + catch (GException::matrix_not_square &e) {
  948 + test_try_success();
1146 949 }
1147   - //
1148   - // Convert matrix into GMatrix object
1149   - GMatrix full = GMatrix(sparse);
1150   - cout << ".";
1151   - //
1152   - // Convert full matrix back to GSparseMatrix
1153   - back_convert = GSparseMatrix(full);
1154   - cout << ".";
1155   - //
1156   - // Compare back converted matrix to original one. They should be identical
1157   - if (sparse != back_convert) {
1158   - cout << endl << "TEST ERROR: Unable to convert matrixes (sparse)." << endl;
1159   - cout << "Original matrix " << sparse << endl;
1160   - cout << "GMatrix matrix " << full << endl;
1161   - cout << "Back converted matrix " << back_convert << endl;
1162   - throw;
  950 + catch (std::exception &e) {
  951 + test_try_failure(e);
1163 952 }
1164   - cout << ".";
1165   - }
1166   - catch (exception &e) {
1167   - cout << e.what() << endl;
1168   - throw;
1169   - }
1170   - cout << " ok." << endl;
1171   -
1172   - // Return
1173   - return;
  953 + */
  954 +
  955 + // Extract lower triangle for square matrix
  956 + /*
  957 + GSparseMatrix test3 = m_test * transpose(m_test);
  958 + GSparseMatrix test4 = test3.extract_lower_triangle();
  959 + test_assert(check_matrix_lt(test4, test3),
  960 + "Test GSparseMatrix.extract_lower_triangle() method",
  961 + "Unexpected lower triangle:\n"+test4.print());
  962 +
  963 + // Extract upper triangle
  964 + test4 = test3.extract_upper_triangle();
  965 + test_assert(check_matrix_ut(test4, test3),
  966 + "Test GSparseMatrix.extract_upper_triangle() method",
  967 + "Unexpected lower triangle:\n"+test4.print());
  968 + */
  969 +
  970 + // Return
  971 + return;
1174 972 }
1175 973  
1176 974  
1177   -/***************************************************************************
1178   - * Test: Cholesky factorisation *
  975 +/***********************************************************************//**
  976 + * @brief Test matrix comparisons
1179 977 ***************************************************************************/
1180   -void test_cholesky(void)
  978 +void TestGSparseMatrix::matrix_compare(void)
1181 979 {
1182   - // Dump header
1183   - std::cout << "Test GSparseMatrix: Cholesky decomposition, solver and inverter: ";
  980 + // Allocate an empty matrix
  981 + GSparseMatrix empty(g_rows, g_cols);
  982 +
  983 + // Allocate a full matrix
  984 + GSparseMatrix full(g_rows, g_cols);
  985 + for (int i = 0; i < g_rows; ++i) {
  986 + for (int j = 0; j < g_rows; ++j) {
  987 + full(i,j) = 1.0 + i*1000.0 + j*10.0;
  988 + }
  989 + }
  990 +
  991 + // Test == operator
  992 + test_assert((m_test == m_test), "Test == operator",
  993 + "Identity test faileded on:\n"+m_test.print());
  994 + test_assert(!(m_test == empty), "Test == operator",
  995 + "Matrix\n"+m_test.print()+"\nshould not be equal to\n"+empty.print());
  996 + test_assert(!(m_test == full), "Test == operator",
  997 + "Matrix\n"+m_test.print()+"\nshould not be equal to\n"+full.print());
  998 + test_assert(!(m_test == m_bigger), "Test == operator",
  999 + "Matrix\n"+m_test.print()+"\nshould not be equal to\n"+m_bigger.print());
  1000 +
  1001 + // Test != operator
  1002 + test_assert(!(m_test != m_test), "Test != operator",
  1003 + "Unequality test faileded on:\n"+m_test.print());
  1004 + test_assert((m_test != empty), "Test != operator",
  1005 + "Matrix\n"+m_test.print()+"\nshould differ from\n"+empty.print());
  1006 + test_assert((m_test != full), "Test != operator",
  1007 + "Matrix\n"+m_test.print()+"\nshould differ from\n"+full.print());
  1008 + test_assert((m_test != m_bigger), "Test != operator",
  1009 + "Matrix\n"+m_test.print()+"\nshould differ from\n"+m_bigger.print());
  1010 +
  1011 + // Return
  1012 + return;
  1013 +}
1184 1014  
1185   - // Test 1
  1015 +
  1016 +/***********************************************************************//**
  1017 + * @brief Test Cholesky decomposition
  1018 + ***************************************************************************/
  1019 +void TestGSparseMatrix::matrix_cholesky(void)
  1020 +{
  1021 + // Setup matrix for Cholesky decomposition
  1022 + GSparseMatrix chol_test(5,5);
  1023 + chol_test(0,0) = 1.0;
  1024 + chol_test(0,1) = 0.2;
  1025 + chol_test(0,2) = 0.2;
  1026 + chol_test(0,3) = 0.2;
  1027 + chol_test(0,4) = 0.2;
  1028 + chol_test(1,0) = 0.2;
  1029 + chol_test(2,0) = 0.2;
  1030 + chol_test(3,0) = 0.2;
  1031 + chol_test(4,0) = 0.2;
  1032 + chol_test(1,1) = 1.0;
  1033 + chol_test(2,2) = 1.0;
  1034 + chol_test(3,3) = 1.0;
  1035 + chol_test(4,4) = 1.0;
  1036 +
  1037 + // Try to solve now (should not work)
  1038 + test_try("Try Cholesky solver without factorisation");
1186 1039 try {
1187   - //
1188   - // Setup matrix for Cholesky decomposition
1189   - GSparseMatrix m_chol_test(5,5);
1190   - m_chol_test(0,0) = 1.0;
1191   - m_chol_test(0,1) = 0.2;
1192   - m_chol_test(0,2) = 0.2;
1193   - m_chol_test(0,3) = 0.2;
1194   - m_chol_test(0,4) = 0.2;
1195   - m_chol_test(1,0) = 0.2;
1196   - m_chol_test(2,0) = 0.2;
1197   - m_chol_test(3,0) = 0.2;
1198   - m_chol_test(4,0) = 0.2;
1199   - m_chol_test(1,1) = 1.0;
1200   - m_chol_test(2,2) = 1.0;
1201   - m_chol_test(3,3) = 1.0;
1202   - m_chol_test(4,4) = 1.0;
1203   - //
1204   - // Try to solve now (should not work)
1205   - try {
1206   - GVector v_test12(5);
1207   - v_test12 = m_chol_test.cholesky_solver(v_test12);
1208   - }
1209   - catch (GException::matrix_not_factorised) {
1210   - std::cout << ".";
1211   - }
1212   - catch (exception &e) {
1213   - std::cout << e.what() << std::endl;
1214   - throw;
1215   - }
1216   - //
1217   - // Test Cholesky decomposition
1218   - GSparseMatrix cd = cholesky_decompose(m_chol_test);
1219   - std::cout << ".";
1220   - //
1221   - // Test inplace Cholesky decomposition
1222   - cd = m_chol_test;
1223   - cd.cholesky_decompose();
1224   - std::cout << ".";
1225   - //
1226   - // Test Cholesky solver
1227   - GVector e0(5);
1228   - GVector a0(5);
1229   - e0[0] = 1.0;
1230   - a0[0] = 1.0;
1231   - a0[1] = 0.2;
1232   - a0[2] = 0.2;
1233   - a0[3] = 0.2;
1234   - a0[4] = 0.2;
1235   - GVector s0 = cd.cholesky_solver(a0);
1236   - double res = max(abs(s0-e0));
1237   - if (res < 1.0e-15) {
1238   - #if defined(DUMP_RESIDUALS)
1239   - std::cout << " Res(S0)=" << res << " ";
1240   - #else
1241   - std::cout << ".";
1242   - #endif
1243   - }
1244   - else {
1245   - std::cout << std::endl
1246   - << "TEST ERROR: Corrupt cholesky_solver(GVector) function."
1247   - << std::endl;
1248   - std::cout << "Residual vector (all elements should be zero):" << std::endl;
1249   - std::cout << s0 << std::endl;
1250   - throw;
1251   - }
1252   - //
  1040 + GVector vector(5);
  1041 + vector = chol_test.cholesky_solver(vector);
  1042 + test_try_failure("Expected GException::matrix_not_factorised exception.");
  1043 + }
  1044 + catch (GException::matrix_not_factorised) {
  1045 + test_try_success();
  1046 + }
  1047 + catch (std::exception &e) {
  1048 + test_try_failure(e);
  1049 + }
  1050 +
  1051 + // Perform Cholesky decomposition
  1052 + GSparseMatrix cd = cholesky_decompose(chol_test);
  1053 +
  1054 + // Perform inplace Cholesky decomposition
  1055 + cd = chol_test;
  1056 + cd.cholesky_decompose();
  1057 +
  1058 + // Test Cholesky solver (first test)
  1059 + GVector e0(5);
  1060 + GVector a0(5);
  1061 + e0[0] = 1.0;
  1062 + a0[0] = 1.0;
  1063 + a0[1] = 0.2;
  1064 + a0[2] = 0.2;
  1065 + a0[3] = 0.2;
  1066 + a0[4] = 0.2;
  1067 + GVector s0 = cd.cholesky_solver(a0);
  1068 + double res = max(abs(s0-e0));
  1069 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 1");
  1070 +
  1071 + // Test Cholesky solver (second test)
1253 1072 e0[0] = 0.0;
1254 1073 e0[1] = 1.0;
1255 1074 a0[0] = 0.2;
... ... @@ -1259,97 +1078,56 @@ void test_cholesky(void)
1259 1078 a0[4] = 0.0;
1260 1079 s0 = cd.cholesky_solver(a0);
1261 1080 res = max(abs(s0-e0));
1262   - if (res < 1.0e-15)
1263   - #if defined(DUMP_RESIDUALS)
1264   - cout << "Res(S1)=" << res << " ";
1265   - #else
1266   - cout << ".";
1267   - #endif
1268   - else {
1269   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1270   - cout << "Residual vector (all elements should be zero):" << endl;
1271   - cout << s0 << endl;
1272   - throw;
1273   - }
1274   - //
  1081 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 2");
  1082 +
  1083 + // Test Cholesky solver (third test)
1275 1084 e0[1] = 0.0;
1276 1085 e0[2] = 1.0;
1277 1086 a0[1] = 0.0;
1278 1087 a0[2] = 1.0;
1279 1088 s0 = cd.cholesky_solver(a0);
1280 1089 res = max(abs(s0-e0));
1281   - if (res < 1.0e-15)
1282   - #if defined(DUMP_RESIDUALS)
1283   - cout << "Res(S2)=" << res << " ";
1284   - #else
1285   - cout << ".";
1286   - #endif
1287   - else {
1288   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1289   - cout << "Residual vector (all elements should be zero):" << endl;
1290   - cout << s0 << endl;
1291   - throw;
1292   - }
1293   - //
  1090 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 3");
  1091 +
  1092 + // Test Cholesky solver (forth test)
1294 1093 e0[2] = 0.0;
1295 1094 e0[3] = 1.0;
1296 1095 a0[2] = 0.0;
1297 1096 a0[3] = 1.0;
1298 1097 s0 = cd.cholesky_solver(a0);
1299 1098 res = max(abs(s0-e0));
1300   - if (res < 1.0e-15)
1301   - #if defined(DUMP_RESIDUALS)
1302   - cout << "Res(S3)=" << res << " ";
1303   - #else
1304   - cout << ".";
1305   - #endif
1306   - else {
1307   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1308   - cout << "Residual vector (all elements should be zero):" << endl;
1309   - cout << s0 << endl;
1310   - throw;
1311   - }
1312   - //
  1099 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 4");
  1100 +
  1101 + // Test Cholesky solver (fifth test)
1313 1102 e0[3] = 0.0;
1314 1103 e0[4] = 1.0;
1315 1104 a0[3] = 0.0;
1316 1105 a0[4] = 1.0;
1317 1106 s0 = cd.cholesky_solver(a0);
1318 1107 res = max(abs(s0-e0));
1319   - if (res < 1.0e-15)
1320   - #if defined(DUMP_RESIDUALS)
1321   - cout << "Res(S4)=" << res << " ";
1322   - #else
1323   - cout << ".";
1324   - #endif
1325   - else {
1326   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1327   - cout << "Residual vector (all elements should be zero):" << endl;
1328   - cout << s0 << endl;
1329   - throw;
1330   - }
1331   - //
  1108 + test_value(res, 0.0, 1.0e-15, "Test cholesky_solver() method - 5");
  1109 +
1332 1110 // Setup matrix for Cholesky decomposition with zero row/col
1333   - GSparseMatrix m_chol_test_zero(6,6);
1334   - m_chol_test_zero(0,0) = 1.0;
1335   - m_chol_test_zero(0,1) = 0.2;
1336   - m_chol_test_zero(0,2) = 0.2;
1337   - m_chol_test_zero(0,4) = 0.2;
1338   - m_chol_test_zero(0,5) = 0.2;
1339   - m_chol_test_zero(1,0) = 0.2;
1340   - m_chol_test_zero(2,0) = 0.2;
1341   - m_chol_test_zero(4,0) = 0.2;
1342   - m_chol_test_zero(5,0) = 0.2;
1343   - m_chol_test_zero(1,1) = 1.0;
1344   - m_chol_test_zero(2,2) = 1.0;
1345   - m_chol_test_zero(4,4) = 1.0;
1346   - m_chol_test_zero(5,5) = 1.0;
1347   - //
  1111 + GSparseMatrix chol_test_zero(6,6);
  1112 + chol_test_zero(0,0) = 1.0;
  1113 + chol_test_zero(0,1) = 0.2;
  1114 + chol_test_zero(0,2) = 0.2;
  1115 + chol_test_zero(0,4) = 0.2;
  1116 + chol_test_zero(0,5) = 0.2;
  1117 + chol_test_zero(1,0) = 0.2;
  1118 + chol_test_zero(2,0) = 0.2;
  1119 + chol_test_zero(4,0) = 0.2;
  1120 + chol_test_zero(5,0) = 0.2;
  1121 + chol_test_zero(1,1) = 1.0;
  1122 + chol_test_zero(2,2) = 1.0;
  1123 + chol_test_zero(4,4) = 1.0;
  1124 + chol_test_zero(5,5) = 1.0;
  1125 +
1348 1126 // Test compressed Cholesky decomposition
1349   - GSparseMatrix cd_zero = m_chol_test_zero;
  1127 + GSparseMatrix cd_zero = chol_test_zero;
1350 1128 cd_zero.cholesky_decompose();
1351   - //
1352   - // Test compressed Cholesky solver
  1129 +
  1130 + // Test compressed Cholesky solver (first test)
1353 1131 e0 = GVector(6);
1354 1132 a0 = GVector(6);
1355 1133 e0[0] = 1.0;
... ... @@ -1360,19 +1138,9 @@ void test_cholesky(void)
1360 1138 a0[5] = 0.2;
1361 1139 s0 = cd_zero.cholesky_solver(a0);
1362 1140 res = max(abs(s0-e0));
1363   - if (res < 1.0e-15)
1364   - #if defined(DUMP_RESIDUALS)
1365   - cout << "Res(S0Z)=" << res << " ";
1366   - #else
1367   - cout << ".";
1368   - #endif
1369   - else {
1370   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1371   - cout << "Residual vector (all elements should be zero):" << endl;
1372   - cout << s0 << endl;
1373   - throw;
1374   - }
1375   - //
  1141 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 1");
  1142 +
  1143 + // Test compressed Cholesky solver (second test)
1376 1144 e0[0] = 0.0;
1377 1145 e0[1] = 1.0;
1378 1146 a0[0] = 0.2;
... ... @@ -1382,96 +1150,55 @@ void test_cholesky(void)
1382 1150 a0[5] = 0.0;
1383 1151 s0 = cd_zero.cholesky_solver(a0);
1384 1152 res = max(abs(s0-e0));
1385   - if (res < 1.0e-15)
1386   - #if defined(DUMP_RESIDUALS)
1387   - cout << "Res(S1Z)=" << res << " ";
1388   - #else
1389   - cout << ".";
1390   - #endif
1391   - else {
1392   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1393   - cout << "Residual vector (all elements should be zero):" << endl;
1394   - cout << s0 << endl;
1395   - throw;
1396   - }
1397   - //
  1153 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 2");
  1154 +
  1155 + // Test compressed Cholesky solver (third test)
1398 1156 e0[1] = 0.0;
1399 1157 e0[2] = 1.0;
1400 1158 a0[1] = 0.0;
1401 1159 a0[2] = 1.0;
1402 1160 s0 = cd_zero.cholesky_solver(a0);
1403 1161 res = max(abs(s0-e0));
1404   - if (res < 1.0e-15)
1405   - #if defined(DUMP_RESIDUALS)
1406   - cout << "Res(S2Z)=" << res << " ";
1407   - #else
1408   - cout << ".";
1409   - #endif
1410   - else {
1411   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1412   - cout << "Residual vector (all elements should be zero):" << endl;
1413   - cout << s0 << endl;
1414   - throw;
1415   - }
1416   - //
  1162 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 3");
  1163 +
  1164 + // Test compressed Cholesky solver (forth test)
1417 1165 e0[2] = 0.0;
1418 1166 e0[4] = 1.0;
1419 1167 a0[2] = 0.0;
1420 1168 a0[4] = 1.0;
1421 1169 s0 = cd_zero.cholesky_solver(a0);
1422 1170 res = max(abs(s0-e0));
1423   - if (res < 1.0e-15)
1424   - #if defined(DUMP_RESIDUALS)
1425   - cout << "Res(S3Z)=" << res << " ";
1426   - #else
1427   - cout << ".";
1428   - #endif
1429   - else {
1430   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1431   - cout << "Residual vector (all elements should be zero):" << endl;
1432   - cout << s0 << endl;
1433   - throw;
1434   - }
1435   - //
  1171 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 4");
  1172 +
  1173 + // Test compressed Cholesky solver (fifth test)
1436 1174 e0[4] = 0.0;
1437 1175 e0[5] = 1.0;
1438 1176 a0[4] = 0.0;
1439 1177 a0[5] = 1.0;
1440 1178 s0 = cd_zero.cholesky_solver(a0);
1441 1179 res = max(abs(s0-e0));
1442   - if (res < 1.0e-15)
1443   - #if defined(DUMP_RESIDUALS)
1444   - cout << "Res(S4Z)=" << res << " ";
1445   - #else
1446   - cout << ".";
1447   - #endif
1448   - else {
1449   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1450   - cout << "Residual vector (all elements should be zero):" << endl;
1451   - cout << s0 << endl;
1452   - throw;
1453   - }
1454   - //
  1180 + test_value(res, 0.0, 1.0e-15, "Test compressed cholesky_solver() method - 5");
  1181 +
1455 1182 // Setup matrix for Cholesky decomposition with zero row/col (unsymmetric case)
1456   - GSparseMatrix m_chol_test_zero2(6,5);
1457   - m_chol_test_zero2(0,0) = 1.0;
1458   - m_chol_test_zero2(0,1) = 0.2;
1459   - m_chol_test_zero2(0,2) = 0.2;
1460   - m_chol_test_zero2(0,3) = 0.2;
1461   - m_chol_test_zero2(0,4) = 0.2;
1462   - m_chol_test_zero2(1,0) = 0.2;
1463   - m_chol_test_zero2(2,0) = 0.2;
1464   - m_chol_test_zero2(4,0) = 0.2;
1465   - m_chol_test_zero2(5,0) = 0.2;
1466   - m_chol_test_zero2(1,1) = 1.0;
1467   - m_chol_test_zero2(2,2) = 1.0;
1468   - m_chol_test_zero2(4,3) = 1.0;
1469   - m_chol_test_zero2(5,4) = 1.0;
1470   - //
  1183 + GSparseMatrix chol_test_zero2(6,5);
  1184 + chol_test_zero2(0,0) = 1.0;
  1185 + chol_test_zero2(0,1) = 0.2;
  1186 + chol_test_zero2(0,2) = 0.2;
  1187 + chol_test_zero2(0,3) = 0.2;
  1188 + chol_test_zero2(0,4) = 0.2;
  1189 + chol_test_zero2(1,0) = 0.2;
  1190 + chol_test_zero2(2,0) = 0.2;
  1191 + chol_test_zero2(4,0) = 0.2;
  1192 + chol_test_zero2(5,0) = 0.2;
  1193 + chol_test_zero2(1,1) = 1.0;
  1194 + chol_test_zero2(2,2) = 1.0;
  1195 + chol_test_zero2(4,3) = 1.0;
  1196 + chol_test_zero2(5,4) = 1.0;
  1197 +
1471 1198 // Test compressed Cholesky decomposition (unsymmetric case)
1472   - GSparseMatrix cd_zero2 = m_chol_test_zero2;
  1199 + GSparseMatrix cd_zero2 = chol_test_zero2;
1473 1200 cd_zero2.cholesky_decompose();
1474   - //
  1201 +
1475 1202 // Test compressed Cholesky solver (unsymmetric case)
1476 1203 e0 = GVector(5);
1477 1204 a0 = GVector(6);
... ... @@ -1483,19 +1210,10 @@ void test_cholesky(void)
1483 1210 a0[5] = 0.2;
1484 1211 s0 = cd_zero2.cholesky_solver(a0);
1485 1212 res = max(abs(s0-e0));
1486   - if (res < 1.0e-15)
1487   - #if defined(DUMP_RESIDUALS)
1488   - cout << "Res(S0ZU)=" << res << " ";
1489   - #else
1490   - cout << ".";
1491   - #endif
1492   - else {
1493   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1494   - cout << "Residual vector (all elements should be zero):" << endl;
1495   - cout << s0 << endl;
1496   - throw;
1497   - }
1498   - //
  1213 + test_value(res, 0.0, 1.0e-15,
  1214 + "Test unsymmetric compressed cholesky_solver() method - 1");
  1215 +
  1216 + // Test compressed Cholesky solver (unsymmetric case)
1499 1217 e0[0] = 0.0;
1500 1218 e0[1] = 1.0;
1501 1219 a0[0] = 0.2;
... ... @@ -1505,76 +1223,39 @@ void test_cholesky(void)
1505 1223 a0[5] = 0.0;
1506 1224 s0 = cd_zero2.cholesky_solver(a0);
1507 1225 res = max(abs(s0-e0));
1508   - if (res < 1.0e-15)
1509   - #if defined(DUMP_RESIDUALS)
1510   - cout << "Res(S1ZU)=" << res << " ";
1511   - #else
1512   - cout << ".";
1513   - #endif
1514   - else {
1515   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1516   - cout << "Residual vector (all elements should be zero):" << endl;
1517   - cout << s0 << endl;
1518   - throw;
1519   - }
1520   - //
  1226 + test_value(res, 0.0, 1.0e-15,
  1227 + "Test unsymmetric compressed cholesky_solver() method - 2");
  1228 +
  1229 + // Test compressed Cholesky solver (unsymmetric case)
1521 1230 e0[1] = 0.0;
1522 1231 e0[2] = 1.0;
1523 1232 a0[1] = 0.0;
1524 1233 a0[2] = 1.0;
1525 1234 s0 = cd_zero2.cholesky_solver(a0);
1526 1235 res = max(abs(s0-e0));
1527   - if (res < 1.0e-15)
1528   - #if defined(DUMP_RESIDUALS)
1529   - cout << "Res(S2ZU)=" << res << " ";
1530   - #else
1531   - cout << ".";
1532   - #endif
1533   - else {
1534   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1535   - cout << "Residual vector (all elements should be zero):" << endl;
1536   - cout << s0 << endl;
1537   - throw;
1538   - }
1539   - //
  1236 + test_value(res, 0.0, 1.0e-15,
  1237 + "Test unsymmetric compressed cholesky_solver() method - 3");
  1238 +
  1239 + // Test compressed Cholesky solver (unsymmetric case)
1540 1240 e0[2] = 0.0;
1541 1241 e0[3] = 1.0;
1542 1242 a0[2] = 0.0;
1543 1243 a0[4] = 1.0;
1544 1244 s0 = cd_zero2.cholesky_solver(a0);
1545 1245 res = max(abs(s0-e0));
1546   - if (res < 1.0e-15)
1547   - #if defined(DUMP_RESIDUALS)
1548   - cout << "Res(S3ZU)=" << res << " ";
1549   - #else
1550   - cout << ".";
1551   - #endif
1552   - else {
1553   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1554   - cout << "Residual vector (all elements should be zero):" << endl;
1555   - cout << s0 << endl;
1556   - throw;
1557   - }
1558   - //
  1246 + test_value(res, 0.0, 1.0e-15,
  1247 + "Test unsymmetric compressed cholesky_solver() method - 4");
  1248 +
  1249 + // Test compressed Cholesky solver (unsymmetric case)
1559 1250 e0[3] = 0.0;
1560 1251 e0[4] = 1.0;
1561 1252 a0[4] = 0.0;
1562 1253 a0[5] = 1.0;
1563 1254 s0 = cd_zero2.cholesky_solver(a0);
1564 1255 res = max(abs(s0-e0));
1565   - if (res < 1.0e-15)
1566   - #if defined(DUMP_RESIDUALS)
1567   - cout << "Res(S4ZU)=" << res << " ";
1568   - #else
1569   - cout << ".";
1570   - #endif
1571   - else {
1572   - cout << endl << "TEST ERROR: Corrupt cholesky_solver(GVector) function." << endl;
1573   - cout << "Residual vector (all elements should be zero):" << endl;
1574   - cout << s0 << endl;
1575   - throw;
1576   - }
1577   - //
  1256 + test_value(res, 0.0, 1.0e-15,
  1257 + "Test unsymmetric compressed cholesky_solver() method - 5");
  1258 +
1578 1259 // Test Cholesky inverter (inplace)
1579 1260 GSparseMatrix unit(5,5);
1580 1261 unit(0,0) = 1.0;
... ... @@ -1582,77 +1263,33 @@ void test_cholesky(void)
1582 1263 unit(2,2) = 1.0;
1583 1264 unit(3,3) = 1.0;
1584 1265 unit(4,4) = 1.0;
1585   - GSparseMatrix m_chol_test_inv = m_chol_test;
1586   - m_chol_test_inv.cholesky_invert();
1587   - GSparseMatrix ci_product = m_chol_test * m_chol_test_inv;
  1266 + GSparseMatrix chol_test_inv = chol_test;
  1267 + chol_test_inv.cholesky_invert();
  1268 + GSparseMatrix ci_product = chol_test * chol_test_inv;
1588 1269 GSparseMatrix ci_residuals = ci_product - unit;
1589 1270 res = (abs(ci_residuals)).max();
1590   - if (res < 1.0e-15)
1591   - #if defined(DUMP_RESIDUALS)
1592   - cout << "Res(CI)=" << res << " ";
1593   - #else
1594   - cout << ".";
1595   - #endif
1596   - else {
1597   - cout << endl << "TEST ERROR: Corrupt GSparseMatrix.cholesky_invert() function." << endl;
1598   - cout << "Residual matrix (all elements should be zero):" << endl;
1599   - cout << ci_residuals << endl;
1600   - throw;
1601   - }
1602   - //
  1271 + test_value(res, 0.0, 1.0e-15, "Test inplace Cholesky inverter");
  1272 +
1603 1273 // Test Cholesky inverter
1604   - m_chol_test_inv = cholesky_invert(m_chol_test);
1605   - ci_product = m_chol_test * m_chol_test_inv;
1606   - ci_residuals = ci_product - unit;
1607   - res = (abs(ci_residuals)).max();
1608   - if (res < 1.0e-15)
1609   - #if defined(DUMP_RESIDUALS)
1610   - cout << "Res(CI2)=" << res << " ";
1611   - #else
1612   - cout << ".";
1613   - #endif
1614   - else {
1615   - cout << endl << "TEST ERROR: Corrupt cholesky_invert(GSparseMatrix) function." << endl;
1616   - cout << "Residual matrix (all elements should be zero):" << endl;
1617   - cout << ci_residuals << endl;
1618   - throw;
1619   - }
1620   - //
1621   - // Test Cholesky inverter for compressed matrix
1622   - unit = GSparseMatrix(6,6);
1623   - unit(0,0) = 1.0;
1624   - unit(1,1) = 1.0;
1625   - unit(2,2) = 1.0;
1626   - unit(4,4) = 1.0;
1627   - unit(5,5) = 1.0;
1628   - GSparseMatrix m_chol_test_zero_inv = m_chol_test_zero;
1629   - m_chol_test_zero_inv.cholesky_invert();
1630   - GSparseMatrix ciz_product = m_chol_test_zero * m_chol_test_zero_inv;
1631   - GSparseMatrix ciz_residuals = ciz_product - unit;
1632   - res = (abs(ciz_residuals)).max();
1633   - if (res < 1.0e-15) {
1634   - #if defined(DUMP_RESIDUALS)
1635   - std::cout << "Res(CIZ)=" << res << " ";
1636   - #else
1637   - std::cout << ".";
1638   - #endif
1639   - }
1640   - else {
1641   - std::cout << std::endl
1642   - << "TEST ERROR: Corrupt compressed GSparseMatrix.cholesky_invert()"
1643   - " method." << std::endl;
1644   - std::cout << "Residual matrix (all elements should be zero):" << std::endl;
1645   - std::cout << ciz_residuals << std::endl;
1646   - throw;
1647   - }
1648   - }
1649   - catch (exception &e) {
1650   - std::cout << e.what() << std::endl;
1651   - throw;
1652   - }
1653   -
1654   - // Dump final test ok
1655   - std::cout << "ok." << std::endl;
  1274 + chol_test_inv = cholesky_invert(chol_test);
  1275 + ci_product = chol_test * chol_test_inv;
  1276 + ci_residuals = ci_product - unit;
  1277 + res = (abs(ci_residuals)).max();
  1278 + test_value(res, 0.0, 1.0e-15, "Test Cholesky inverter");
  1279 +
  1280 + // Test Cholesky inverter for compressed matrix
  1281 + unit = GSparseMatrix(6,6);
  1282 + unit(0,0) = 1.0;
  1283 + unit(1,1) = 1.0;
  1284 + unit(2,2) = 1.0;
  1285 + unit(4,4) = 1.0;
  1286 + unit(5,5) = 1.0;
  1287 + GSparseMatrix chol_test_zero_inv = chol_test_zero;
  1288 + chol_test_zero_inv.cholesky_invert();
  1289 + GSparseMatrix ciz_product = chol_test_zero * chol_test_zero_inv;
  1290 + GSparseMatrix ciz_residuals = ciz_product - unit;
  1291 + res = (abs(ciz_residuals)).max();
  1292 + test_value(res, 0.0, 1.0e-15, "Test compressed matrix Cholesky inverter");
1656 1293  
1657 1294 // Return
1658 1295 return;
... ... @@ -1660,227 +1297,97 @@ void test_cholesky(void)
1660 1297  
1661 1298  
1662 1299 /***************************************************************************
1663   - * Test: Heavy calculus *
  1300 + * @brief Test matrix printing
1664 1301 ***************************************************************************/
1665   -void test_heavy(int block = 512)
  1302 +void TestGSparseMatrix::matrix_print(void)
1666 1303 {
1667   - // Allocate some variables
1668   - clock_t t_start;
1669   - double t_elapse;
1670   - int number;
1671   - int num_cols;
1672   - int i_min, i_max;
1673   -
1674   - // Perform test
1675   - cout << "Test GSparseMatrix: Heavy calculus: ";
1676   - try {
1677   - //
1678   - // Fill 10000 x 10000 matrix with 10000 values
1679   - t_start = clock();
1680   - number = 10000;
1681   - GSparseMatrix large(number,number);
1682   - large.set_mem_block(block);
1683   - for (int i = 0; i < number; ++i)
1684   - large(i,i) = (i+1)*3.14;
1685   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1686   - #if defined(DUMP_TIMING)
1687   - cout << endl << " - Fill of 10000 values needed " << t_elapse <<
1688   - " sec (reference ~ 0.2 sec)";
1689   - #endif
1690   - //
1691   - // Modify 10000 x 10000 matrix with 10000 (exisiting) values
1692   - t_start = clock();
1693   - for (int i = 0; i < number; ++i)
1694   - large(i,i) = (i+1)*1.0;
1695   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1696   - #if defined(DUMP_TIMING)
1697   - cout << endl << " - Modification of 10000 values needed " << t_elapse <<
1698   - " sec (reference ~ 0 sec)";
1699   - #endif
1700   - //
1701   - // Insert columns into 10000 x 10000 matrix
1702   - number = 10000;
1703   - num_cols = 10000;
1704   - GSparseMatrix diag(number,number);
1705   - for (int j = 10; j < number-10; ++j)
1706   - diag(j,j) = 3.14;
1707   - large = diag;
1708   - large.set_mem_block(block);
1709   - GVector column(number);
1710   - t_start = clock();
1711   - for (int j = 0; j < num_cols; ++j) {
1712   - i_min = (j < 2) ? 0 : j-2;
1713   - i_max = (j > num_cols-2) ? num_cols : j+2;
1714   - column = 0.0;
1715   - for (int i = i_min; i < i_max; ++i)
1716   - column[i] = (i+1)*0.01;
1717   - large.add_col(column, j);
1718   - }
1719   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1720   - #if defined(DUMP_TIMING)
1721   - cout << endl << " - " << num_cols << " columns adding needed " << t_elapse <<
1722   - " sec (reference ~ 4.6 sec)";
1723   - #endif
1724   - //
1725   - // Insert columns into 10000 x 10000 matrix using matrix stack
1726   - GSparseMatrix stack(number,number);
1727   - stack = diag;
1728   - stack.set_mem_block(block);
1729   - for (int j = 200; j < 400; ++j)
1730   - stack(j,j) = 3.14;
1731   - t_start = clock();
1732   - column = GVector(number);
1733   - stack.stack_init(10000, 1000);
1734   - for (int j = 0; j < num_cols; ++j) {
1735   - i_min = (j < 2) ? 0 : j-2;
1736   - i_max = (j > num_cols-2) ? num_cols : j+2;
1737   - column = 0.0;
1738   - for (int i = i_min; i < i_max; ++i)
1739   - column[i] = (i+1)*0.01;
1740   - stack.add_col(column, j);
1741   - }
1742   - stack.stack_destroy();
1743   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1744   - #if defined(DUMP_TIMING)
1745   - cout << endl << " - " << num_cols << " columns stack-adding needed " << t_elapse <<
1746   - " sec (reference ~ 1 sec)";
1747   - #endif
1748   - //
1749   - // Check that both are identical
1750   - if (large != stack) {
1751   - cout << endl << "TEST ERROR: Stack-based insertion corrupted." << endl;
1752   - for (int i = 0; i < number; ++i) {
1753   - for (int j = 0; j < number; ++j) {
1754   - if (large(i,j) != stack(i,j)) {
1755   - std::cout << "(" << i << "," << j << "): ";
1756   - std::cout << large(i,j) << " is not stack " << stack(i,j) << std::endl;
1757   - }
  1304 + // Set reference
  1305 + std::string reference;
  1306 + reference.append("=== GSparseMatrix ===\n");
  1307 + reference.append(" Number of rows ............: 4\n");
  1308 + reference.append(" Number of columns .........: 5\n");
  1309 + reference.append(" Number of nonzero elements : 9\n");
  1310 + reference.append(" Pending element ...........: (3,4)=9\n");
  1311 + reference.append(" Number of allocated cells .: 512\n");
  1312 + reference.append(" Memory block size .........: 512\n");
  1313 + reference.append(" Sparse matrix fill ........: 0.45\n");
  1314 + reference.append(" Pending element ...........: 9\n");
  1315 + reference.append(" Fill stack size ...........: 0 (none)\n");
  1316 + reference.append(" 1, 0, 0, 0, 7\n");
  1317 + reference.append(" 0, 3, 0, 0, 0\n");
  1318 + reference.append(" 2, 0, 4, 0, 8\n");
  1319 + reference.append(" 0, 0, 5, 6, 9");
  1320 +
  1321 + // Test the print method
  1322 + std::string output = m_test.print();
  1323 + test_assert((output == reference), "Test matrix printing",
  1324 + "Unexpected print() output:\n"+output+"\nExpected:\n"+reference);
  1325 +
  1326 + // Allocate big matrix
  1327 + GSparseMatrix big(30, 40);
  1328 + for (int i = 0; i < 30; ++i) {
  1329 + for (int j = 0; j < 40; ++j) {
  1330 + big(i,j) = i+j;
1758 1331 }
1759   - }
1760   - throw;
1761   - }
1762   - //
1763   - // Subsequent addition and subtractions
1764   - number = 300;
1765   - t_start = clock();
1766   - GSparseMatrix sum(number,number);
1767   - GSparseMatrix add(number,number);
1768   - GSparseMatrix sub(number,number);
1769   - sum.set_mem_block(block);
1770   - add.set_mem_block(block);
1771   - sub.set_mem_block(block);
1772   - for (int i = 0; i < number; ++i) {
1773   - add(i,number-i-1) = (i*i+1)*0.01;
1774   - sum += add;
1775   - sub(i,i) = (i+1)*1.0;
1776   - sum -= sub;
1777   - }
1778   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1779   - #if defined(DUMP_TIMING)
1780   - cout << endl << " - Matrix adding and subtraction 300 times " << t_elapse <<
1781   - " sec (reference ~ 1.4 sec)";
1782   - #endif
1783   - //
1784   - // Subsequent multiplications
1785   - GSparseMatrix fac(number,number);
1786   - fac.set_mem_block(block);
1787   - t_start = clock();
1788   - for (int i = 0; i < 1; ++i) {
1789   - for (int j = 0; j < number; ++j)
1790   - fac(j,j) = (i+1)*1.0;
1791   - sum *= fac;
1792   - }
1793   - t_elapse = double(clock() - t_start)/double(CLOCKS_PER_SEC);
1794   - #if defined(DUMP_TIMING)
1795   - cout << endl << " - Matrix multiplication 1 times " << t_elapse <<
1796   - " sec (reference ~ 3.1 sec)";
1797   - #endif
1798   - }
1799   - catch (exception &e) {
1800   - cout << e.what() << endl;
1801   - throw;
1802   - }
1803   - #if defined(DUMP_TIMING)
1804   - cout << endl;
1805   - #endif
1806   - cout << "ok." << endl;
1807   -}
1808   -
1809   -
1810   -void test_stack(int block = 512)
1811   -{
1812   - // Set parameters
1813   - int nrows = 10;
1814   - int ncols = 10;
1815   -
1816   - // Initialise column vector
1817   - GVector column(nrows);
1818   - for (int i = 0; i < nrows; i+=2) {
1819   - column[i] = 5.0;
1820 1332 }
1821 1333  
1822   - // Initialise reference matrix
1823   - GSparseMatrix ref(nrows, ncols);
1824   - for (int i = 0; i < ncols; i+=2) {
1825   - ref.add_col(column, i);
1826   - }
  1334 + // Set reference for big matrix
  1335 + std::string ref_big;
  1336 + ref_big.append("=== GSparseMatrix ===\n");
  1337 + ref_big.append(" Number of rows ............: 30\n");
  1338 + ref_big.append(" Number of columns .........: 40\n");
  1339 + ref_big.append(" Number of nonzero elements : 1199\n");
  1340 + ref_big.append(" Pending element ...........: (29,39)=68\n");
  1341 + ref_big.append(" Number of allocated cells .: 1536\n");
  1342 + ref_big.append(" Memory block size .........: 512\n");
  1343 + ref_big.append(" Sparse matrix fill ........: 0.999167\n");
  1344 + ref_big.append(" Pending element ...........: 68\n");
  1345 + ref_big.append(" Fill stack size ...........: 0 (none)\n");
  1346 + ref_big.append(" 0, 1, 2, 3, 4, ... 35, 36, 37, 38, 39\n");
  1347 + ref_big.append(" 1, 2, 3, 4, 5, ... 36, 37, 38, 39, 40\n");
  1348 + ref_big.append(" 2, 3, 4, 5, 6, ... 37, 38, 39, 40, 41\n");
  1349 + ref_big.append(" 3, 4, 5, 6, 7, ... 38, 39, 40, 41, 42\n");
  1350 + ref_big.append(" 4, 5, 6, 7, 8, ... 39, 40, 41, 42, 43\n");
  1351 + ref_big.append(" ... ... ... ... ... ... ... ... ... ... ... \n");
  1352 + ref_big.append(" 25, 26, 27, 28, 29, ... 60, 61, 62, 63, 64\n");
  1353 + ref_big.append(" 26, 27, 28, 29, 30, ... 61, 62, 63, 64, 65\n");
  1354 + ref_big.append(" 27, 28, 29, 30, 31, ... 62, 63, 64, 65, 66\n");
  1355 + ref_big.append(" 28, 29, 30, 31, 32, ... 63, 64, 65, 66, 67\n");
  1356 + ref_big.append(" 29, 30, 31, 32, 33, ... 64, 65, 66, 67, 68");
  1357 +
  1358 + // Test the print method
  1359 + output = big.print();
  1360 + test_assert((output == ref_big), "Test big matrix printing",
  1361 + "Unexpected print() output:\n"+output+"\nExpected:\n"+ref_big);
1827 1362  
1828   - // Initialise stack matrix
1829   - GSparseMatrix stack(nrows, ncols);
1830   - stack.stack_init(10000, 4);
1831   - for (int i = 0; i < ncols; i+=2) {
1832   - stack.add_col(column, i);
1833   - }
1834   - stack.stack_destroy();
1835   -
1836   - // Compare
1837   - if (ref != stack) {
1838   - std::cout << endl << "TEST ERROR: Stack-based insertion corrupted." << std::endl;
1839   - for (int i = 0; i < nrows; ++i) {
1840   - for (int j = 0; j < ncols; ++j) {
1841   - if (ref(i,j) != stack(i,j)) {
1842   - std::cout << "(" << i << "," << j << "): ";
1843   - std::cout << "ref=" << ref(i,j) << " stack=" << stack(i,j) << std::endl;
1844   - }
1845   - }
1846   - }
1847   - throw;
1848   - }
  1363 + // Return
  1364 + return;
1849 1365 }
1850 1366  
1851 1367  
1852 1368 /***************************************************************************
1853   - * Main test function *
  1369 + * @brief Main entry point for test executable
1854 1370 ***************************************************************************/
1855 1371 int main(void)
1856 1372 {
1857   - // Dump header
1858   - std::cout << std::endl;
1859   - std::cout << "*******************************" << std::endl;
1860   - std::cout << "* GSparseMatrix class testing *" << std::endl;
1861   - std::cout << "*******************************" << std::endl;
1862   -
1863   - // Set test matrix and vector
1864   - GSparseMatrix m_test = set_matrix();
1865   - GVector v_test = set_vector();
1866   -
1867   - // Execute the tests
1868   - test_output(m_test);
1869   - test_allocate();
1870   - test_assign_values(m_test);
1871   - test_copy_constructor(m_test);
1872   - test_assign_matrix(m_test);
1873   - test_transpose(m_test);
1874   - test_matrix_vector(m_test, v_test);
1875   - test_matrix_matrix(m_test);
1876   - test_arithmetics(m_test);
1877   - test_functions(m_test);
1878   - test_comparison(m_test);
1879   - test_conversion();
1880   - test_cholesky();
1881   - test_heavy();
1882   - //test_stack();
  1373 + // Allocate test suit container
  1374 + GTestSuites testsuites("GSparseMatrix class testing");
1883 1375  
1884   - // Return
1885   - return 0;
  1376 + // Initially assume that we pass all tests
  1377 + bool success = true;
  1378 +
  1379 + // Create a test suite
  1380 + TestGSparseMatrix test;
  1381 +
  1382 + // Append test suite to the container
  1383 + testsuites.append(test);
  1384 +
  1385 + // Run the testsuites
  1386 + success = testsuites.run();
  1387 +
  1388 + // Save test report
  1389 + testsuites.save("reports/GSparseMatrix.xml");
  1390 +
  1391 + // Return success status
  1392 + return (success ? 0 : 1);
1886 1393 }
... ...
test/test_GSparseMatrix.hpp 0 → 100644
  1 +/***************************************************************************
  2 + * test_GSparseMatrix.hpp - Test sparse 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_GSparseMatrix.hpp
  23 + * @brief Definition of unit tests for sparse matrices
  24 + * @author Juergen Knoedlseder
  25 + */
  26 +
  27 +#ifndef TEST_GSPARSEMATRIX_HPP
  28 +#define TEST_GSPARSEMATRIX_HPP
  29 +
  30 +/* __ Includes ___________________________________________________________ */
  31 +#include "GammaLib.hpp"
  32 +
  33 +
  34 +/***********************************************************************//**
  35 + * @class TestGSparseMatrix
  36 + *
  37 + * @brief Test suite for sparse matrix class testing
  38 + *
  39 + * This test suite performs a unit test for the sparse 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 TestGSparseMatrix : public GTestSuite {
  44 +
  45 +public:
  46 + // Constructors and destructors
  47 + TestGSparseMatrix(void) : GTestSuite() {}
  48 + virtual ~TestGSparseMatrix(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 + GSparseMatrix set_matrix(void) const;
  65 + //GSparseMatrix set_matrix_zero(void) const;
  66 + GVector set_vector(void) const;
  67 + bool check_matrix(const GSparseMatrix& matrix,
  68 + const double& scale = 1.0,
  69 + const double& offset = 0.0) const;
  70 + bool check_matrix_trans(const GSparseMatrix& matrix,
  71 + const double& scale,
  72 + const double& offset) const;
  73 + bool check_matrix_lt(const GSparseMatrix& matrix,
  74 + const GSparseMatrix& ref) const;
  75 + bool check_matrix_ut(const GSparseMatrix& matrix,
  76 + const GSparseMatrix& ref) const;
  77 +
  78 + // Private members;
  79 + GSparseMatrix m_test; //!< Test matrix
  80 + GSparseMatrix m_bigger; //!< Bigger test matrix (for collisions)
  81 + GVector v_test; //!< Test vector
  82 +};
  83 +
  84 +#endif /* TEST_GSPARSEMATRIX_HPP */
... ...