Thyra Version of the Day
Loading...
Searching...
No Matches
Thyra_TestingTools.hpp
1// @HEADER
2// ***********************************************************************
3//
4// Thyra: Interfaces and Support for Abstract Numerical Algorithms
5// Copyright (2004) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Roscoe A. Bartlett (bartlettra@ornl.gov)
38//
39// ***********************************************************************
40// @HEADER
41
42#ifndef THYRA_TESTING_TOOLS_HPP
43#define THYRA_TESTING_TOOLS_HPP
44
45#include "Thyra_TestingToolsDecl.hpp"
46#include "Thyra_VectorBase.hpp"
47#include "Thyra_VectorStdOps.hpp"
48#include "Thyra_LinearOpBase.hpp"
49#include "Thyra_AssertOp.hpp"
50#include "Teuchos_as.hpp"
51
52
53template <class Scalar>
56{
58 typedef typename ST::magnitudeType ScalarMag;
59#ifdef TEUCHOS_DEBUG
60 THYRA_ASSERT_VEC_SPACES( "relErr(v1,v2)", *v1.space(), *v2.space() );
61#endif
63 diff = createMember(v1.space());
64 V_VmV( diff.ptr(), v1, v2 );
65 const ScalarMag
66 nrm_v1 = norm(v1),
67 nrm_v2 = norm(v2),
68 nrm_diff = norm(*diff);
69 return
70 ( nrm_diff
71 / (
72 ST::magnitude(
74 )
75 + std::max( nrm_v1, nrm_v2 )
76 )
77 );
78}
79
80
81template<class Scalar1, class Scalar2, class ScalarMag>
83 const std::string &v1_name,
85 const std::string &v2_name,
87 const std::string &maxRelErr_error_name,
88 const ScalarMag &maxRelErr_error,
89 const std::string &maxRelErr_warning_name,
90 const ScalarMag &maxRelErr_warning,
91 const Ptr<std::ostream> &out,
92 const std::string &li
93 )
94{
95 using std::setw;
97 typedef typename Teuchos::PromotionTraits<Scalar1,Scalar2>::promote Scalar;
98
100 const int num_scalars = v1.size();
101
102 if(num_scalars==1) {
104 v1_name, v1[0], v2_name, v2[0],
105 maxRelErr_error_name, maxRelErr_error,
106 maxRelErr_warning_name, maxRelErr_warning,
107 out
108 );
109 }
110
111 bool success = true;
112
113 if (nonnull(out)) *out
114 << std::endl
115 << li << "Check: rel_err(" << v1_name << "," << v2_name << ") <= " << maxRelErr_error_name << " ?\n";
116
117 for( int i = 0; i < num_scalars; ++i ) {
118 const ScalarMag rel_err = relErr<Scalar>( v1[i], v2[i] );
119 const bool result = ( !SMT::isnaninf(rel_err) && !SMT::isnaninf(maxRelErr_error) && rel_err <= maxRelErr_error );
120 if(!result) success = false;
121 if(nonnull(out)) {
122 *out
123 << li << " "<<setw(2)<<i<<": rel_err("<<v1[i]<<","<<v2[i]<<") "<<"= "<<rel_err
124 << " <= " << maxRelErr_error << " : " << passfail(result) << std::endl;
125 if( result && rel_err >= maxRelErr_warning ) {
126 *out
127 << li << " Warning! rel_err(...) >= " << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
128 }
129 }
130 }
131
132 return success;
133
134}
135
136
137template<class Scalar>
139 const std::string &v1_name,
140 const VectorBase<Scalar> &v1,
141 const std::string &v2_name,
142 const VectorBase<Scalar> &v2,
143 const std::string &maxRelErr_error_name,
144 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_error,
145 const std::string &maxRelErr_warning_name,
146 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &maxRelErr_warning,
147 std::ostream *out_inout,
148 const Teuchos::EVerbosityLevel verbLevel,
149 const std::string &li
150 )
151{
152 using std::endl;
153 using Teuchos::as;
154 using Teuchos::OSTab;
156 typedef typename ST::magnitudeType ScalarMag;
158 const RCP<FancyOStream> out =
159 Teuchos::fancyOStream(Teuchos::rcp(out_inout, false));
160 const ScalarMag
161 nrm_v1 = norm(v1),
162 nrm_v2 = norm(v2);
163 const ScalarMag rel_err = relVectorErr(v1,v2);
164 const bool success =
165 (
166 !SMT::isnaninf(rel_err)
167 && !SMT::isnaninf(maxRelErr_error)
168 && rel_err <= maxRelErr_error
169 );
170 if (nonnull(out)) {
171 *out
172 << endl
173 << li << "Testing relative error between vectors "
174 << v1_name << " and " << v2_name << ":\n";
175 OSTab tab(out);
176 *out
177 << li << "||"<<v1_name<<"|| = " << nrm_v1 << endl
178 << li << "||"<<v2_name<<"|| = " << nrm_v2 << endl;
179 if (as<int>(verbLevel) >= as<int>(Teuchos::VERB_HIGH)) {
180 *out
181 << li << v1_name << " = " << describe(v1,verbLevel)
182 << li << v2_name << " = " << describe(v2,verbLevel);
183 RCP<VectorBase<Scalar> > diff = createMember(v1.space());
184 V_VmV( diff.ptr(), v1, v2 );
185 *out
186 << li << v1_name << " - " << v2_name << " = " << describe(*diff,verbLevel);
187 }
188 *out
189 << li << "Check: rel_err(" << v1_name << "," << v2_name << ") = "
190 << rel_err << " <= " << maxRelErr_error_name << " = "
191 << maxRelErr_error << " : " << passfail(success) << endl;
192 if( success && rel_err >= maxRelErr_warning ) {
193 *out
194 << li << "Warning! rel_err(" << v1_name << "," << v2_name << " >= "
195 << maxRelErr_warning_name << " = " << maxRelErr_warning << "!\n";
196 }
197 }
198 return success;
199}
200
201
202template<class Scalar>
204 const std::string &error_name
205 ,const Scalar &error
206 ,const std::string &max_error_name
207 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error
208 ,const std::string &max_warning_name
209 ,const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning
210 ,std::ostream *out
211 ,const std::string &li
212 )
213{
215 typedef typename ST::magnitudeType ScalarMag;
217 const ScalarMag error_mag = ST::magnitude(error);
218 const bool success = (
219 !SMT::isnaninf(error_mag)
220 && !SMT::isnaninf(max_error)
221 && error_mag <= max_error );
222 if(out) {
223 *out
224 << std::endl
225 << li << "Check: |" << error_name << "| = " << error_mag
226 << " <= " << max_error_name << " = " << max_error << " : "
227 << passfail(success) << std::endl;
228 if( success && error_mag >= max_warning ) {
229 *out
230 << li << "Warning! " << error_name << " = " << error_mag
231 << " >= " << max_warning_name << " = " << max_warning << "!\n";
232 }
233 }
234 return success;
235}
236
237
238template<class Scalar>
240 const std::string &error_name,
241 const ArrayView<const typename Teuchos::ScalarTraits<Scalar>::magnitudeType> &errors,
242 const std::string &max_error_name,
243 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_error,
244 const std::string &max_warning_name,
245 const typename Teuchos::ScalarTraits<Scalar>::magnitudeType &max_warning,
246 const Ptr<std::ostream> &out,
247 const std::string &li
248 )
249{
250 using std::setw;
252 typedef typename ST::magnitudeType ScalarMag;
254
255 const int num_scalars = errors.size();
256
257 if(num_scalars==1) {
258 return testMaxErr<Scalar>(
259 error_name, errors[0],
260 max_error_name, max_error,
261 max_warning_name, max_warning,
262 out.get(), li
263 );
264 }
265
266 bool success = true;
267
268 if (nonnull(out)) *out
269 << std::endl
270 << li << "Check: |"<<error_name<<"| <= "<<max_error_name<<" ?\n";
271 for( int i = 0; i < num_scalars; ++i ) {
272 const ScalarMag error_mag = ST::magnitude(errors[i]);
273 const bool result = (
274 !SMT::isnaninf(error_mag)
275 && !SMT::isnaninf(max_error)
276 && error_mag <= max_error );
277 if(!result) success = false;
278 if(nonnull(out)) {
279 *out
280 << li << " "<<setw(2)<<i<<": |"<<errors[i]<<"| = "<<error_mag<<" <= "
281 <<max_error<<" : "<<passfail(success)<<"\n";
282 if( result && error_mag >= max_warning ) {
283 *out
284 << li << " Warning! |...| >= "<<max_warning_name<<" = "<<max_warning<<"!\n";
285 }
286 }
287 }
288 return success;
289}
290
291
292template<class Scalar>
293std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
294{
295 return o << Teuchos::describe(v, Teuchos::VERB_EXTREME);
296}
297
298
299template<class Scalar>
300std::ostream& Thyra::operator<<( std::ostream& o, const LinearOpBase<Scalar>& M )
301{
302 return o << Teuchos::describe(M, Teuchos::VERB_EXTREME);
303}
304
305
306#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)