00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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, 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 " << v1_name << " and " << v2_name << ":\n";
00153 OSTab tab(out);
00154 *out
00155 << li << "||"<<v1_name<<"|| = " << nrm_v1 << endl
00156 << li << "||"<<v2_name<<"|| = " << nrm_v2 << endl;
00157 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
00158 *out
00159 << li << v1_name << " = " << describe(v1,verbLevel)
00160 << li << v2_name << " = " << describe(v2,verbLevel);
00161 RCP<VectorBase<Scalar> > diff = createMember(v1.space());
00162 V_VmV( &*diff, v1, v2 );
00163 *out
00164 << li << v1_name << " - " << v2_name << " = " << describe(*diff,verbLevel);
00165 }
00166 *out
00167 << li << "Check: rel_err(" << v1_name << "," << v2_name << ") = "
00168 << rel_err << " <= " << maxRelErr_error_name << " = " << maxRelErr_error << " : " << passfail(success) << endl;
00169 if( success && rel_err >= maxRelErr_warning ) {
00170 *out
00171 << li << "Warning! rel_err(" << v1_name << "," << v2_name << " >= "
00172 << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
00173 }
00174 }
00175 return success;
00176 }
00177
00178
00179 template<class Scalar>
00180 bool Thyra::testMaxErr(
00181 const std::string &error_name
00182 ,const Scalar &error
00183 ,const std::string &max_error_name
00184 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error
00185 ,const std::string &max_warning_name
00186 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning
00187 ,std::ostream *out
00188 ,const std::string &li
00189 )
00190 {
00191 typedef Teuchos::ScalarTraits<Scalar> ST;
00192 typedef typename ST::magnitudeType ScalarMag;
00193 typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00194 const ScalarMag error_mag = ST::magnitude(error);
00195 const bool success = ( !SMT::isnaninf(error_mag) && !SMT::isnaninf(max_error) && error_mag <= max_error );
00196 if(out) {
00197 *out
00198 << std::endl
00199 << li << "Check: |" << error_name << "| = " << error_mag
00200 << " <= " << max_error_name << " = " << max_error << " : " << passfail(success) << std::endl;
00201 if( success && error_mag >= max_warning ) {
00202 *out
00203 << li << "Warning! " << error_name << " = " << error_mag
00204 << " >= " << max_warning_name << " = " << max_warning << "!\n";
00205 }
00206 }
00207 return success;
00208 }
00209
00210 template<class Scalar>
00211 bool Thyra::testMaxErrors(
00212 const int num_scalars
00213 ,const std::string &error_name
00214 ,const Scalar error[]
00215 ,const std::string &max_error_name
00216 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error
00217 ,const std::string &max_warning_name
00218 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning
00219 ,std::ostream *out
00220 ,const std::string &li
00221 )
00222 {
00223 using std::setw;
00224 typedef Teuchos::ScalarTraits<Scalar> ST;
00225 typedef typename ST::magnitudeType ScalarMag;
00226 typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00227 if(num_scalars==1) {
00228 return testMaxErr(
00229 error_name,error[0]
00230 ,max_error_name,max_error
00231 ,max_warning_name,max_warning
00232 ,out,li
00233 );
00234 }
00235 bool success = true;
00236 if(out) *out
00237 << std::endl
00238 << li << "Check: |"<<error_name<<"| <= "<<max_error_name<<" ?\n";
00239 for( int i = 0; i < num_scalars; ++i ) {
00240 const ScalarMag error_mag = ST::magnitude(error[i]);
00241 const bool result = ( !SMT::isnaninf(error_mag) && !SMT::isnaninf(max_error) && error_mag <= max_error );
00242 if(!result) success = false;
00243 if(out) {
00244 *out
00245 << li << " "<<setw(2)<<i<<": |"<<error[i]<<"| = "<<error_mag<<" <= "<<max_error<<" : "<<passfail(success)<<"\n";
00246 if( result && error_mag >= max_warning ) {
00247 *out
00248 << li << " Warning! |...| >= "<<max_warning_name<<" = "<<max_warning<<"!\n";
00249 }
00250 }
00251 }
00252 return success;
00253 }
00254
00255 template<class Scalar>
00256 std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
00257 {
00258 return o << Teuchos::describe(v, Teuchos::VERB_EXTREME);
00259 }
00260
00261 template<class Scalar>
00262 std::ostream& Thyra::operator<<( std::ostream& o, const LinearOpBase<Scalar>& M )
00263 {
00264 return o << Teuchos::describe(M, Teuchos::VERB_EXTREME);
00265 }
00266
00267 #endif // THYRA_TESTING_TOOLS_HPP