|
Teuchos Package Browser (Single Doxygen Collection)
Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Teuchos: Common Tools Package 00005 // Copyright (2004) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // Redistribution and use in source and binary forms, with or without 00011 // modification, are permitted provided that the following conditions are 00012 // met: 00013 // 00014 // 1. Redistributions of source code must retain the above copyright 00015 // notice, this list of conditions and the following disclaimer. 00016 // 00017 // 2. Redistributions in binary form must reproduce the above copyright 00018 // notice, this list of conditions and the following disclaimer in the 00019 // documentation and/or other materials provided with the distribution. 00020 // 00021 // 3. Neither the name of the Corporation nor the names of the 00022 // contributors may be used to endorse or promote products derived from 00023 // this software without specific prior written permission. 00024 // 00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 // 00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 // @HEADER 00041 00042 #ifndef TEUCHOS_TESTING_HELPERS_HPP 00043 #define TEUCHOS_TESTING_HELPERS_HPP 00044 00045 00051 #include "Teuchos_ConfigDefs.hpp" 00052 #include "Teuchos_ScalarTraits.hpp" 00053 #include "Teuchos_TypeNameTraits.hpp" 00054 #include "Teuchos_FancyOStream.hpp" 00055 00056 00057 namespace Teuchos { 00058 00059 00064 inline void updateSuccess(const bool result, bool &success); 00065 00066 00071 inline const std::string passfail(const bool result); 00072 00073 00078 TEUCHOS_LIB_DLL_EXPORT const std::string passfail_with_location(const bool result, const std::string &file, const int lineNumber); 00079 00084 void showTestFailureLocation(bool); 00085 00086 00091 bool showTestFailureLocation(); 00092 00093 00098 template <bool hasMachineParameters, class Scalar> 00099 class RelErrSmallNumber { 00100 public: 00101 static Scalar smallNumber() 00102 { 00103 return ScalarTraits<Scalar>::ThisShouldNotCompile(); 00104 } 00105 }; 00106 00107 00112 template <class Scalar> 00113 class RelErrSmallNumber<false,Scalar> { 00114 public: 00115 static Scalar smallNumber() 00116 { 00117 return Scalar(1e-8); 00118 } 00119 }; 00120 00121 00126 template <class Scalar> 00127 class RelErrSmallNumber<true,Scalar> { 00128 public: 00129 static Scalar smallNumber() 00130 { 00131 return Teuchos::ScalarTraits<Scalar>::eps(); 00132 } 00133 }; 00134 00135 00140 template <class Scalar> 00141 Scalar defaultSmallNumber() 00142 { 00143 const bool hasMachineParameters = ScalarTraits<Scalar>::hasMachineParameters; 00144 return RelErrSmallNumber<hasMachineParameters,Scalar>::smallNumber(); 00145 } 00146 00147 00154 template <class Scalar> 00155 typename ScalarTraits<Scalar>::magnitudeType 00156 relErr( const Scalar &s1, const Scalar &s2 ); 00157 00158 00165 template<class Scalar> 00166 bool testRelErr( 00167 const std::string &v1_name, 00168 const Scalar &v1, 00169 const std::string &v2_name, 00170 const Scalar &v2, 00171 const std::string &maxRelErr_error_name, 00172 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_error, 00173 const std::string &maxRelErr_warning_name, 00174 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_warning, 00175 const Ptr<std::ostream> &out 00176 ); 00177 00178 00190 template<class Array1, class Array2> 00191 bool compareArrays( 00192 const Array1 &a1, const std::string &a1_name, 00193 const Array2 &a2, const std::string &a2_name, 00194 Teuchos::FancyOStream &out 00195 ); 00196 00197 00210 template<class Array1, class Array2, class ScalarMag> 00211 bool compareFloatingArrays( 00212 const Array1 &a1, const std::string &a1_name, 00213 const Array2 &a2, const std::string &a2_name, 00214 const ScalarMag &tol, 00215 Teuchos::FancyOStream &out 00216 ); 00217 00218 00219 } // namespace Teuchos 00220 00221 00230 #define TEUCHOS_PASS_FAIL(RESULT) \ 00231 Teuchos::passfail_with_location((RESULT), __FILE__, __LINE__) 00232 00233 00240 #define TEUCHOS_ECHO( statement, out ) \ 00241 (out) << #statement ";\n"; \ 00242 statement; 00243 00250 #define TEUCHOS_TEST_EQUALITY_CONST( v1, v2, out, success ) \ 00251 { \ 00252 (out) << #v1" = "<<Teuchos::toString(v1)<<" == "<<Teuchos::toString(v2)<<" : "; \ 00253 const bool l_result = (v1) == (v2); \ 00254 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00255 if (!l_result) (success) = false; \ 00256 } 00257 00264 #define TEUCHOS_TEST_ASSERT( v1, out, success ) \ 00265 { \ 00266 const bool l_result = v1; \ 00267 (out) << #v1" = "<<l_result<<" == true : "; \ 00268 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00269 if (!l_result) (success) = false; \ 00270 } 00271 00278 #define TEUCHOS_TEST_EQUALITY( v1, v2, out, success ) \ 00279 { \ 00280 (out) << #v1" = "<<Teuchos::toString(v1)<<" == "#v2" = "<<Teuchos::toString(v2)<<" : "; \ 00281 const bool l_result = (v1) == (v2); \ 00282 if (!l_result) (success) = false; \ 00283 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00284 } 00285 00286 00293 #define TEUCHOS_TEST_INEQUALITY_CONST( v1, v2, out, success ) \ 00294 { \ 00295 (out) << #v1" = "<<Teuchos::toString(v1)<<" != "<<Teuchos::toString(v2)<<" : "; \ 00296 const bool l_result = (v1) != (v2); \ 00297 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00298 if (!l_result) (success) = false; \ 00299 } 00300 00301 00308 #define TEUCHOS_TEST_INEQUALITY( v1, v2, out, success ) \ 00309 { \ 00310 (out) << #v1" = "<<Teuchos::toString(v1)<<" != "#v2" = "<<Teuchos::toString(v2)<<" : "; \ 00311 const bool l_result = (v1) != (v2); \ 00312 if (!l_result) (success) = false; \ 00313 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00314 } 00315 00316 00323 #define TEUCHOS_TEST_FLOATING_EQUALITY( v1, v2, tol, out, success ) \ 00324 { \ 00325 const bool l_result = Teuchos::testRelErr( \ 00326 #v1, v1, #v2, v2, "tol", tol, "tol", tol, Teuchos::outArg(out) ); \ 00327 if (!l_result) (success) = false; \ 00328 } 00329 00330 00340 #define TEUCHOS_TEST_ITER_EQUALITY( iter1, iter2, out, success ) \ 00341 { \ 00342 (out) << #iter1" == "#iter2" = : "; \ 00343 const bool l_result = (iter1) == (iter2); \ 00344 if (!l_result) (success) = false; \ 00345 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00346 } 00347 00348 00358 #define TEUCHOS_TEST_ITER_INEQUALITY( iter1, iter2, out, success ) \ 00359 { \ 00360 (out) << #iter1" != "#iter2" = : "; \ 00361 const bool l_result = (iter1) != (iter2); \ 00362 if (!l_result) (success) = false; \ 00363 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00364 } 00365 00366 00373 #define TEUCHOS_TEST_ARRAY_ELE_EQUALITY( a, i, val, printPass, out, success ) \ 00374 { \ 00375 const bool l_result = ( (a)[i] == (val) ); \ 00376 if (!l_result) (success) = false; \ 00377 if (printPass || !(l_result)) { \ 00378 out << #a"["<<i<<"] = " << Teuchos::toString((a)[i]) << " == "#val" = " << Teuchos::toString(val) \ 00379 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00380 } \ 00381 } 00382 00383 00390 #define TEUCHOS_TEST_ARRAY_ELE_INEQUALITY( a, i, val, printPass, out, success ) \ 00391 { \ 00392 const bool l_result = ( (a)[i] != (val) ); \ 00393 if (!l_result) (success) = false; \ 00394 if (printPass || !(l_result)) { \ 00395 out << #a"["<<i<<"] = " << Teuchos::toString((a)[i]) << " != "#val" = " << Teuchos::toString(val) \ 00396 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00397 } \ 00398 } 00399 00400 00408 #define TEUCHOS_TEST_MATRIX_ELE_FLOATING_EQUALITY( a, i, j, val, tol, printPass, out, success ) \ 00409 { \ 00410 std::ostringstream a_i_str; \ 00411 a_i_str <<#a<<"("<<i<<","<<j<<")"; \ 00412 const bool l_result = Teuchos::testRelErr( \ 00413 a_i_str.str(), (a)(i,j), #val, val, "tol", tol, "tol", tol, \ 00414 (printPass) ? Teuchos::outArg(out) : Teuchos::null ); \ 00415 if (!l_result) (success) = false; \ 00416 } 00417 00418 00425 #define TEUCHOS_TEST_MATRIX_ELE_EQUALITY( a, i, j, val, printPass, out, success ) \ 00426 { \ 00427 const bool l_result = ( (a)(i,j) == (val) ); \ 00428 if (!l_result) (success) = false; \ 00429 if (printPass || !(l_result)) { \ 00430 out << #a"("<<i<<","<<j<<") = " << (a)(i,j) << " == "#val" = " << (val) \ 00431 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00432 } \ 00433 } 00434 00435 00442 #define TEUCHOS_TEST_COMPARE( v1, comp, v2, out, success ) \ 00443 { \ 00444 out << #v1" = "<<(v1)<<" "#comp" "#v2" = "<<(v2)<<" : "; \ 00445 const bool l_result = (v1) comp (v2); \ 00446 if (!l_result) (success) = false; \ 00447 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 00448 } 00449 00450 00457 #define TEUCHOS_TEST_THROW( code, ExceptType, out, success ) \ 00458 try { \ 00459 (out) << "Test that code {"#code";} throws " \ 00460 <<Teuchos::TypeNameTraits<ExceptType>::name()<<": "; \ 00461 code; \ 00462 (success) = false; \ 00463 (out) << "failed\n"; \ 00464 } \ 00465 catch (const ExceptType& except) { \ 00466 out << "passed\n"; \ 00467 out << "\nException message for expected exception:\n\n"; \ 00468 { \ 00469 Teuchos::OSTab l_tab(out); \ 00470 out << except.what() << "\n\n"; \ 00471 } \ 00472 } 00473 00474 00481 #define TEUCHOS_TEST_NOTHROW( code, out, success ) \ 00482 try { \ 00483 (out) << "Test that code {"#code";} does not throw : "; \ 00484 code; \ 00485 (out) << "passes\n"; \ 00486 } \ 00487 catch (...) { \ 00488 (success) = false; \ 00489 out << "failed\n"; \ 00490 } 00491 00492 00493 // 00494 // Implementations 00495 // 00496 00497 00498 inline 00499 void Teuchos::updateSuccess(const bool result, bool &success) 00500 { 00501 if (!result) success = false; 00502 } 00503 00504 00505 inline 00506 const std::string 00507 Teuchos::passfail(const bool result) 00508 { 00509 if (!result) 00510 return "FAILED"; 00511 return "passed"; 00512 } 00513 00514 00515 template <class Scalar> 00516 typename Teuchos::ScalarTraits<Scalar>::magnitudeType 00517 Teuchos::relErr( const Scalar &s1, const Scalar &s2 ) 00518 { 00519 typedef Teuchos::ScalarTraits<Scalar> ST; 00520 return 00521 ST::magnitude( s1 - s2 ) 00522 / ( 00523 ST::magnitude( 00524 RelErrSmallNumber<ST::hasMachineParameters,Scalar>::smallNumber() 00525 ) 00526 + std::max( ST::magnitude(s1), ST::magnitude(s2) ) 00527 ); 00528 } 00529 00530 00531 template<class Scalar> 00532 bool Teuchos::testRelErr( 00533 const std::string &v1_name, 00534 const Scalar &v1, 00535 const std::string &v2_name, 00536 const Scalar &v2, 00537 const std::string &maxRelErr_error_name, 00538 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_error, 00539 const std::string &maxRelErr_warning_name, 00540 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_warning, 00541 const Ptr<std::ostream> &out 00542 ) 00543 { 00544 using std::endl; 00545 typedef ScalarTraits<Scalar> ST; 00546 typedef typename ST::magnitudeType ScalarMag; 00547 typedef ScalarTraits<ScalarMag> SMT; 00548 const ScalarMag rel_err = relErr( v1, v2 ); 00549 const bool success = ( !SMT::isnaninf(rel_err) && !SMT::isnaninf(maxRelErr_error) 00550 && rel_err <= maxRelErr_error ); 00551 if (!is_null(out)) { 00552 *out 00553 << endl 00554 << "Check: rel_err(" << v1_name << ", " << v2_name << ")\n" 00555 << " = rel_err(" << v1 << ", " << v2 << ") " 00556 << "= " << rel_err << endl 00557 << " <= " << maxRelErr_error_name 00558 << " = " << maxRelErr_error << " : " << passfail(success) << endl; 00559 if( success && rel_err >= maxRelErr_warning ) { 00560 *out 00561 << "Warning! rel_err(" << v1_name << ", " << v2_name << ")\n" 00562 << " = rel_err(" << v1 << ", " << v2 << ") " 00563 << "= " << rel_err << endl 00564 << " >= " << maxRelErr_warning_name 00565 << " = " << maxRelErr_warning << "!\n"; 00566 } 00567 } 00568 return success; 00569 } 00570 00571 00572 template<class Array1, class Array2> 00573 bool Teuchos::compareArrays( 00574 const Array1 &a1, const std::string &a1_name, 00575 const Array2 &a2, const std::string &a2_name, 00576 Teuchos::FancyOStream &out 00577 ) 00578 { 00579 using Teuchos::as; 00580 bool success = true; 00581 00582 out << "Comparing " << a1_name << " == " << a2_name << " ... "; 00583 00584 const int n = a1.size(); 00585 00586 // Compare sizes 00587 if (as<int>(a2.size()) != n) { 00588 out << "\nError, "<<a1_name<<".size() = "<<a1.size()<<" == " 00589 << a2_name<<".size() = "<<a2.size()<<" : failed!\n"; 00590 return false; 00591 } 00592 00593 // Compare elements 00594 for( int i = 0; i < n; ++i ) { 00595 const bool result = ( a1[i] == a2[i] ); // Tests C::operator[](i) const 00596 if (!result) { 00597 out << "\nError, "<<a1_name<<"["<<i<<"] = "<<a1[i]<<" == " 00598 << a2_name<<"["<<i<<"] = "<<a2[i]<<": failed!\n"; 00599 success = false; 00600 } 00601 } 00602 if (success) { 00603 out << "passed\n"; 00604 } 00605 00606 return success; 00607 00608 } 00609 00610 00611 template<class Array1, class Array2, class ScalarMag> 00612 bool Teuchos::compareFloatingArrays( 00613 const Array1 &a1, const std::string &a1_name, 00614 const Array2 &a2, const std::string &a2_name, 00615 const ScalarMag &tol, 00616 Teuchos::FancyOStream &out 00617 ) 00618 { 00619 using Teuchos::as; 00620 bool success = true; 00621 00622 out << "Comparing " << a1_name << " == " << a2_name << " ... "; 00623 00624 const int n = a1.size(); 00625 00626 // Compare sizes 00627 if (as<int>(a2.size()) != n) { 00628 out << "\nError, "<<a1_name<<".size() = "<<a1.size()<<" == " 00629 << a2_name<<".size() = "<<a2.size()<<" : failed!\n"; 00630 return false; 00631 } 00632 00633 // Compare elements 00634 for( int i = 0; i < n; ++i ) { 00635 const ScalarMag err = relErr( a1[i], a2[i] ); 00636 if ( err > tol ) { 00637 out 00638 <<"\nError, relErr("<<a1_name<<"["<<i<<"]," 00639 <<a2_name<<"["<<i<<"]) = relErr("<<a1[i]<<","<<a2[i]<<") = " 00640 <<err<<" <= tol = "<<tol<<": failed!\n"; 00641 success = false; 00642 } 00643 } 00644 if (success) { 00645 out << "passed\n"; 00646 } 00647 00648 return success; 00649 00650 } 00651 00652 00653 #endif // TEUCHOS_TESTING_HELPERS_HPP
1.7.6.1