Thyra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Thyra_MultiVectorStdOpsTester_def.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_MULTI_VECTOR_STD_OPS_TESTER_HPP
43 #define THYRA_MULTI_VECTOR_STD_OPS_TESTER_HPP
44 
45 #include "Thyra_MultiVectorStdOpsTester_decl.hpp"
46 #include "Thyra_MultiVectorStdOps.hpp"
47 #include "Thyra_VectorStdOps.hpp"
48 #include "Thyra_TestingTools.hpp"
49 
50 namespace Thyra {
51 
52 // MultiVectorStdOpsTester
53 
54 template <class Scalar>
56  const ScalarMag &warning_tol_in
57  ,const ScalarMag &error_tol_in
58  ,const int num_mv_cols_in
59  )
60  :warning_tol_(warning_tol_in)
61  ,error_tol_(error_tol_in)
62  ,num_mv_cols_(num_mv_cols_in)
63 {}
64 
65 template <class Scalar>
67  const VectorSpaceBase<Scalar> &vecSpc
68  ,std::ostream *out
69  ,const bool &/* dumpAll */
70  )
71 {
72  using Teuchos::as;
73  using Teuchos::ptr;
74  using Teuchos::tuple;
76  typedef typename ST::magnitudeType ScalarMag;
77 
78  if(out)
79  *out << "\n*** Entering MultiVectorStdOpsTester<"<<ST::name()<<">::checkStdOps(...) ...\n"
80  << "using a \'" << vecSpc.description() << "\' object ...\n";
81 
82  bool success = true;
83  if(out) *out << "\nvecSpc.dim() = " << vecSpc.dim() << std::endl;
84 
85  const Ordinal n = vecSpc.dim();
86 
87  const Scalar
88  two = as<Scalar>(2.0),
89  three = as<Scalar>(3.0),
90  four = as<Scalar>(4.0);
91 
92  int tc = 0;
93 
94  if(out) *out << "\nCreating MultiVectorBase objects V1, V2, and V3 ...\n";
96  V1 = createMembers(vecSpc,num_mv_cols()),
97  V2 = createMembers(vecSpc,num_mv_cols()),
98  V3 = createMembers(vecSpc,num_mv_cols());
99 
100  if(out) *out << "\nassign(V1.ptr(),-2.0);\n";
101  assign(V1.ptr(),Scalar(-two));
102 
103  Teuchos::Array<Scalar> scalars1(num_mv_cols());
104  Teuchos::Array<Scalar> scalars2(num_mv_cols());
105  Teuchos::Array<ScalarMag> mags1(num_mv_cols());
106  Teuchos::Array<ScalarMag> mags2(num_mv_cols());
107 
108  // sums
109  if(out) *out << "\n"<<tc<<") sums(*V1);\n";
110  ++tc;
111  {
112  sums(*V1, scalars1());
113  for (Ordinal i = 0; i < scalars2.size(); ++i)
114  scalars2[i] = -two*as<Scalar>(vecSpc.dim());
115  if (!testRelErrors<Scalar, Scalar, ScalarMag>(
116  "sums(*V1)", scalars1(),
117  "-2.0*n", scalars2(),
118  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
119  )
120  ) success = false;
121  }
122 
123  // norms_1
124  if(out) *out << "\n"<<tc<<") norms_1(*V1);\n";
125  ++tc;
126  {
127  norms_1(*V1, mags1());
128  for (Ordinal i = 0; i < mags2.size(); ++i)
129  mags2[i] = ST::magnitude(two)*as<ScalarMag>(vecSpc.dim());
130  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
131  "norms_1(*V1)", mags1(),
132  "2.0*n", mags2(),
133  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
134  )
135  ) success = false;
136  }
137 
138  // norms_2
139  if(out) *out << "\n"<<tc<<") norms_2(*V1);\n";
140  ++tc;
141  {
142  norms_2(*V1, mags1());
143  for (Ordinal i = 0; i < mags2.size(); ++i)
144  mags2[i] = ST::magnitude(two * ST::squareroot(as<Scalar>(n)));
145  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
146  "norms_2(*V1)", mags1(),
147  "2.0*sqrt(n)", mags2(),
148  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
149  )
150  ) success = false;
151  }
152 
153  // norms_inf
154  if(out) *out << "\n"<<tc<<") norms_inf(*V1);\n";
155  ++tc;
156  {
157  norms_inf(*V1, mags1());
158  for (Ordinal i = 0; i < mags2.size(); ++i)
159  mags2[i] = ST::magnitude(two);
160  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
161  "norms_inf(*V1)", mags1(),
162  "2.0", mags2(),
163  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
164  )
165  ) success = false;
166  }
167 
168  // assign(scalar)
169  if(out) *out << "\n"<<tc<<") assign(V2.ptr(), alpha);\n";
170  ++tc;
171  {
172  assign(V2.ptr(), three);
173  norms_2(*V2, mags1());
174  for (Ordinal i = 0; i < mags2.size(); ++i)
175  mags2[i] = ST::magnitude(three * ST::squareroot(as<Scalar>(n)));
176  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
177  "norms_2(*V2)", mags1(),
178  "3.0*sqrt(n)", mags2(),
179  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
180  )
181  ) success = false;
182  }
183 
184  // assign(MV)
185  if(out) *out << "\n"<<tc<<") assign(V2.ptr(), *V1);\n";
186  ++tc;
187  assign(V2.ptr(), *V1);
188  norms_2(*V1, mags1());
189  norms_2(*V2, mags2());
190  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
191  "norms_2(*V1)", mags1(),
192  "norms_2(*V2)", mags2(),
193  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
194  )
195  ) success = false;
196 
197  // scale
198  if(out) *out << "\n"<<tc<<") scale(alpha,V2.ptr());\n";
199  ++tc;
200  {
201  Scalar alpha = as<Scalar>(1.2345);
202  assign(V2.ptr(), *V1);
203  scale(alpha, V2.ptr());
204  norms_2(*V1, mags1());
205  for (Ordinal i = 0; i < mags1.size(); ++i)
206  mags1[i] *= ST::magnitude(alpha);
207  norms_2(*V2, mags2());
208  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
209  "norms_2(alpha*V1)", mags1(),
210  "alpha*norms_2(V1)", mags2(),
211  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
212  )
213  ) success = false;
214  }
215 
216  // scaleUpdate
217  if(out) *out << "\n"<<tc<<") scaleUpdate(a,V1,V2.ptr());\n";
218  ++tc;
219  {
220  Teuchos::RCP<VectorBase<Scalar> > a = createMember(vecSpc);
221  assign(a.ptr(), two);
222  assign(V2.ptr(), four);
223  scaleUpdate(*a, *V1, V2.ptr()); // V2(i,j) = 2.0*(-2.0) + 4.0
224  norms_2(*V2, mags1());
225  if (!testMaxErrors<Scalar>(
226  "norms_2(*V2)", mags1(),
227  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
228  )
229  ) success = false;
230  }
231 
232  // update(alpha, U, V.ptr())
233  if(out) *out << "\n"<<tc<<") update(a,V1,V2.ptr());\n";
234  ++tc;
235  {
236  Scalar alpha = as<Scalar>(1.2345);
237  assign(V2.ptr(), three);
238  assign(V3.ptr(), *V1);
239  scale(alpha, V3.ptr());
240  Vp_V(V3.ptr(), *V2);
241  update(alpha, *V1, V2.ptr());
242  norms_2(*V2, mags1());
243  norms_2(*V3, mags2());
244  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
245  "norms_2(*V2)", mags1(),
246  "norms_2(*V3)", mags2(),
247  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
248  )
249  ) success = false;
250  }
251 
252  // update(alpha, beta, U, V.ptr())
253  if(out) *out << "\n"<<tc<<") update(alpha,beta,*V1,V2.ptr());\n";
254  ++tc;
255  {
256  Teuchos::Array<Scalar> alpha(num_mv_cols());
257  for (Ordinal i = 0; i < alpha.size(); ++i)
258  alpha[i] = as<Scalar>(i+1);
259  Scalar beta = as<Scalar>(1.2345);
260  assign(V2.ptr(), three);
261  assign(V3.ptr(), *V1);
262  scale(beta, V3.ptr());
263  for (Ordinal i = 0; i < alpha.size(); ++i)
264  scale(alpha[i], V3->col(i).ptr());
265  Vp_V(V3.ptr(), *V2);
266  Teuchos::ArrayView<const Scalar> alphaView = alpha();
267  update(alphaView, beta, *V1, V2.ptr());
268  norms_2(*V2, mags1());
269  norms_2(*V3, mags2());
270  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
271  "norms_2(*V2)", mags1(),
272  "norms_2(*V3)", mags2(),
273  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
274  )
275  ) success = false;
276  }
277 
278  // update(U, alpha, beta, V.ptr())
279  if(out) *out << "\n"<<tc<<") update(*V1,alpha,beta,V2.ptr());\n";
280  ++tc;
281  {
282  Teuchos::Array<Scalar> alpha(num_mv_cols());
283  for (Ordinal i = 0; i < alpha.size(); ++i)
284  alpha[i] = as<Scalar>(i+1);
285  Scalar beta = as<Scalar>(1.2345);
286  assign(V2.ptr(), three);
287  assign(V3.ptr(), *V2);
288  scale(beta, V3.ptr());
289  for (Ordinal i = 0; i < alpha.size(); ++i)
290  scale(alpha[i], V3->col(i).ptr());
291  Vp_V(V3.ptr(), *V1);
292  Teuchos::ArrayView<const Scalar> alphaView = alpha();
293  update(*V1, alphaView, beta, V2.ptr());
294  norms_2(*V2, mags1());
295  norms_2(*V3, mags2());
296  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
297  "norms_2(*V2)", mags1(),
298  "norms_2(*V3)", mags2(),
299  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
300  )
301  ) success = false;
302  }
303 
304  // linear_combination
305  if(out) *out << "\n"<<tc<<") linear_combination({alpha,beta,gamma},{V1.ptr(),V2.ptr(),V3.ptr()},0.0,V4.ptr());\n";
306  ++tc;
307  {
308  Scalar alpha = two, beta = -three, gamma = three;
309  Teuchos::RCP<MultiVectorBase<Scalar> > V4 = createMembers(vecSpc,num_mv_cols());
310  assign(V2.ptr(), two);
311  assign(V3.ptr(), four);
312  linear_combination<Scalar>(
313  tuple<Scalar>(alpha, beta, gamma),
314  tuple<Ptr<const MultiVectorBase<Scalar> > >(V1.ptr(), V2.ptr(), V3.ptr()),
315  as<Scalar>(0.0),
316  V4.ptr()); // V4(i,j) = 2.0(-2.0) + (-3.0)(2.0) + 3.0(4.0)
317  norms_2(*V4, mags1());
318  for (Ordinal i = 0; i < mags2.size(); ++i)
319  mags2[i] = ST::magnitude(two * ST::squareroot(as<Scalar>(n)));
320  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
321  "norms_2(*V4)", mags1(),
322  "2.0*sqrt(n)", mags2(),
323  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
324  )
325  ) success = false;
326  }
327 
328  if(out) *out << "\n"<<tc<<") linear_combination({alpha,beta,gamma},{V1.ptr(),V2.ptr(),V3.ptr()},0.5,V4.ptr());\n";
329  ++tc;
330  {
331  Scalar alpha = two, beta = -three, gamma = three;
332  Teuchos::RCP<MultiVectorBase<Scalar> > V4 = createMembers(vecSpc,num_mv_cols());
333  assign(V2.ptr(), two);
334  assign(V3.ptr(), four);
335  assign(V4.ptr(), -four);
336  linear_combination<Scalar>(
337  tuple<Scalar>(alpha, beta, gamma),
338  tuple<Ptr<const MultiVectorBase<Scalar> > >(V1.ptr(), V2.ptr(), V3.ptr()),
339  as<Scalar>(0.5),
340  V4.ptr()); // V4(i,j) = 0.5(-4.0) + 2.0(-2.0) + (-3.0)(2.0) + 3.0(4.0)
341  norms_2(*V4, mags1());
342  if (!testMaxErrors<Scalar>(
343  "norms_2(*V4)", mags1(),
344  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
345  )
346  ) success = false;
347  }
348 
349  // Vt_S
350  if(out) *out << "\n"<<tc<<") Vt_S(V1.ptr(),alpha);\n";
351  ++tc;
352  {
353  Scalar alpha = as<Scalar>(1.2345);
354  assign(V2.ptr(), *V1);
355  Vt_S(V2.ptr(), alpha);
356  norms_2(*V1, mags1());
357  for (Ordinal i = 0; i < mags1.size(); ++i)
358  mags1[i] *= ST::magnitude(alpha);
359  norms_2(*V2, mags2());
360  if (!testRelErrors<ScalarMag, ScalarMag, ScalarMag>(
361  "norms_2(alpha*V1)", mags1(),
362  "alpha*norms_2(V1)", mags2(),
363  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
364  )
365  ) success = false;
366  }
367 
368  // Vp_S
369  if(out) *out << "\n"<<tc<<") Vp_S(V2.ptr(),alpha);\n";
370  ++tc;
371  {
372  assign(V2.ptr(), *V1);
373  Vp_S(V2.ptr(), two); // V2(i,j) = -2.0 + 2.0
374  norms_2(*V2, mags1());
375  if (!testMaxErrors<Scalar>(
376  "norms_2(V2)", mags1(),
377  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
378  )
379  ) success = false;
380  }
381 
382  // Vp_V
383  if(out) *out << "\n"<<tc<<") Vp_V(V2.ptr(),*V1);\n";
384  ++tc;
385  {
386  assign(V2.ptr(), two);
387  Vp_V(V2.ptr(), *V1); // V2(i,j) = -2.0 + 2.0
388  norms_2(*V2, mags1());
389  if (!testMaxErrors<Scalar>(
390  "norms_2(V2)", mags1(),
391  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
392  )
393  ) success = false;
394  }
395 
396 
397  // V_VpV
398  if(out) *out << "\n"<<tc<<") V_VpV(V3.ptr(),*V1,*V2);\n";
399  ++tc;
400  {
401  assign(V2.ptr(), two);
402  V_VpV(V3.ptr(), *V1, *V2); // V3(i,j) = -2.0 + 2.0
403  norms_2(*V3, mags1());
404  if (!testMaxErrors<Scalar>(
405  "norms_2(V3)", mags1(),
406  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
407  )
408  ) success = false;
409  }
410 
411 
412  // V_VmV
413  if(out) *out << "\n"<<tc<<") V_VmV(V3.ptr(),*V1,*V2);\n";
414  ++tc;
415  {
416  assign(V2.ptr(), -two);
417  V_VmV(V3.ptr(), *V1, *V2); // V3(i,j) = -2.0 - (-2.0)
418  norms_2(*V3, mags1());
419  if (!testMaxErrors<Scalar>(
420  "norms_2(V3)", mags1(),
421  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
422  )
423  ) success = false;
424  }
425 
426 
427  // V_StVpV
428  if(out) *out << "\n"<<tc<<") V_StVpV(V3.ptr(),alpha,*V1,*V2);\n";
429  ++tc;
430  {
431  Scalar alpha = as<Scalar>(1.2345);
432  assign(V2.ptr(), three);
433  V_StVpV(V3.ptr(), alpha, *V1, *V2);
434  scale(alpha, V1.ptr());
435  Vp_V(V2.ptr(), *V1);
436  V_VmV(V3.ptr(), *V2, *V3);
437  norms_2(*V3, mags1());
438  if (!testMaxErrors<Scalar>(
439  "norms_2(V3)", mags1(),
440  "error_tol", error_tol(), "warning_tol", warning_tol(), ptr(out)
441  )
442  ) success = false;
443  }
444 
445 
446  if(out) *out
447  << "\n*** Leaving MultiVectorStdOpsTester<"<<ST::name()<<">::checkStdOps(...) ...\n";
448 
449  return success;
450 
451 }
452 
453 } // namespace Thyra
454 
455 #endif // THYRA_MULTI_VECTOR_STD_OPS_TESTER_HPP
MultiVectorStdOpsTester(const ScalarMag &warning_tol=0, const ScalarMag &error_tol=0, const int num_mv_cols=4)
Abstract interface for objects that represent a space for vectors.
bool checkStdOps(const VectorSpaceBase< Scalar > &vecSpc, std::ostream *out=0, const bool &dumpAll=false)
Run the tests using a vector space.
Teuchos::Ordinal Ordinal
Type for the dimension of a vector space. `*.
Interface for a collection of column vectors called a multi-vector.
Teuchos::ScalarTraits< Scalar >::magnitudeType ScalarMag
Ptr< T > ptr() const
virtual std::string description() const
size_type size() const
TypeTo as(const TypeFrom &t)
virtual Ordinal dim() const =0
Return the dimension of the vector space.