![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TEST_MGR_H 00024 #define O2SCL_TEST_MGR_H 00025 #include <string> 00026 #include <o2scl/string_conv.h> 00027 00028 #ifndef DOXYGENP 00029 namespace o2scl { 00030 #endif 00031 00032 /** \brief A class to manage testing and record success and failure 00033 00034 \future test_mgr::success and test_mgr::last_fail should be protected, 00035 but that breaks the operator+() function. Can this be fixed? 00036 */ 00037 class test_mgr { 00038 00039 protected: 00040 00041 #ifndef DOXYGEN_INTERNAL 00042 00043 /// The number of tests performed 00044 int ntests; 00045 00046 /// The output level 00047 int output_level; 00048 00049 /// A helper function for processing tests 00050 void process_test(bool ret, std::string d2, std::string description); 00051 00052 #endif 00053 00054 public: 00055 00056 test_mgr() { 00057 success=true; 00058 ntests=0; 00059 output_level=1; 00060 } 00061 00062 /** \brief Provide a report of all tests so far. 00063 00064 Returns true if all tests have passed and false if at least 00065 one test failed. 00066 */ 00067 bool report(); 00068 00069 /// Returns the description of the last test that failed. 00070 std::string get_last_fail() {return last_fail;}; 00071 00072 /** \brief Set the output level 00073 00074 Possible values: 00075 - 0 = No output 00076 - 1 = Output only tests that fail 00077 - 2 = Output all tests 00078 */ 00079 void set_output_level(int l) { output_level=l; }; 00080 00081 /// Return the number of tests performed so far 00082 int get_ntests() {return ntests;}; 00083 00084 /// \name The testing methods 00085 ///@{ 00086 00087 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00088 \mathrm{expected}<\mathrm{rel\_error}\f$ 00089 */ 00090 bool test_rel(double result, double expected, double rel_error, 00091 std::string description); 00092 00093 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00094 <\mathrm{abs\_error}\f$ 00095 */ 00096 bool test_abs(double result, double expected, double abs_error, 00097 std::string description); 00098 00099 /** \brief Test for \f$1/\mathrm{factor} < \mathrm{result/expected} 00100 < \mathrm{factor}\f$ 00101 */ 00102 bool test_fact(double result, double expected, double factor, 00103 std::string description); 00104 00105 /// Test for \f$\mathrm{result}=\mathrm{expected}\f$ 00106 bool test_str(std::string result, std::string expected, 00107 std::string description); 00108 00109 /// Test for \f$\mathrm{result}=\mathrm{expected}\f$ 00110 bool test_gen(bool value, std::string description); 00111 00112 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00113 \mathrm{expected}<\mathrm{rel\_error}\f$ over each element 00114 of an array 00115 */ 00116 template<class vec_t, class vec2_t> 00117 bool test_rel_arr(int nv, const vec_t &result, const vec2_t &expected, 00118 double rel_error, std::string description) { 00119 bool ret=true; 00120 double max=0.0; 00121 int i; 00122 00123 for(i=0;i<nv;i++) { 00124 if (isnan(expected[i])) { 00125 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00126 } else if (isinf(expected[i])) { 00127 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00128 } else if (expected[i]==0.0) { 00129 ret=(ret && test_abs(result[i],expected[i],rel_error,description)); 00130 if (fabs(result[i]-expected[i])>max) { 00131 max=fabs(result[i]-expected[i]); 00132 } 00133 } else { 00134 ret=(ret && ((fabs(expected[i]-result[i]))/ 00135 fabs(expected[i])<rel_error)); 00136 if (fabs(expected[i]-result[i])/fabs(expected[i])>max) { 00137 max=fabs(expected[i]-result[i])/fabs(expected[i]); 00138 } 00139 } 00140 } 00141 00142 process_test(ret,((std::string)"relative array, max=")+dtos(max), 00143 description); 00144 00145 return ret; 00146 00147 } 00148 00149 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00150 \mathrm{expected}<\mathrm{rel\_error}\f$ over each element 00151 of an array 00152 */ 00153 template<class mat_t, class mat2_t> 00154 bool test_rel_mat(int nr, int nc, const mat_t &result, 00155 const mat2_t &expected, 00156 double rel_error, std::string description) { 00157 bool ret=true; 00158 double max=0.0; 00159 int i, j; 00160 00161 for(i=0;i<nr;i++) { 00162 for(j=0;j<nc;j++) { 00163 if (isnan(expected[i][j])) { 00164 ret=(ret && (isnan(expected[i][j])==isnan(result[i][j]))); 00165 } else if (isinf(expected[i][j])) { 00166 ret=(ret && (isinf(expected[i][j])==isinf(result[i][j]))); 00167 } else if (expected[i][j]==0.0) { 00168 ret=(ret && test_abs(result[i][j],expected[i][j],rel_error, 00169 description)); 00170 if (fabs(result[i][j]-expected[i][j])>max) { 00171 max=fabs(result[i][j]-expected[i][j]); 00172 } 00173 } else { 00174 ret=(ret && ((fabs(expected[i][j]-result[i][j]))/ 00175 fabs(expected[i][j])<rel_error)); 00176 if (fabs(expected[i][j]-result[i][j])/fabs(expected[i][j])>max) { 00177 max=fabs(expected[i][j]-result[i][j])/fabs(expected[i][j]); 00178 } 00179 } 00180 } 00181 } 00182 00183 process_test(ret,((std::string)"relative matrix, max=")+dtos(max), 00184 description); 00185 00186 return ret; 00187 00188 } 00189 00190 /** \brief Test for \f$|\mathrm{result}-\mathrm{expected}|/ 00191 <\mathrm{abs\_error}\f$ over each element 00192 of an array 00193 */ 00194 template<class vec_t, class vec2_t> 00195 bool test_abs_arr(int nv, const vec_t &result, const vec2_t &expected, 00196 double rel_error, std::string description) { 00197 bool ret=true; 00198 int i; 00199 00200 for(i=0;i<nv;i++) { 00201 if (isnan(expected[i])) { 00202 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00203 } else if (isinf(expected[i])) { 00204 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00205 } else { 00206 ret=(ret && (fabs(expected[i]-result[i])<rel_error)); 00207 } 00208 } 00209 00210 process_test(ret,"absolute array",description); 00211 00212 return ret; 00213 } 00214 00215 /** \brief Test for \f$ 1/factor < result/expected < factor \f$ 00216 over each element of an array 00217 */ 00218 template<class vec_t, class vec2_t> 00219 bool test_fact_arr(int nv, const vec_t &result, const vec2_t &expected, 00220 double factor, std::string description) { 00221 bool ret=true; 00222 int i; 00223 double ratio; 00224 00225 for(i=0;i<nv;i++) { 00226 if (isnan(expected[i])) { 00227 ret=(ret && (isnan(expected[i])==isnan(result[i]))); 00228 } else if (isinf(expected[i])) { 00229 ret=(ret && (isinf(expected[i])==isinf(result[i]))); 00230 } else { 00231 ratio=expected[i]/result[i]; 00232 ret=(ret && (ratio<factor && ratio>1.0/factor)); 00233 } 00234 } 00235 00236 process_test(ret,"factor array",description); 00237 00238 return ret; 00239 } 00240 00241 /// Test for equality of a generic array 00242 template<class vec_t> 00243 bool test_gen_arr(int nv, const vec_t &result, const vec_t &expected, 00244 std::string description) { 00245 bool ret=true; 00246 int i; 00247 00248 for(i=0;i<nv;i++) { 00249 ret=(ret && (result[i]==expected[i])); 00250 } 00251 00252 process_test(ret,"generic array",description); 00253 00254 return ret; 00255 } 00256 ///@} 00257 00258 /// Add two test_mgr objects (if either failed, the sum fails) 00259 friend const test_mgr operator+(const test_mgr& left, 00260 const test_mgr& right); 00261 00262 /// True if all tests have passed 00263 bool success; 00264 00265 /// The description of the last failed test 00266 std::string last_fail; 00267 00268 }; 00269 00270 #ifndef DOXYGENP 00271 } 00272 #endif 00273 00274 #endif
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).