|
Thyra Package Browser (Single Doxygen Collection) Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Thyra: Interfaces and Support for Abstract Numerical Algorithms 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 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #ifndef THYRA_TESTING_TOOLS_HPP 00030 #define THYRA_TESTING_TOOLS_HPP 00031 00032 #include "Thyra_TestingToolsDecl.hpp" 00033 #include "Thyra_VectorBase.hpp" 00034 #include "Thyra_VectorStdOps.hpp" 00035 #include "Thyra_LinearOpBase.hpp" 00036 #include "Thyra_AssertOp.hpp" 00037 #include "Teuchos_as.hpp" 00038 00039 00040 template <class Scalar> 00041 typename Teuchos::ScalarTraits<Scalar>::magnitudeType 00042 Thyra::relVectorErr( const VectorBase<Scalar> &v1, const VectorBase<Scalar> &v2 ) 00043 { 00044 typedef Teuchos::ScalarTraits<Scalar> ST; 00045 typedef typename ST::magnitudeType ScalarMag; 00046 #ifdef TEUCHOS_DEBUG 00047 THYRA_ASSERT_VEC_SPACES( "relErr(v1,v2)", *v1.space(), *v2.space() ); 00048 #endif 00049 RCP<VectorBase<Scalar> > 00050 diff = createMember(v1.space()); 00051 V_VmV( diff.ptr(), v1, v2 ); 00052 const ScalarMag 00053 nrm_v1 = norm(v1), 00054 nrm_v2 = norm(v2), 00055 nrm_diff = norm(*diff); 00056 return 00057 ( nrm_diff 00058 / ( 00059 ST::magnitude( 00060 Teuchos::RelErrSmallNumber<ST::hasMachineParameters,Scalar>::smallNumber() 00061 ) 00062 + std::max( nrm_v1, nrm_v2 ) 00063 ) 00064 ); 00065 } 00066 00067 00068 template<class Scalar1, class Scalar2, class ScalarMag> 00069 bool Thyra::testRelErrors( 00070 const int num_scalars 00071 ,const std::string &v1_name 00072 ,const Scalar1 v1[] 00073 ,const std::string &v2_name 00074 ,const Scalar2 v2[] 00075 ,const std::string &maxRelErr_error_name 00076 ,const ScalarMag &maxRelErr_error 00077 ,const std::string &maxRelErr_warning_name 00078 ,const ScalarMag &maxRelErr_warning 00079 ,std::ostream *out 00080 ,const std::string &li 00081 ) 00082 { 00083 using std::setw; 00084 typedef Teuchos::ScalarTraits<ScalarMag> SMT; 00085 typedef typename Teuchos::PromotionTraits<Scalar1,Scalar2>::promote Scalar; 00086 if(num_scalars==1) { 00087 return testRelErr<Scalar>( 00088 v1_name,v1[0],v2_name,v2[0] 00089 ,maxRelErr_error_name,maxRelErr_error 00090 ,maxRelErr_warning_name,maxRelErr_warning 00091 ,out,li 00092 ); 00093 } 00094 bool success = true; 00095 if(out) *out 00096 << std::endl 00097 << li << "Check: rel_err(" << v1_name << "," << v2_name << ") <= " << maxRelErr_error_name << " ?\n"; 00098 for( int i = 0; i < num_scalars; ++i ) { 00099 const ScalarMag rel_err = relErr<Scalar>( v1[i], v2[i] ); 00100 const bool result = ( !SMT::isnaninf(rel_err) && !SMT::isnaninf(maxRelErr_error) && rel_err <= maxRelErr_error ); 00101 if(!result) success = false; 00102 if(out) { 00103 *out 00104 << li << " "<<setw(2)<<i<<": rel_err("<<v1[i]<<","<<v2[i]<<") "<<"= "<<rel_err 00105 << " <= " << maxRelErr_error << " : " << passfail(result) << std::endl; 00106 if( result && rel_err >= maxRelErr_warning ) { 00107 *out 00108 << li << " Warning! rel_err(...) >= " << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n"; 00109 } 00110 } 00111 } 00112 return success; 00113 } 00114 00115 00116 template<class Scalar> 00117 bool Thyra::testRelNormDiffErr( 00118 const std::string &v1_name, 00119 const VectorBase<Scalar> &v1, 00120 const std::string &v2_name, 00121 const VectorBase<Scalar> &v2, 00122 const std::string &maxRelErr_error_name, 00123 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_error, 00124 const std::string &maxRelErr_warning_name, 00125 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_warning, 00126 std::ostream *out_inout, 00127 const Teuchos::EVerbosityLevel verbLevel, 00128 const std::string &li 00129 ) 00130 { 00131 using std::endl; 00132 using Teuchos::as; 00133 using Teuchos::OSTab; 00134 typedef Teuchos::ScalarTraits<Scalar> ST; 00135 typedef typename ST::magnitudeType ScalarMag; 00136 typedef Teuchos::ScalarTraits<ScalarMag> SMT; 00137 const RCP<FancyOStream> out = 00138 Teuchos::fancyOStream(Teuchos::rcp(out_inout, false)); 00139 const ScalarMag 00140 nrm_v1 = norm(v1), 00141 nrm_v2 = norm(v2); 00142 const ScalarMag rel_err = relVectorErr(v1,v2); 00143 const bool success = 00144 ( 00145 !SMT::isnaninf(rel_err) 00146 && !SMT::isnaninf(maxRelErr_error) 00147 && rel_err <= maxRelErr_error 00148 ); 00149 if (nonnull(out)) { 00150 *out 00151 << endl 00152 << li << "Testing relative error between vectors " 00153 << v1_name << " and " << v2_name << ":\n"; 00154 OSTab tab(out); 00155 *out 00156 << li << "||"<<v1_name<<"|| = " << nrm_v1 << endl 00157 << li << "||"<<v2_name<<"|| = " << nrm_v2 << endl; 00158 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) { 00159 *out 00160 << li << v1_name << " = " << describe(v1,verbLevel) 00161 << li << v2_name << " = " << describe(v2,verbLevel); 00162 RCP<VectorBase<Scalar> > diff = createMember(v1.space()); 00163 V_VmV( diff.ptr(), v1, v2 ); 00164 *out 00165 << li << v1_name << " - " << v2_name << " = " << describe(*diff,verbLevel); 00166 } 00167 *out 00168 << li << "Check: rel_err(" << v1_name << "," << v2_name << ") = " 00169 << rel_err << " <= " << maxRelErr_error_name << " = " 00170 << maxRelErr_error << " : " << passfail(success) << endl; 00171 if( success && rel_err >= maxRelErr_warning ) { 00172 *out 00173 << li << "Warning! rel_err(" << v1_name << "," << v2_name << " >= " 00174 << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n"; 00175 } 00176 } 00177 return success; 00178 } 00179 00180 00181 template<class Scalar> 00182 bool Thyra::testMaxErr( 00183 const std::string &error_name 00184 ,const Scalar &error 00185 ,const std::string &max_error_name 00186 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error 00187 ,const std::string &max_warning_name 00188 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning 00189 ,std::ostream *out 00190 ,const std::string &li 00191 ) 00192 { 00193 typedef Teuchos::ScalarTraits<Scalar> ST; 00194 typedef typename ST::magnitudeType ScalarMag; 00195 typedef Teuchos::ScalarTraits<ScalarMag> SMT; 00196 const ScalarMag error_mag = ST::magnitude(error); 00197 const bool success = ( 00198 !SMT::isnaninf(error_mag) 00199 && !SMT::isnaninf(max_error) 00200 && error_mag <= max_error ); 00201 if(out) { 00202 *out 00203 << std::endl 00204 << li << "Check: |" << error_name << "| = " << error_mag 00205 << " <= " << max_error_name << " = " << max_error << " : " 00206 << passfail(success) << std::endl; 00207 if( success && error_mag >= max_warning ) { 00208 *out 00209 << li << "Warning! " << error_name << " = " << error_mag 00210 << " >= " << max_warning_name << " = " << max_warning << "!\n"; 00211 } 00212 } 00213 return success; 00214 } 00215 00216 00217 template<class Scalar> 00218 bool Thyra::testMaxErrors( 00219 const int num_scalars 00220 ,const std::string &error_name 00221 ,const Scalar error[] 00222 ,const std::string &max_error_name 00223 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error 00224 ,const std::string &max_warning_name 00225 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning 00226 ,std::ostream *out 00227 ,const std::string &li 00228 ) 00229 { 00230 using std::setw; 00231 typedef Teuchos::ScalarTraits<Scalar> ST; 00232 typedef typename ST::magnitudeType ScalarMag; 00233 typedef Teuchos::ScalarTraits<ScalarMag> SMT; 00234 if(num_scalars==1) { 00235 return testMaxErr( 00236 error_name,error[0] 00237 ,max_error_name,max_error 00238 ,max_warning_name,max_warning 00239 ,out,li 00240 ); 00241 } 00242 bool success = true; 00243 if(out) *out 00244 << std::endl 00245 << li << "Check: |"<<error_name<<"| <= "<<max_error_name<<" ?\n"; 00246 for( int i = 0; i < num_scalars; ++i ) { 00247 const ScalarMag error_mag = ST::magnitude(error[i]); 00248 const bool result = ( 00249 !SMT::isnaninf(error_mag) 00250 && !SMT::isnaninf(max_error) 00251 && error_mag <= max_error ); 00252 if(!result) success = false; 00253 if(out) { 00254 *out 00255 << li << " "<<setw(2)<<i<<": |"<<error[i]<<"| = "<<error_mag<<" <= " 00256 <<max_error<<" : "<<passfail(success)<<"\n"; 00257 if( result && error_mag >= max_warning ) { 00258 *out 00259 << li << " Warning! |...| >= "<<max_warning_name<<" = "<<max_warning<<"!\n"; 00260 } 00261 } 00262 } 00263 return success; 00264 } 00265 00266 00267 template<class Scalar> 00268 std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v ) 00269 { 00270 return o << Teuchos::describe(v, Teuchos::VERB_EXTREME); 00271 } 00272 00273 00274 template<class Scalar> 00275 std::ostream& Thyra::operator<<( std::ostream& o, const LinearOpBase<Scalar>& M ) 00276 { 00277 return o << Teuchos::describe(M, Teuchos::VERB_EXTREME); 00278 } 00279 00280 00281 #endif // THYRA_TESTING_TOOLS_HPP
1.7.4