Thyra_TestingTools.hpp

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, 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

Generated on Wed May 12 21:26:54 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7