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   Teuchos::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,
00127   const Teuchos::EVerbosityLevel verbLevel,
00128   const std::string &li
00129   )
00130 {
00131   using std::endl;
00132   using Teuchos::as;
00133   typedef Teuchos::ScalarTraits<Scalar> ST;
00134   typedef typename ST::magnitudeType ScalarMag;
00135   typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00136   const ScalarMag
00137     nrm_v1 = norm(v1),
00138     nrm_v2 = norm(v2);
00139   const ScalarMag rel_err = relVectorErr(v1,v2);
00140   const bool success =
00141     (
00142       !SMT::isnaninf(rel_err)
00143       && !SMT::isnaninf(maxRelErr_error)
00144       && rel_err <= maxRelErr_error
00145       );
00146   if(out) {
00147     *out
00148       << endl
00149       << li << "Testing relative error between vectors " << v1_name << " and " << v2_name << ":\n"
00150       << li << "  ||"<<v1_name<<"|| = " << nrm_v1 << endl
00151       << li << "  ||"<<v2_name<<"|| = " << nrm_v2 << endl;
00152     if ( as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH) ) {
00153       *out
00154         << li << "  " << v1_name << " = " << describe(v1,verbLevel)
00155         << li << "  " << v2_name << " = " << describe(v2,verbLevel);
00156       Teuchos::RCP<VectorBase<Scalar> >
00157         diff = createMember(v1.space());
00158       V_VmV( &*diff, v1, v2 );
00159       *out
00160         << li << "  " << v1_name << " - " << v2_name << " = " << describe(*diff,verbLevel);
00161     }
00162     *out
00163       << li << "  Check: rel_err(" << v1_name << "," << v2_name << ") = "
00164       << rel_err << " <= " << maxRelErr_error_name << " = " << maxRelErr_error << " : " << passfail(success) << endl;
00165     if( success && rel_err >= maxRelErr_warning ) {
00166       *out
00167         << li << "  Warning! rel_err(" << v1_name << "," << v2_name << " >= "
00168         << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
00169     }
00170   }
00171   return success;
00172 }
00173 
00174 
00175 template<class Scalar>
00176 bool Thyra::testMaxErr(
00177   const std::string                                             &error_name
00178   ,const Scalar                                                 &error
00179   ,const std::string                                            &max_error_name
00180   ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType  &max_error
00181   ,const std::string                                            &max_warning_name
00182   ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType  &max_warning
00183   ,std::ostream                                                 *out
00184   ,const std::string                                            &li
00185   )
00186 {
00187   typedef Teuchos::ScalarTraits<Scalar> ST;
00188   typedef typename ST::magnitudeType ScalarMag;
00189   typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00190   const ScalarMag error_mag = ST::magnitude(error);
00191   const bool success = ( !SMT::isnaninf(error_mag) && !SMT::isnaninf(max_error) && error_mag <= max_error );
00192   if(out) {
00193     *out
00194       << std::endl
00195       << li << "Check: |" << error_name << "| = " << error_mag
00196       << " <= " << max_error_name << " = " << max_error << " : " << passfail(success) << std::endl;
00197     if( success && error_mag >= max_warning ) {
00198       *out
00199         << li << "Warning! " << error_name << " = " << error_mag
00200         << " >= " << max_warning_name << " = " << max_warning << "!\n";
00201     }
00202   }
00203   return success;
00204 }
00205 
00206 template<class Scalar>
00207 bool Thyra::testMaxErrors(
00208   const int                                                     num_scalars
00209   ,const std::string                                            &error_name
00210   ,const Scalar                                                 error[]
00211   ,const std::string                                            &max_error_name
00212   ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType  &max_error
00213   ,const std::string                                            &max_warning_name
00214   ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType  &max_warning
00215   ,std::ostream                                                 *out
00216   ,const std::string                                            &li
00217   )
00218 {
00219   using std::setw;
00220   typedef Teuchos::ScalarTraits<Scalar> ST;
00221   typedef typename ST::magnitudeType ScalarMag;
00222   typedef Teuchos::ScalarTraits<ScalarMag> SMT;
00223   if(num_scalars==1) {
00224     return testMaxErr(
00225       error_name,error[0]
00226       ,max_error_name,max_error
00227       ,max_warning_name,max_warning
00228       ,out,li
00229       );
00230   }
00231   bool success = true;
00232   if(out) *out
00233     << std::endl
00234     << li << "Check: |"<<error_name<<"| <= "<<max_error_name<<" ?\n";
00235   for( int i = 0; i < num_scalars; ++i ) {
00236     const ScalarMag error_mag = ST::magnitude(error[i]);
00237     const bool result = ( !SMT::isnaninf(error_mag) && !SMT::isnaninf(max_error) && error_mag <= max_error );
00238     if(!result) success = false;
00239     if(out) {
00240       *out
00241         << li << "  "<<setw(2)<<i<<": |"<<error[i]<<"| = "<<error_mag<<" <= "<<max_error<<" : "<<passfail(success)<<"\n";
00242       if( result && error_mag >= max_warning ) {
00243         *out
00244           << li << "      Warning! |...| >= "<<max_warning_name<<" = "<<max_warning<<"!\n";
00245       }
00246     }
00247   }
00248   return success;
00249 }
00250 
00251 template<class Scalar>
00252 std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
00253 {
00254   return o << Teuchos::describe(v,Teuchos::VERB_EXTREME);
00255 }
00256 
00257 template<class Scalar>
00258 std::ostream& Thyra::operator<<( std::ostream& o, const LinearOpBase<Scalar>& M )
00259 {
00260   return o << Teuchos::describe(M,Teuchos::VERB_EXTREME);
00261 }
00262 
00263 #endif // THYRA_TESTING_TOOLS_HPP

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