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