Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_TestingTools.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Thyra: Interfaces and Support for Abstract Numerical Algorithms
4 //
5 // Copyright 2004 NTESS and the Thyra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef THYRA_TESTING_TOOLS_HPP
11 #define THYRA_TESTING_TOOLS_HPP
12 
13 #include "Thyra_TestingToolsDecl.hpp"
14 #include "Thyra_VectorBase.hpp"
15 #include "Thyra_VectorStdOps.hpp"
16 #include "Thyra_LinearOpBase.hpp"
17 #include "Thyra_AssertOp.hpp"
18 #include "Teuchos_as.hpp"
19 
20 
21 template <class Scalar>
24 {
26  typedef typename ST::magnitudeType ScalarMag;
27 #ifdef TEUCHOS_DEBUG
28  THYRA_ASSERT_VEC_SPACES( "relErr(v1,v2)", *v1.space(), *v2.space() );
29 #endif
31  diff = createMember(v1.space());
32  V_VmV( diff.ptr(), v1, v2 );
33  const ScalarMag
34  nrm_v1 = norm(v1),
35  nrm_v2 = norm(v2),
36  nrm_diff = norm(*diff);
37  return
38  ( nrm_diff
39  / (
40  ST::magnitude(
42  )
43  + std::max( nrm_v1, nrm_v2 )
44  )
45  );
46 }
47 
48 
49 template<class Scalar1, class Scalar2, class ScalarMag>
51  const std::string &v1_name,
52  const ArrayView<const Scalar1> &v1,
53  const std::string &v2_name,
54  const ArrayView<const Scalar2> &v2,
55  const std::string &maxRelErr_error_name,
56  const ScalarMag &maxRelErr_error,
57  const std::string &maxRelErr_warning_name,
58  const ScalarMag &maxRelErr_warning,
59  const Ptr<std::ostream> &out,
60  const std::string &li
61  )
62 {
63  using std::setw;
65  typedef typename Teuchos::PromotionTraits<Scalar1,Scalar2>::promote Scalar;
66 
67  TEUCHOS_ASSERT_EQUALITY(v1.size(), v2.size());
68  const int num_scalars = v1.size();
69 
70  if(num_scalars==1) {
71  return Teuchos::testRelErr<Scalar>(
72  v1_name, v1[0], v2_name, v2[0],
73  maxRelErr_error_name, maxRelErr_error,
74  maxRelErr_warning_name, maxRelErr_warning,
75  out
76  );
77  }
78 
79  bool success = true;
80 
81  if (nonnull(out)) *out
82  << std::endl
83  << li << "Check: rel_err(" << v1_name << "," << v2_name << ") <= " << maxRelErr_error_name << " ?\n";
84 
85  for( int i = 0; i < num_scalars; ++i ) {
86  const ScalarMag rel_err = relErr<Scalar>( v1[i], v2[i] );
87  const bool result = ( !SMT::isnaninf(rel_err) && !SMT::isnaninf(maxRelErr_error) && rel_err <= maxRelErr_error );
88  if(!result) success = false;
89  if(nonnull(out)) {
90  *out
91  << li << " "<<setw(2)<<i<<": rel_err("<<v1[i]<<","<<v2[i]<<") "<<"= "<<rel_err
92  << " <= " << maxRelErr_error << " : " << passfail(result) << std::endl;
93  if( result && rel_err >= maxRelErr_warning ) {
94  *out
95  << li << " Warning! rel_err(...) >= " << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
96  }
97  }
98  }
99 
100  return success;
101 
102 }
103 
104 
105 template<class Scalar>
107  const std::string &v1_name,
108  const VectorBase<Scalar> &v1,
109  const std::string &v2_name,
110  const VectorBase<Scalar> &v2,
111  const std::string &maxRelErr_error_name,
112  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_error,
113  const std::string &maxRelErr_warning_name,
114  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_warning,
115  std::ostream *out_inout,
116  const Teuchos::EVerbosityLevel verbLevel,
117  const std::string &li
118  )
119 {
120  using std::endl;
121  using Teuchos::as;
122  using Teuchos::OSTab;
124  typedef typename ST::magnitudeType ScalarMag;
126  const RCP<FancyOStream> out =
127  Teuchos::fancyOStream(Teuchos::rcp(out_inout, false));
128  const ScalarMag
129  nrm_v1 = norm(v1),
130  nrm_v2 = norm(v2);
131  const ScalarMag rel_err = relVectorErr(v1,v2);
132  const bool success =
133  (
134  !SMT::isnaninf(rel_err)
135  && !SMT::isnaninf(maxRelErr_error)
136  && rel_err <= maxRelErr_error
137  );
138  if (nonnull(out)) {
139  *out
140  << endl
141  << li << "Testing relative error between vectors "
142  << v1_name << " and " << v2_name << ":\n";
143  OSTab tab(out);
144  *out
145  << li << "||"<<v1_name<<"|| = " << nrm_v1 << endl
146  << li << "||"<<v2_name<<"|| = " << nrm_v2 << endl;
147  if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
148  *out
149  << li << v1_name << " = " << describe(v1,verbLevel)
150  << li << v2_name << " = " << describe(v2,verbLevel);
152  V_VmV( diff.ptr(), v1, v2 );
153  *out
154  << li << v1_name << " - " << v2_name << " = " << describe(*diff,verbLevel);
155  }
156  *out
157  << li << "Check: rel_err(" << v1_name << "," << v2_name << ") = "
158  << rel_err << " <= " << maxRelErr_error_name << " = "
159  << maxRelErr_error << " : " << passfail(success) << endl;
160  if( success && rel_err >= maxRelErr_warning ) {
161  *out
162  << li << "Warning! rel_err(" << v1_name << "," << v2_name << " >= "
163  << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
164  }
165  }
166  return success;
167 }
168 
169 
170 template<class Scalar>
172  const std::string &error_name
173  ,const Scalar &error
174  ,const std::string &max_error_name
175  ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error
176  ,const std::string &max_warning_name
177  ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning
178  ,std::ostream *out
179  ,const std::string &li
180  )
181 {
183  typedef typename ST::magnitudeType ScalarMag;
185  const ScalarMag error_mag = ST::magnitude(error);
186  const bool success = (
187  !SMT::isnaninf(error_mag)
188  && !SMT::isnaninf(max_error)
189  && error_mag <= max_error );
190  if(out) {
191  *out
192  << std::endl
193  << li << "Check: |" << error_name << "| = " << error_mag
194  << " <= " << max_error_name << " = " << max_error << " : "
195  << passfail(success) << std::endl;
196  if( success && error_mag >= max_warning ) {
197  *out
198  << li << "Warning! " << error_name << " = " << error_mag
199  << " >= " << max_warning_name << " = " << max_warning << "!\n";
200  }
201  }
202  return success;
203 }
204 
205 
206 template<class Scalar>
208  const std::string &error_name,
209  const ArrayView<const typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &errors,
210  const std::string &max_error_name,
211  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error,
212  const std::string &max_warning_name,
213  const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning,
214  const Ptr<std::ostream> &out,
215  const std::string &li
216  )
217 {
218  using std::setw;
220  typedef typename ST::magnitudeType ScalarMag;
222 
223  const int num_scalars = errors.size();
224 
225  if(num_scalars==1) {
226  return testMaxErr<Scalar>(
227  error_name, errors[0],
228  max_error_name, max_error,
229  max_warning_name, max_warning,
230  out.get(), li
231  );
232  }
233 
234  bool success = true;
235 
236  if (nonnull(out)) *out
237  << std::endl
238  << li << "Check: |"<<error_name<<"| <= "<<max_error_name<<" ?\n";
239  for( int i = 0; i < num_scalars; ++i ) {
240  const ScalarMag error_mag = ST::magnitude(errors[i]);
241  const bool result = (
242  !SMT::isnaninf(error_mag)
243  && !SMT::isnaninf(max_error)
244  && error_mag <= max_error );
245  if(!result) success = false;
246  if(nonnull(out)) {
247  *out
248  << li << " "<<setw(2)<<i<<": |"<<errors[i]<<"| = "<<error_mag<<" <= "
249  <<max_error<<" : "<<passfail(success)<<"\n";
250  if( result && error_mag >= max_warning ) {
251  *out
252  << li << " Warning! |...| >= "<<max_warning_name<<" = "<<max_warning<<"!\n";
253  }
254  }
255  }
256  return success;
257 }
258 
259 
260 template<class Scalar>
261 std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
262 {
263  return o << Teuchos::describe(v, Teuchos::VERB_EXTREME);
264 }
265 
266 
267 template<class Scalar>
268 std::ostream& Thyra::operator<<( std::ostream& o, const LinearOpBase<Scalar>& M )
269 {
270  return o << Teuchos::describe(M, Teuchos::VERB_EXTREME);
271 }
272 
273 
274 #endif // THYRA_TESTING_TOOLS_HPP
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
bool testMaxErrors(const std::string &error_name, const ArrayView< const typename Teuchos::ScalarTraits< Scalar >::magnitudeType > &errors, const std::string &max_error_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &max_error, const std::string &max_warning_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &max_warning, const Ptr< std::ostream > &out, const std::string &leadingIndent=std::string(""))
Check that an array of errors is less than some error tolerence.
#define THYRA_ASSERT_VEC_SPACES(FUNC_NAME, VS1, VS2)
This is a very useful macro that should be used to validate that two vector spaces are compatible...
basic_OSTab< char > OSTab
const std::string passfail(const bool result)
size_type size() const
bool testRelNormDiffErr(const std::string &v1_name, const VectorBase< Scalar > &v1, const std::string &v2_name, const VectorBase< Scalar > &v2, const std::string &maxRelErr_error_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_error, const std::string &maxRelErr_warning_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_warning, std::ostream *out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::VERB_LOW, const std::string &leadingIndent=std::string(""))
Compute, check and optionally print the relative errors in two vectors.
bool testMaxErr(const std::string &error_name, const Scalar &error, const std::string &max_error_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &max_error, const std::string &max_warning_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &max_warning, std::ostream *out, const std::string &leadingIndent=std::string(""))
Check that an error is less than some error tolerence.
void V_VmV(const Ptr< MultiVectorBase< Scalar > > &Z, const MultiVectorBase< Scalar > &X, const MultiVectorBase< Scalar > &Y)
Z(i,j) = X(i,j) - Y(i,j), i = 0...Z-&gt;range()-&gt;dim()-1, j = 0...Z-&gt;domain()-&gt;dim()-1.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Ptr< T > ptr() const
RCP< VectorBase< Scalar > > createMember(const RCP< const VectorSpaceBase< Scalar > > &vs, const std::string &label="")
Create a vector member from the vector space.
Abstract interface for finite-dimensional dense vectors.
Teuchos::ScalarTraits< Scalar >::magnitudeType relVectorErr(const VectorBase< Scalar > &v1, const VectorBase< Scalar > &v2)
Return relative error of two vectors.
bool nonnull(const boost::shared_ptr< T > &p)
TypeTo as(const TypeFrom &t)
Teuchos::ScalarTraits< Scalar >::magnitudeType norm(const VectorBase< Scalar > &v)
Natural norm: result = sqrt(&lt;v,v&gt;).
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
bool testRelErrors(const std::string &v1_name, const ArrayView< const Scalar1 > &v1, const std::string &v2_name, const ArrayView< const Scalar2 > &v2, const std::string &maxRelErr_error_name, const ScalarMag &maxRelErr_error, const std::string &maxRelErr_warning_name, const ScalarMag &maxRelErr_warning, const Ptr< std::ostream > &out, const std::string &leadingIndent=std::string(""))
Compute, check and optionally print the relative errors in two scalar arays.
T * get() const