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 //
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 
53 template <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 
81 template<class Scalar1, class Scalar2, class ScalarMag>
83  const std::string &v1_name,
84  const ArrayView<const Scalar1> &v1,
85  const std::string &v2_name,
86  const ArrayView<const Scalar2> &v2,
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 
99  TEUCHOS_ASSERT_EQUALITY(v1.size(), v2.size());
100  const int num_scalars = v1.size();
101 
102  if(num_scalars==1) {
103  return Teuchos::testRelErr<Scalar>(
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 
137 template<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);
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 
202 template<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 
238 template<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 
292 template<class Scalar>
293 std::ostream& Thyra::operator<<( std::ostream& o, const VectorBase<Scalar>& v )
294 {
295  return o << Teuchos::describe(v, Teuchos::VERB_EXTREME);
296 }
297 
298 
299 template<class Scalar>
300 std::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
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