Thyra Package Browser (Single Doxygen Collection) Version of the Day
Thyra_TestingTools.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines