10 #ifndef THYRA_LINEAR_OP_TESTER_DEF_HPP
11 #define THYRA_LINEAR_OP_TESTER_DEF_HPP
13 #include "Thyra_LinearOpTester_decl.hpp"
14 #include "Thyra_LinearOpBase.hpp"
15 #include "Thyra_DefaultScaledAdjointLinearOp.hpp"
16 #include "Thyra_describeLinearOp.hpp"
17 #include "Thyra_VectorStdOps.hpp"
18 #include "Thyra_TestingTools.hpp"
19 #include "Thyra_UniversalMultiVectorRandomizer.hpp"
20 #include "Teuchos_TestingHelpers.hpp"
26 template<
class Scalar>
27 class SymmetricLinearOpTester {
30 static void checkSymmetry(
31 const LinearOpBase<Scalar> &op,
32 const Ptr<MultiVectorRandomizerBase<Scalar> > &dRand,
35 const int num_random_vectors,
38 const ScalarMag &symmetry_error_tol,
39 const ScalarMag &symmetry_warning_tol,
40 const Ptr<bool> &these_results
49 const Scalar half = Scalar(0.4)*ST::one();
50 RCP<const VectorSpaceBase<Scalar> > domain = op.domain();
52 testOut << endl <<
"op.domain()->isCompatible(*op.range()) == true : ";
53 result = op.domain()->isCompatible(*op.range());
54 if(!result) *these_results =
false;
60 << endl <<
"Checking that the operator is symmetric as:\n"
61 << endl <<
" <0.5*op*v2,v1> == <v2,0.5*op*v1>"
62 << endl <<
" \\_______/ \\_______/"
65 << endl <<
" <v4,v1> == <v2,v3>"
66 << endl << std::flush;
68 for(
int rand_vec_i = 1; rand_vec_i <= num_random_vectors; ++rand_vec_i ) {
70 testOut << endl <<
"Random vector tests = " << rand_vec_i << endl;
74 if(dump_all) testOut << endl <<
"v1 = randomize(-1,+1); ...\n" ;
75 RCP<MultiVectorBase<Scalar> > v1 = createMembers(domain,num_rhs);
76 dRand->randomize(v1.ptr());
77 if(dump_all) testOut << endl <<
"v1 =\n" << describe(*v1,verbLevel);
79 if(dump_all) testOut << endl <<
"v2 = randomize(-1,+1); ...\n" ;
80 RCP<MultiVectorBase<Scalar> > v2 = createMembers(domain,num_rhs);
81 dRand->randomize(v2.ptr());
82 if(dump_all) testOut << endl <<
"v2 =\n" << describe(*v2,verbLevel);
84 if(dump_all) testOut << endl <<
"v3 = 0.5*op*v1 ...\n" ;
85 RCP<MultiVectorBase<Scalar> > v3 = createMembers(domain,num_rhs);
86 apply( op,
NOTRANS, *v1, v3.ptr(), half );
87 if(dump_all) testOut << endl <<
"v3 =\n" << describe(*v3,verbLevel);
89 if(dump_all) testOut << endl <<
"v4 = 0.5*op*v2 ...\n" ;
90 RCP<MultiVectorBase<Scalar> > v4 = createMembers(domain,num_rhs);
91 apply( op,
NOTRANS, *v2, v4.ptr(), half );
92 if(dump_all) testOut << endl <<
"v4 =\n" << describe(*v4,verbLevel);
94 Array<Scalar> prod1(num_rhs), prod2(num_rhs);
95 domain->scalarProds(*v4, *v1, prod1());
96 domain->scalarProds(*v2, *v3, prod2());
98 result = testRelErrors<Scalar, Scalar, ScalarMag>(
101 "symmetry_error_tol()", symmetry_error_tol,
102 "symmetry_warning_tol()", symmetry_warning_tol,
105 if(!result) *these_results =
false;
110 testOut << endl <<
"Range and domain spaces are different, skipping check!\n";
121 template<
class Scalar>
123 :check_linear_properties_(true),
124 linear_properties_warning_tol_(-1.0),
125 linear_properties_error_tol_(-1.0),
126 check_adjoint_(true),
127 adjoint_warning_tol_(-1.0),
128 adjoint_error_tol_(-1.0),
129 check_for_symmetry_(false),
130 symmetry_warning_tol_(-1.0),
131 symmetry_error_tol_(-1.0),
132 num_random_vectors_(1),
133 show_all_tests_(false),
141 template<
class Scalar>
144 check_linear_properties_ = enable_all_tests_in;
145 check_adjoint_ = enable_all_tests_in;
146 check_for_symmetry_ = enable_all_tests_in;
150 template<
class Scalar>
153 linear_properties_warning_tol_ = warning_tol_in;
154 adjoint_warning_tol_ = warning_tol_in;
155 symmetry_warning_tol_ = warning_tol_in;
159 template<
class Scalar>
162 linear_properties_error_tol_ = error_tol_in;
163 adjoint_error_tol_ = error_tol_in;
164 symmetry_error_tol_ = error_tol_in;
168 template<
class Scalar>
180 using Teuchos::rcpFromPtr;
181 using Teuchos::rcpFromRef;
182 using Teuchos::outArg;
183 using Teuchos::inoutArg;
184 using Teuchos::fancyOStream;
189 bool success =
true, result;
190 const int loc_num_rhs = this->num_rhs();
191 const Scalar r_one = ST::one();
192 const Scalar d_one = ST::one();
193 const Scalar r_half = as<Scalar>(0.5)*r_one;
194 const Scalar d_half = as<Scalar>(0.5)*d_one;
198 out = Teuchos::rcpFromPtr(out_inout);
205 OSTab tab2(out,1,
"THYRA");
210 *out << endl <<
"*** Entering LinearOpTester<"<<ST::name()<<
","<<ST::name()<<
">::check(op,...) ...\n";
211 if(show_all_tests()) {
212 *out << endl <<
"describe op:\n" << Teuchos::describe(op,verbLevel);
224 RCP< MultiVectorRandomizerBase<Scalar> > rRand;
226 rRand = rcpFromPtr(rangeRandomizer);
228 rRand = universalMultiVectorRandomizer<Scalar>();
229 RCP< MultiVectorRandomizerBase<Scalar> > dRand;
230 if (!
is_null(domainRandomizer))
231 dRand = rcpFromPtr(domainRandomizer);
233 dRand = universalMultiVectorRandomizer<Scalar>();
235 *out << endl <<
"Checking the domain and range spaces ... ";
237 RCP<const VectorSpaceBase<Scalar> > range = op.range();
238 RCP<const VectorSpaceBase<Scalar> > domain = op.domain();
242 TestResultsPrinter testResultsPrinter(out, show_all_tests());
243 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
245 bool these_results =
true;
247 *testOut << endl <<
"op.domain().get() != NULL ? ";
248 result = domain.get() != NULL;
249 if(!result) these_results =
false;
250 *testOut <<
passfail(result) << endl;
252 *testOut << endl <<
"op.range().get() != NULL ? ";
253 result = range.get() != NULL;
254 if(!result) these_results =
false;
255 *testOut <<
passfail(result) << endl;
257 testResultsPrinter.printTestResults(these_results, inoutArg(success));
261 if( check_linear_properties() ) {
263 *out << endl <<
"this->check_linear_properties()==true:"
264 <<
"Checking the linear properties of the forward linear operator ... ";
266 TestResultsPrinter testResultsPrinter(out, show_all_tests());
267 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
269 bool these_results =
true;
276 << endl <<
"Checking that the forward operator is truly linear:\n"
277 << endl <<
" 0.5*op*(v1 + v2) == 0.5*op*v1 + 0.5*op*v2"
278 << endl <<
" \\_____/ \\___/"
280 << endl <<
" \\_____________/ \\___________________/"
283 << endl <<
" sum(v4) == sum(v5)"
284 << endl << std::flush;
286 for(
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
288 *testOut << endl <<
"Random vector tests = " << rand_vec_i << endl;
292 *testOut << endl <<
"v1 = randomize(-1,+1); ...\n" ;
293 RCP<MultiVectorBase<Scalar> > v1 = createMembers(domain,loc_num_rhs);
294 dRand->randomize(v1.ptr());
295 if(dump_all()) *testOut << endl <<
"v1 =\n" << describe(*v1,verbLevel);
297 *testOut << endl <<
"v2 = randomize(-1,+1); ...\n" ;
298 RCP<MultiVectorBase<Scalar> > v2 = createMembers(domain,loc_num_rhs);
299 dRand->randomize(v2.ptr());
300 if(dump_all()) *testOut << endl <<
"v2 =\n" << describe(*v2,verbLevel);
302 *testOut << endl <<
"v3 = v1 + v2 ...\n" ;
303 RCP<MultiVectorBase<Scalar> > v3 = createMembers(domain,loc_num_rhs);
304 V_VpV(v3.ptr(),*v1,*v2);
305 if(dump_all()) *testOut << endl <<
"v3 =\n" << describe(*v3,verbLevel);
307 *testOut << endl <<
"v4 = 0.5*op*v3 ...\n" ;
308 RCP<MultiVectorBase<Scalar> > v4 = createMembers(range,loc_num_rhs);
309 apply( op,
NOTRANS, *v3, v4.ptr(), r_half );
310 if(dump_all()) *testOut << endl <<
"v4 =\n" << describe(*v4,verbLevel);
312 *testOut << endl <<
"v5 = op*v1 ...\n" ;
313 RCP<MultiVectorBase<Scalar> > v5 = createMembers(range,loc_num_rhs);
314 apply( op,
NOTRANS, *v1, v5.ptr() );
315 if(dump_all()) *testOut << endl <<
"v5 =\n" << describe(*v5,verbLevel);
317 *testOut << endl <<
"v5 = 0.5*op*v2 + 0.5*v5 ...\n" ;
318 apply( op,
NOTRANS, *v2, v5.ptr(), r_half, r_half );
319 if(dump_all()) *testOut << endl <<
"v5 =\n" << describe(*v5,verbLevel);
321 Array<Scalar> sum_v4(loc_num_rhs), sum_v5(loc_num_rhs);
325 result = testRelErrors<Scalar, Scalar, ScalarMag>(
328 "linear_properties_error_tol()", linear_properties_error_tol(),
329 "linear_properties_warning_tol()", linear_properties_warning_tol(),
332 if(!result) these_results =
false;
337 *testOut << endl <<
"Forward operator not supported, skipping check!\n";
340 testResultsPrinter.printTestResults(these_results, inoutArg(success));
344 *out << endl <<
"this->check_linear_properties()==false: Skipping the check of the linear properties of the forward operator!\n";
347 if( check_linear_properties() && check_adjoint() ) {
349 *out << endl <<
"(this->check_linear_properties()&&this->check_adjoint())==true:"
350 <<
" Checking the linear properties of the adjoint operator ... ";
353 TestResultsPrinter testResultsPrinter(out, show_all_tests());
354 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
356 bool these_results =
true;
363 << endl <<
"Checking that the adjoint operator is truly linear:\n"
364 << endl <<
" 0.5*op'*(v1 + v2) == 0.5*op'*v1 + 0.5*op'*v2"
365 << endl <<
" \\_____/ \\____/"
367 << endl <<
" \\_______________/ \\_____________________/"
370 << endl <<
" sum(v4) == sum(v5)"
371 << endl << std::flush;
373 for(
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
375 *testOut << endl <<
"Random vector tests = " << rand_vec_i << endl;
379 *testOut << endl <<
"v1 = randomize(-1,+1); ...\n" ;
380 RCP<MultiVectorBase<Scalar> > v1 = createMembers(range,loc_num_rhs);
381 rRand->randomize(v1.ptr());
382 if(dump_all()) *testOut << endl <<
"v1 =\n" << describe(*v1,verbLevel);
384 *testOut << endl <<
"v2 = randomize(-1,+1); ...\n" ;
385 RCP<MultiVectorBase<Scalar> > v2 = createMembers(range,loc_num_rhs);
386 rRand->randomize(v2.ptr());
387 if(dump_all()) *testOut << endl <<
"v2 =\n" << describe(*v2,verbLevel);
389 *testOut << endl <<
"v3 = v1 + v2 ...\n" ;
390 RCP<MultiVectorBase<Scalar> > v3 = createMembers(range,loc_num_rhs);
391 V_VpV(v3.ptr(),*v1,*v2);
392 if(dump_all()) *testOut << endl <<
"v3 =\n" << describe(*v3,verbLevel);
394 *testOut << endl <<
"v4 = 0.5*op'*v3 ...\n" ;
395 RCP<MultiVectorBase<Scalar> > v4 = createMembers(domain,loc_num_rhs);
396 apply( op,
CONJTRANS, *v3, v4.ptr(), d_half );
397 if(dump_all()) *testOut << endl <<
"v4 =\n" << describe(*v4,verbLevel);
399 *testOut << endl <<
"v5 = op'*v1 ...\n" ;
400 RCP<MultiVectorBase<Scalar> > v5 = createMembers(domain,loc_num_rhs);
402 if(dump_all()) *testOut << endl <<
"v5 =\n" << describe(*v5,verbLevel);
404 *testOut << endl <<
"v5 = 0.5*op'*v2 + 0.5*v5 ...\n" ;
405 apply( op,
CONJTRANS, *v2, v5.ptr(), d_half, d_half );
406 if(dump_all()) *testOut << endl <<
"v5 =\n" << describe(*v5,verbLevel);
408 Array<Scalar> sum_v4(loc_num_rhs), sum_v5(loc_num_rhs);
412 result = testRelErrors<Scalar, Scalar, ScalarMag>(
415 "linear_properties_error_tol()", linear_properties_error_tol(),
416 "linear_properties_warning_tol()", linear_properties_warning_tol(),
419 if(!result) these_results =
false;
424 *testOut << endl <<
"Adjoint operator not supported, skipping check!\n";
427 testResultsPrinter.printTestResults(these_results, inoutArg(success));
431 *out << endl <<
"(this->check_linear_properties()&&this->check_adjoint())==false: Skipping the check of the linear properties of the adjoint operator!\n";
434 if( check_adjoint() ) {
436 *out << endl <<
"this->check_adjoint()==true:"
437 <<
" Checking the agreement of the adjoint and forward operators ... ";
439 TestResultsPrinter testResultsPrinter(out, show_all_tests());
440 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
442 bool these_results =
true;
449 << endl <<
"Checking that the adjoint agrees with the non-adjoint operator as:\n"
450 << endl <<
" <0.5*op'*v2,v1> == <v2,0.5*op*v1>"
451 << endl <<
" \\________/ \\_______/"
454 << endl <<
" <v4,v1> == <v2,v3>"
455 << endl << std::flush;
457 for(
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
459 *testOut << endl <<
"Random vector tests = " << rand_vec_i << endl;
463 *testOut << endl <<
"v1 = randomize(-1,+1); ...\n" ;
464 RCP<MultiVectorBase<Scalar> > v1 = createMembers(domain,loc_num_rhs);
465 dRand->randomize(v1.ptr());
466 if(dump_all()) *testOut << endl <<
"v1 =\n" << describe(*v1,verbLevel);
468 *testOut << endl <<
"v2 = randomize(-1,+1); ...\n" ;
469 RCP<MultiVectorBase<Scalar> > v2 = createMembers(range,loc_num_rhs);
470 rRand->randomize(v2.ptr());
471 if(dump_all()) *testOut << endl <<
"v2 =\n" << describe(*v2,verbLevel);
473 *testOut << endl <<
"v3 = 0.5*op*v1 ...\n" ;
474 RCP<MultiVectorBase<Scalar> > v3 = createMembers(range,loc_num_rhs);
475 apply( op,
NOTRANS, *v1, v3.ptr(), r_half );
476 if(dump_all()) *testOut << endl <<
"v3 =\n" << describe(*v3,verbLevel);
478 *testOut << endl <<
"v4 = 0.5*op'*v2 ...\n" ;
479 RCP<MultiVectorBase<Scalar> > v4 = createMembers(domain,loc_num_rhs);
480 apply( op,
CONJTRANS, *v2, v4.ptr(), d_half );
481 if(dump_all()) *testOut << endl <<
"v4 =\n" << describe(*v4,verbLevel);
483 Array<Scalar> prod_v4_v1(loc_num_rhs);
484 domain->scalarProds(*v4, *v1, prod_v4_v1());
485 Array<Scalar> prod_v2_v3(loc_num_rhs);
486 range->scalarProds(*v2, *v3, prod_v2_v3());
488 result = testRelErrors<Scalar, Scalar, ScalarMag>(
489 "<v4,v1>", prod_v4_v1(),
490 "<v2,v3>", prod_v2_v3(),
491 "adjoint_error_tol()", adjoint_error_tol(),
492 "adjoint_warning_tol()", adjoint_warning_tol(),
495 if(!result) these_results =
false;
500 *testOut << endl <<
"Adjoint operator not supported, skipping check!\n";
503 testResultsPrinter.printTestResults(these_results, inoutArg(success));
507 *out << endl <<
"this->check_adjoint()==false:"
508 <<
" Skipping check for the agreement of the adjoint and forward operators!\n";
512 if( check_for_symmetry() ) {
514 *out << endl <<
"this->check_for_symmetry()==true: Performing check of symmetry ... ";
516 TestResultsPrinter testResultsPrinter(out, show_all_tests());
517 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
519 bool these_results =
true;
521 SymmetricLinearOpTester<Scalar>::checkSymmetry(
522 op, dRand.ptr(), *testOut, loc_num_rhs,num_random_vectors(), verbLevel,dump_all(),
523 symmetry_error_tol(), symmetry_warning_tol(),
524 outArg(these_results)
527 testResultsPrinter.printTestResults(these_results, inoutArg(success));
531 *out << endl <<
"this->check_for_symmetry()==false: Skipping check of symmetry ...\n";
535 *out << endl <<
"Congratulations, this LinearOpBase object seems to check out!\n";
537 *out << endl <<
"Oh no, at least one of the tests performed with this LinearOpBase object failed (see above failures)!\n";
538 *out << endl <<
"*** Leaving LinearOpTester<"<<ST::name()<<
","<<ST::name()<<
">::check(...)\n";
545 template<
class Scalar>
547 const LinearOpBase<Scalar> &op,
548 const Ptr<Teuchos::FancyOStream> &out
552 return check(op, null, null, out);
556 template<
class Scalar>
558 const LinearOpBase<Scalar> &op1,
559 const LinearOpBase<Scalar> &op2,
560 const Ptr<MultiVectorRandomizerBase<Scalar> > &domainRandomizer,
561 const Ptr<Teuchos::FancyOStream> &out_arg
566 using Teuchos::rcpFromPtr;
567 using Teuchos::inoutArg;
571 bool success =
true, result;
572 const int loc_num_rhs = this->num_rhs();
573 const Scalar r_half = Scalar(0.5)*ST::one();
574 const RCP<FancyOStream> out = rcpFromPtr(out_arg);
577 OSTab tab(out,1,
"THYRA");
581 << endl <<
"*** Entering LinearOpTester<"<<ST::name()<<
","<<ST::name()<<
">::compare(op1,op2,...) ...\n";
583 *out << endl <<
"describe op1:\n" << Teuchos::describe(op1,verbLevel);
585 *out << endl <<
"describe op1: " << op1.description() << endl;
587 *out << endl <<
"describe op2:\n" << Teuchos::describe(op2,verbLevel);
589 *out << endl <<
"describe op2: " << op2.description() << endl;
592 RCP<MultiVectorRandomizerBase<Scalar> > dRand;
593 if (
nonnull(domainRandomizer)) dRand = rcpFromPtr(domainRandomizer);
594 else dRand = universalMultiVectorRandomizer<Scalar>();
596 RCP<const VectorSpaceBase<Scalar> > range = op1.range();
597 RCP<const VectorSpaceBase<Scalar> > domain = op1.domain();
599 if(out.get()) *out << endl <<
"Checking that range and domain spaces are compatible ... ";
603 TestResultsPrinter testResultsPrinter(out, show_all_tests());
604 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
606 bool these_results =
true;
608 *testOut << endl <<
"op1.domain()->isCompatible(*op2.domain()) ? ";
609 result = op1.domain()->isCompatible(*op2.domain());
610 if(!result) these_results =
false;
611 *testOut <<
passfail(result) << endl;
613 *testOut << endl <<
"op1.range()->isCompatible(*op2.range()) ? ";
614 result = op1.range()->isCompatible(*op2.range());
615 if(!result) these_results =
false;
616 *testOut <<
passfail(result) << endl;
618 testResultsPrinter.printTestResults(these_results, inoutArg(success));
623 if(out.get()) *out << endl <<
"Skipping further checks since operators are not compatible!\n";
627 if(out.get()) *out << endl <<
"Checking that op1 == op2 ... ";
631 TestResultsPrinter testResultsPrinter(out, show_all_tests());
632 const RCP<FancyOStream> testOut = testResultsPrinter.getTestOStream();
634 bool these_results =
true;
637 << endl <<
"Checking that op1 and op2 produce the same results:\n"
638 << endl <<
" 0.5*op1*v1 == 0.5*op2*v1"
639 << endl <<
" \\________/ \\________/"
642 << endl <<
" norm(v2-v3) ~= 0"
644 << endl << std::flush;
646 for(
int rand_vec_i = 1; rand_vec_i <= num_random_vectors(); ++rand_vec_i ) {
648 *testOut << endl <<
"Random vector tests = " << rand_vec_i << endl;
652 if(dump_all()) *testOut << endl <<
"v1 = randomize(-1,+1); ...\n" ;
653 RCP<MultiVectorBase<Scalar> > v1 = createMembers(domain,loc_num_rhs);
654 dRand->randomize(v1.ptr());
655 if(dump_all()) *testOut << endl <<
"v1 =\n" << *v1;
657 if(dump_all()) *testOut << endl <<
"v2 = 0.5*op1*v1 ...\n" ;
658 RCP<MultiVectorBase<Scalar> > v2 = createMembers(range,loc_num_rhs);
659 apply( op1,
NOTRANS, *v1, v2.ptr(), r_half );
660 if(dump_all()) *testOut << endl <<
"v2 =\n" << *v2;
662 if(dump_all()) *testOut << endl <<
"v3 = 0.5*op2*v1 ...\n" ;
663 RCP<MultiVectorBase<Scalar> > v3 = createMembers(range,loc_num_rhs);
664 apply( op2,
NOTRANS, *v1, v3.ptr(), r_half );
665 if(dump_all()) *testOut << endl <<
"v3 =\n" << *v3;
668 for(
int col_id=0;col_id < v1->domain()->dim();col_id++) {
669 std::stringstream ss;
670 ss <<
".col[" << col_id <<
"]";
673 "v2"+ss.str(),*v2->col(col_id),
674 "v3"+ss.str(),*v3->col(col_id),
675 "linear_properties_error_tol()", linear_properties_error_tol(),
676 "linear_properties_warning_tol()", linear_properties_warning_tol(),
678 if(!result) these_results =
false;
694 if(!result) these_results =
false;
698 testResultsPrinter.printTestResults(these_results, inoutArg(success));
704 *out << endl <<
"Congratulations, these two LinearOpBase objects seem to be the same!\n";
706 *out << endl <<
"Oh no, these two LinearOpBase objects seem to be different (see above failures)!\n";
707 *out << endl <<
"*** Leaving LinearOpTester<"<<ST::name()<<
","<<ST::name()<<
">::compare(...)\n";
715 template<
class Scalar>
717 const LinearOpBase<Scalar> &op1,
718 const LinearOpBase<Scalar> &op2,
719 const Ptr<Teuchos::FancyOStream> &out_arg
722 return compare(op1, op2, Teuchos::null, out_arg);
730 template<
class ScalarMag>
732 void setDefaultTol(
const ScalarMag &defaultDefaultTol,
733 ScalarMag &defaultTol)
735 typedef ScalarTraits<ScalarMag> SMT;
736 if (defaultTol < SMT::zero()) {
737 defaultTol = defaultDefaultTol;
742 template<
class Scalar>
743 void LinearOpTester<Scalar>::setDefaultTols()
745 typedef ScalarTraits<ScalarMag> SMT;
746 const ScalarMag defaultWarningTol = 1e+2 * SMT::eps();
747 const ScalarMag defaultErrorTol = 1e+4 * SMT::eps();
748 setDefaultTol(defaultWarningTol, linear_properties_warning_tol_);
749 setDefaultTol(defaultErrorTol, linear_properties_error_tol_);
750 setDefaultTol(defaultWarningTol, adjoint_warning_tol_);
751 setDefaultTol(defaultErrorTol, adjoint_error_tol_);
752 setDefaultTol(defaultWarningTol, symmetry_warning_tol_);
753 setDefaultTol(defaultErrorTol, symmetry_error_tol_);
760 #endif // THYRA_LINEAR_OP_TESTER_DEF_HPP
void enable_all_tests(const bool enable_all_tests)
Enable or disable all tests.
bool is_null(const boost::shared_ptr< T > &p)
basic_OSTab< char > OSTab
basic_FancyOStream< char > FancyOStream
const std::string passfail(const bool result)
Use the non-transposed operator.
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.
Use the transposed operator with complex-conjugate clements (same as TRANS for real scalar types)...
bool compare(const LinearOpBase< Scalar > &op1, const LinearOpBase< Scalar > &op2, const Ptr< MultiVectorRandomizerBase< Scalar > > &domainRandomizer, const Ptr< FancyOStream > &out_arg) const
Check if two linear operators are the same or not.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Base class for all linear operators.
void set_all_warning_tol(const ScalarMag warning_tol)
Set all the warning tolerances to the same value.
bool nonnull(const boost::shared_ptr< T > &p)
bool check(const LinearOpBase< Scalar > &op, const Ptr< MultiVectorRandomizerBase< Scalar > > &rangeRandomizer, const Ptr< MultiVectorRandomizerBase< Scalar > > &domainRandomizer, const Ptr< FancyOStream > &out) const
Check a linear operator.
TypeTo as(const TypeFrom &t)
Teuchos::ScalarTraits< Scalar >::magnitudeType ScalarMag
Local typedef for promoted scalar magnitude.
LinearOpTester()
Default constructor which sets default parameter values.
Base interface for a strategy object for randomizing a multi-vector.
#define TEUCHOS_TEST_EQUALITY_CONST(v1, v2, out, success)
void set_all_error_tol(const ScalarMag error_tol)
Set all the error tolerances to the same value.