Thyra Version of the Day
Loading...
Searching...
No Matches
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
21template <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
49template<class Scalar1, class Scalar2, class ScalarMag>
51 const std::string &v1_name,
53 const std::string &v2_name,
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
68 const int num_scalars = v1.size();
69
70 if(num_scalars==1) {
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
105template<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);
151 RCP<VectorBase<Scalar> > diff = createMember(v1.space());
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
170template<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
206template<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
260template<class Scalar>
261std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
262{
263 return o << Teuchos::describe(v, Teuchos::VERB_EXTREME);
264}
265
266
267template<class Scalar>
268std::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
size_type size() const
T * get() const
Ptr< T > ptr() const
Base class for all linear operators.
Abstract interface for finite-dimensional dense vectors.
virtual RCP< const VectorSpaceBase< Scalar > > space() const =0
Return a smart pointer to the vector space that this vector belongs to.
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
Teuchos::ScalarTraits< Scalar >::magnitudeType relVectorErr(const VectorBase< Scalar > &v1, const VectorBase< Scalar > &v2)
Return relative error of two vectors.
#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.
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.
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.
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.
TypeTo as(const TypeFrom &t)
T_To & dyn_cast(T_From &from)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)