00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef BELOS_MVOPTESTER_HPP
00030 #define BELOS_MVOPTESTER_HPP
00031
00032
00033
00034
00035
00036
00037
00046 #include "BelosConfigDefs.hpp"
00047 #include "BelosTypes.hpp"
00048
00049 #include "BelosMultiVecTraits.hpp"
00050 #include "BelosOperatorTraits.hpp"
00051 #include "BelosOutputManager.hpp"
00052
00053 #include "Teuchos_RCP.hpp"
00054
00059 namespace Belos {
00060
00066 template< class ScalarType, class MV >
00067 bool TestMultiVecTraits(
00068 const Teuchos::RCP<OutputManager<ScalarType> > &om,
00069 const Teuchos::RCP<const MV> &A ) {
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 typedef MultiVecTraits<ScalarType, MV> MVT;
00143 typedef Teuchos::ScalarTraits<ScalarType> SCT;
00144 typedef typename SCT::magnitudeType MagType;
00145
00146 const ScalarType one = SCT::one();
00147 const ScalarType zero = SCT::zero();
00148 const MagType zero_mag = Teuchos::ScalarTraits<MagType>::zero();
00149
00150
00151 const int numvecs = 10;
00152 const int numvecs_2 = 5;
00153
00154 int i,j;
00155 std::vector<int> ind(numvecs_2);
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 TEST_FOR_EXCEPT(numvecs_2 != 5);
00166 ind[0] = 0;
00167 ind[1] = 5;
00168 ind[2] = 2;
00169 ind[3] = 2;
00170 ind[4] = 9;
00171
00172
00173
00174
00175
00176 if ( MVT::GetNumberVecs(*A) <= 0 ) {
00177 om->stream(Warnings)
00178 << "*** ERROR *** MultiVectorTraits::GetNumberVecs()." << std::endl
00179 << "Returned <= 0." << std::endl;
00180 return false;
00181 }
00182
00183
00184
00185
00186
00187
00188 if ( MVT::GetVecLength(*A) <= 0 ) {
00189 om->stream(Warnings)
00190 << "*** ERROR *** MultiVectorTraits::GetVecLength()" << std::endl
00191 << "Returned <= 0." << std::endl;
00192 return false;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 {
00204 Teuchos::RCP<MV> B = MVT::Clone(*A,numvecs);
00205 std::vector<MagType> norms(2*numvecs);
00206 bool ResizeWarning = false;
00207 if ( MVT::GetNumberVecs(*B) != numvecs ) {
00208 om->stream(Warnings)
00209 << "*** ERROR *** MultiVecTraits::Clone()." << std::endl
00210 << "Did not allocate requested number of vectors." << std::endl;
00211 return false;
00212 }
00213 if ( MVT::GetVecLength(*B) != MVT::GetVecLength(*A) ) {
00214 om->stream(Warnings)
00215 << "*** ERROR *** MultiVecTraits::Clone()." << std::endl
00216 << "Did not allocate requested number of vectors." << std::endl;
00217 return false;
00218 }
00219 MVT::MvNorm(*B, norms);
00220 if ( norms.size() != 2*numvecs && ResizeWarning==false ) {
00221 om->stream(Warnings)
00222 << "*** WARNING *** MultiVecTraits::MvNorm()." << std::endl
00223 << "Method resized the output std::vector." << std::endl;
00224 ResizeWarning = true;
00225 }
00226 for (i=0; i<numvecs; i++) {
00227 if ( norms[i] < zero_mag ) {
00228 om->stream(Warnings)
00229 << "*** ERROR *** MultiVecTraits::Clone()." << std::endl
00230 << "Vector had negative norm." << std::endl;
00231 return false;
00232 }
00233 }
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 {
00253 Teuchos::RCP<MV> B = MVT::Clone(*A,numvecs);
00254 std::vector<MagType> norms(numvecs), norms2(numvecs);
00255
00256 MVT::MvInit(*B);
00257 MVT::MvNorm(*B, norms);
00258 for (i=0; i<numvecs; i++) {
00259 if ( norms[i] != zero_mag ) {
00260 om->stream(Warnings)
00261 << "*** ERROR *** MultiVecTraits::MvInit() "
00262 << "and MultiVecTraits::MvNorm()" << std::endl
00263 << "Supposedly zero std::vector has non-zero norm." << std::endl;
00264 return false;
00265 }
00266 }
00267 MVT::MvRandom(*B);
00268 MVT::MvNorm(*B, norms);
00269 MVT::MvRandom(*B);
00270 MVT::MvNorm(*B, norms2);
00271 for (i=0; i<numvecs; i++) {
00272 if ( norms[i] == zero_mag || norms2[i] == zero_mag ) {
00273 om->stream(Warnings)
00274 << "*** ERROR *** MultiVecTraits::MvRandom()." << std::endl
00275 << "Random std::vector was empty (very unlikely)." << std::endl;
00276 return false;
00277 }
00278 else if ( norms[i] < zero_mag || norms2[i] < zero_mag ) {
00279 om->stream(Warnings)
00280 << "*** ERROR *** MultiVecTraits::MvRandom()." << std::endl
00281 << "Vector had negative norm." << std::endl;
00282 return false;
00283 }
00284 else if ( norms[i] == norms2[i] ) {
00285 om->stream(Warnings)
00286 << "*** ERROR *** MutliVecTraits::MvRandom()." << std::endl
00287 << "Vectors not random enough." << std::endl;
00288 return false;
00289 }
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 {
00308 Teuchos::RCP<MV> B = MVT::Clone(*A,numvecs);
00309 std::vector<MagType> norms(numvecs);
00310
00311 MVT::MvInit(*B,one);
00312 MVT::MvNorm(*B, norms);
00313 bool BadNormWarning = false;
00314 for (i=0; i<numvecs; i++) {
00315 if ( norms[i] < zero_mag ) {
00316 om->stream(Warnings)
00317 << "*** ERROR *** MultiVecTraits::MvRandom()." << std::endl
00318 << "Vector had negative norm." << std::endl;
00319 return false;
00320 }
00321 else if ( norms[i] != SCT::squareroot(MVT::GetVecLength(*B)) && !BadNormWarning ) {
00322 om->stream(Warnings)
00323 << std::endl
00324 << "Warning testing MultiVecTraits::MvInit()." << std::endl
00325 << "Ones std::vector should have norm std::sqrt(dim)." << std::endl
00326 << "norms[i]: " << norms[i] << "\tdim: " << MVT::GetVecLength(*B) << std::endl << std::endl;
00327 BadNormWarning = true;
00328 }
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 {
00341 Teuchos::RCP<MV> B = MVT::Clone(*A,numvecs);
00342 std::vector<MagType> norms(numvecs);
00343 MVT::MvInit(*B, zero_mag);
00344 MVT::MvNorm(*B, norms);
00345 for (i=0; i<numvecs; i++) {
00346 if ( norms[i] < zero_mag ) {
00347 om->stream(Warnings)
00348 << "*** ERROR *** MultiVecTraits::MvInit()." << std::endl
00349 << "Vector had negative norm." << std::endl;
00350 return false;
00351 }
00352 else if ( norms[i] != zero_mag ) {
00353 om->stream(Warnings)
00354 << "*** ERROR *** MultiVecTraits::MvInit()." << std::endl
00355 << "Zero std::vector should have norm zero." << std::endl;
00356 return false;
00357 }
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367 {
00368 Teuchos::RCP<MV> B, C;
00369 std::vector<MagType> norms(numvecs), norms2(numvecs);
00370
00371 B = MVT::Clone(*A,numvecs);
00372 MVT::MvRandom(*B);
00373 MVT::MvNorm(*B, norms);
00374 C = MVT::CloneCopy(*B,ind);
00375 MVT::MvNorm(*C, norms2);
00376 if ( MVT::GetNumberVecs(*C) != numvecs_2 ) {
00377 om->stream(Warnings)
00378 << "*** ERROR *** MultiVecTraits::CloneCopy(ind)." << std::endl
00379 << "Wrong number of vectors." << std::endl;
00380 return false;
00381 }
00382 if ( MVT::GetVecLength(*C) != MVT::GetVecLength(*B) ) {
00383 om->stream(Warnings)
00384 << "*** ERROR *** MultiVecTraits::CloneCopy(ind)." << std::endl
00385 << "Vector lengths don't match." << std::endl;
00386 return false;
00387 }
00388 for (i=0; i<numvecs_2; i++) {
00389 if ( norms2[i] != norms[ind[i]] ) {
00390 om->stream(Warnings)
00391 << "*** ERROR *** MultiVecTraits::CloneCopy(ind)." << std::endl
00392 << "Copied vectors do not agree: "
00393 << norms2[i] << " != " << norms[ind[i]] << std::endl;
00394 MVT::MvPrint(*B,std::cout);
00395 MVT::MvPrint(*C,std::cout);
00396 return false;
00397 }
00398 }
00399 MVT::MvInit(*B,zero);
00400 MVT::MvNorm(*C, norms);
00401 for (i=0; i<numvecs_2; i++) {
00402 if ( norms2[i] != norms[i] ) {
00403 om->stream(Warnings)
00404 << "*** ERROR *** MultiVecTraits::CloneCopy(ind)." << std::endl
00405 << "Copied vectors were not independent." << std::endl;
00406 return false;
00407 }
00408 }
00409 }
00410
00411
00412
00413
00414
00415
00416 {
00417 Teuchos::RCP<MV> B, C;
00418 std::vector<MagType> norms(numvecs), norms2(numvecs);
00419
00420 B = MVT::Clone(*A,numvecs);
00421 MVT::MvRandom(*B);
00422 MVT::MvNorm(*B, norms);
00423 C = MVT::CloneCopy(*B);
00424 MVT::MvNorm(*C, norms2);
00425 if ( MVT::GetNumberVecs(*C) != numvecs ) {
00426 om->stream(Warnings)
00427 << "*** ERROR *** MultiVecTraits::CloneCopy()." << std::endl
00428 << "Wrong number of vectors." << std::endl;
00429 return false;
00430 }
00431 for (i=0; i<numvecs; i++) {
00432 if ( norms2[i] != norms[i] ) {
00433 om->stream(Warnings)
00434 << "*** ERROR *** MultiVecTraits::CloneCopy()." << std::endl
00435 << "Copied vectors do not agree." << std::endl;
00436 return false;
00437 }
00438 }
00439 MVT::MvInit(*B,zero);
00440 MVT::MvNorm(*C, norms);
00441 for (i=0; i<numvecs; i++) {
00442 if ( norms2[i] != norms[i] ) {
00443 om->stream(Warnings)
00444 << "*** ERROR *** MultiVecTraits::CloneCopy()." << std::endl
00445 << "Copied vectors were not independent." << std::endl;
00446 return false;
00447 }
00448 }
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458 {
00459 Teuchos::RCP<MV> B, C;
00460 std::vector<MagType> norms(numvecs), norms2(numvecs);
00461
00462 B = MVT::Clone(*A,numvecs);
00463 MVT::MvRandom(*B);
00464 MVT::MvNorm(*B, norms);
00465 C = MVT::CloneView(*B,ind);
00466 MVT::MvNorm(*C, norms2);
00467 if ( MVT::GetNumberVecs(*C) != numvecs_2 ) {
00468 om->stream(Warnings)
00469 << "*** ERROR *** MultiVecTraits::CloneView(ind)." << std::endl
00470 << "Wrong number of vectors." << std::endl;
00471 return false;
00472 }
00473 for (i=0; i<numvecs_2; i++) {
00474 if ( norms2[i] != norms[ind[i]] ) {
00475 om->stream(Warnings)
00476 << "*** ERROR *** MultiVecTraits::CloneView(ind)." << std::endl
00477 << "Viewed vectors do not agree." << std::endl;
00478 return false;
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503 {
00504 Teuchos::RCP<MV> B;
00505 Teuchos::RCP<const MV> constB, C;
00506 std::vector<MagType> normsB(numvecs), normsC(numvecs_2);
00507 std::vector<int> allind(numvecs);
00508 for (i=0; i<numvecs; i++) {
00509 allind[i] = i;
00510 }
00511
00512 B = MVT::Clone(*A,numvecs);
00513 MVT::MvRandom( *B );
00514
00515 constB = MVT::CloneView(*B,allind);
00516 MVT::MvNorm(*constB, normsB);
00517 C = MVT::CloneView(*constB,ind);
00518 MVT::MvNorm(*C, normsC);
00519 if ( MVT::GetNumberVecs(*C) != numvecs_2 ) {
00520 om->stream(Warnings)
00521 << "*** ERROR *** const MultiVecTraits::CloneView(ind)." << std::endl
00522 << "Wrong number of vectors." << std::endl;
00523 return false;
00524 }
00525 for (i=0; i<numvecs_2; i++) {
00526 if ( normsC[i] != normsB[ind[i]] ) {
00527 om->stream(Warnings)
00528 << "*** ERROR *** const MultiVecTraits::CloneView(ind)." << std::endl
00529 << "Viewed vectors do not agree." << std::endl;
00530 return false;
00531 }
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 {
00561 Teuchos::RCP<MV> B, C;
00562 std::vector<MagType> normsB1(numvecs), normsB2(numvecs),
00563 normsC1(numvecs_2), normsC2(numvecs_2);
00564
00565 B = MVT::Clone(*A,numvecs);
00566 C = MVT::Clone(*A,numvecs_2);
00567
00568 ind.resize(numvecs_2);
00569 for (i=0; i<numvecs_2; i++) {
00570 ind[i] = 2*i;
00571 }
00572 MVT::MvRandom(*B);
00573 MVT::MvRandom(*C);
00574
00575 MVT::MvNorm(*B,normsB1);
00576 MVT::MvNorm(*C,normsC1);
00577 MVT::SetBlock(*C,ind,*B);
00578 MVT::MvNorm(*B,normsB2);
00579 MVT::MvNorm(*C,normsC2);
00580
00581
00582 for (i=0; i<numvecs_2; i++) {
00583 if ( normsC1[i] != normsC2[i] ) {
00584 om->stream(Warnings)
00585 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00586 << "Operation modified source vectors." << std::endl;
00587 return false;
00588 }
00589 }
00590
00591
00592 for (i=0; i<numvecs; i++) {
00593 if (i % 2 == 0) {
00594
00595 if ( normsB2[i] != normsC1[i/2] ) {
00596 om->stream(Warnings)
00597 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00598 << "Copied vectors do not agree." << std::endl;
00599 return false;
00600 }
00601 }
00602 else {
00603
00604 if ( normsB1[i] != normsB2[i] ) {
00605 om->stream(Warnings)
00606 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00607 << "Incorrect vectors were modified." << std::endl;
00608 return false;
00609 }
00610 }
00611 }
00612 MVT::MvInit(*C,zero);
00613 MVT::MvNorm(*B,normsB1);
00614
00615 for (i=0; i<numvecs; i++) {
00616 if ( normsB1[i] != normsB2[i] ) {
00617 om->stream(Warnings)
00618 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00619 << "Copied vectors were not independent." << std::endl;
00620 return false;
00621 }
00622 }
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 {
00642 Teuchos::RCP<MV> B, C;
00643
00644 const int CSize = 6,
00645 setSize = 5,
00646 BSize = 2*setSize;
00647 std::vector<MagType> normsB1(BSize), normsB2(BSize),
00648 normsC1(CSize), normsC2(CSize);
00649
00650 B = MVT::Clone(*A,BSize);
00651 C = MVT::Clone(*A,CSize);
00652
00653 ind.resize(setSize);
00654 for (i=0; i<setSize; i++) {
00655 ind[i] = 2*i;
00656 }
00657 MVT::MvRandom(*B);
00658 MVT::MvRandom(*C);
00659
00660 MVT::MvNorm(*B,normsB1);
00661 MVT::MvNorm(*C,normsC1);
00662 MVT::SetBlock(*C,ind,*B);
00663 MVT::MvNorm(*B,normsB2);
00664 MVT::MvNorm(*C,normsC2);
00665
00666
00667 for (i=0; i<CSize; i++) {
00668 if ( normsC1[i] != normsC2[i] ) {
00669 om->stream(Warnings)
00670 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00671 << "Operation modified source vectors." << std::endl;
00672 return false;
00673 }
00674 }
00675
00676
00677 for (i=0; i<BSize; i++) {
00678 if (i % 2 == 0) {
00679
00680 if ( normsB2[i] != normsC1[i/2] ) {
00681 om->stream(Warnings)
00682 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00683 << "Copied vectors do not agree." << std::endl;
00684 return false;
00685 }
00686 }
00687 else {
00688
00689 if ( normsB1[i] != normsB2[i] ) {
00690 om->stream(Warnings)
00691 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00692 << "Incorrect vectors were modified." << std::endl;
00693 return false;
00694 }
00695 }
00696 }
00697 MVT::MvInit(*C,zero);
00698 MVT::MvNorm(*B,normsB1);
00699
00700 for (i=0; i<numvecs; i++) {
00701 if ( normsB1[i] != normsB2[i] ) {
00702 om->stream(Warnings)
00703 << "*** ERROR *** MultiVecTraits::SetBlock()." << std::endl
00704 << "Copied vectors were not independent." << std::endl;
00705 return false;
00706 }
00707 }
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 {
00731 const int p = 7;
00732 const int q = 9;
00733 Teuchos::RCP<MV> B, C;
00734 std::vector<MagType> normsB(p), normsC(q);
00735 Teuchos::SerialDenseMatrix<int,ScalarType> SDM(p,q);
00736
00737 B = MVT::Clone(*A,p);
00738 C = MVT::Clone(*A,q);
00739
00740
00741 MVT::MvRandom(*B);
00742 MVT::MvNorm(*B,normsB);
00743 MVT::MvRandom(*C);
00744 MVT::MvNorm(*C,normsC);
00745
00746
00747 MVT::MvTransMv( zero, *B, *C, SDM );
00748
00749
00750 if ( SDM.numRows() != p || SDM.numCols() != q ) {
00751 om->stream(Warnings)
00752 << "*** ERROR *** MultiVecTraits::MvTransMv()." << std::endl
00753 << "Routine resized SerialDenseMatrix." << std::endl;
00754 return false;
00755 }
00756
00757
00758 if ( SDM.normOne() != zero ) {
00759 om->stream(Warnings)
00760 << "*** ERROR *** MultiVecTraits::MvTransMv()." << std::endl
00761 << "Scalar argument processed incorrectly." << std::endl;
00762 return false;
00763 }
00764
00765
00766 MVT::MvTransMv( one, *B, *C, SDM );
00767
00768
00769
00770 for (i=0; i<p; i++) {
00771 for (j=0; j<q; j++) {
00772 if ( SCT::magnitude(SDM(i,j))
00773 > SCT::magnitude(normsB[i]*normsC[j]) ) {
00774 om->stream(Warnings)
00775 << "*** ERROR *** MultiVecTraits::MvTransMv()." << std::endl
00776 << "Triangle inequality did not hold: "
00777 << SCT::magnitude(SDM(i,j))
00778 << " > "
00779 << SCT::magnitude(normsB[i]*normsC[j])
00780 << std::endl;
00781 return false;
00782 }
00783 }
00784 }
00785 MVT::MvInit(*C);
00786 MVT::MvRandom(*B);
00787 MVT::MvTransMv( one, *B, *C, SDM );
00788 for (i=0; i<p; i++) {
00789 for (j=0; j<q; j++) {
00790 if ( SDM(i,j) != zero ) {
00791 om->stream(Warnings)
00792 << "*** ERROR *** MultiVecTraits::MvTransMv()." << std::endl
00793 << "Inner products not zero for C==0." << std::endl;
00794 return false;
00795 }
00796 }
00797 }
00798 MVT::MvInit(*B);
00799 MVT::MvRandom(*C);
00800 MVT::MvTransMv( one, *B, *C, SDM );
00801 for (i=0; i<p; i++) {
00802 for (j=0; j<q; j++) {
00803 if ( SDM(i,j) != zero ) {
00804 om->stream(Warnings)
00805 << "*** ERROR *** MultiVecTraits::MvTransMv()." << std::endl
00806 << "Inner products not zero for B==0." << std::endl;
00807 return false;
00808 }
00809 }
00810 }
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820 {
00821 const int p = 7;
00822 const int q = 9;
00823 Teuchos::RCP<MV> B, C;
00824 std::vector<ScalarType> iprods(p+q);
00825 std::vector<MagType> normsB(numvecs), normsC(numvecs);
00826
00827 B = MVT::Clone(*A,p);
00828 C = MVT::Clone(*A,p);
00829
00830 MVT::MvRandom(*B);
00831 MVT::MvRandom(*C);
00832 MVT::MvNorm(*B,normsB);
00833 MVT::MvNorm(*C,normsC);
00834 MVT::MvDot( *B, *C, iprods );
00835 if ( iprods.size() != p+q ) {
00836 om->stream(Warnings)
00837 << "*** ERROR *** MultiVecTraits::MvDot." << std::endl
00838 << "Routine resized results std::vector." << std::endl;
00839 return false;
00840 }
00841 for (i=0; i<BELOS_MIN(p,q); i++) {
00842 if ( SCT::magnitude(iprods[i])
00843 > SCT::magnitude(normsB[i]*normsC[i]) ) {
00844 om->stream(Warnings)
00845 << "*** ERROR *** MultiVecTraits::MvDot()." << std::endl
00846 << "Inner products not valid." << std::endl;
00847 return false;
00848 }
00849 }
00850 MVT::MvInit(*B);
00851 MVT::MvRandom(*C);
00852 MVT::MvDot( *B, *C, iprods );
00853 for (i=0; i<p; i++) {
00854 if ( iprods[i] != zero ) {
00855 om->stream(Warnings)
00856 << "*** ERROR *** MultiVecTraits::MvDot()." << std::endl
00857 << "Inner products not zero for B==0." << std::endl;
00858 return false;
00859 }
00860 }
00861 MVT::MvInit(*C);
00862 MVT::MvRandom(*B);
00863 MVT::MvDot( *B, *C, iprods );
00864 for (i=0; i<p; i++) {
00865 if ( iprods[i] != zero ) {
00866 om->stream(Warnings)
00867 << "*** ERROR *** MultiVecTraits::MvDot()." << std::endl
00868 << "Inner products not zero for C==0." << std::endl;
00869 return false;
00870 }
00871 }
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 {
00883 const int p = 7;
00884 Teuchos::RCP<MV> B, C, D;
00885 std::vector<MagType> normsB1(p), normsB2(p),
00886 normsC1(p), normsC2(p),
00887 normsD1(p), normsD2(p);
00888 ScalarType alpha = SCT::random(),
00889 beta = SCT::random();
00890
00891 B = MVT::Clone(*A,p);
00892 C = MVT::Clone(*A,p);
00893 D = MVT::Clone(*A,p);
00894
00895 MVT::MvRandom(*B);
00896 MVT::MvRandom(*C);
00897 MVT::MvNorm(*B,normsB1);
00898 MVT::MvNorm(*C,normsC1);
00899
00900
00901 MVT::MvAddMv(zero,*B,one,*C,*D);
00902 MVT::MvNorm(*B,normsB2);
00903 MVT::MvNorm(*C,normsC2);
00904 MVT::MvNorm(*D,normsD1);
00905 for (i=0; i<p; i++) {
00906 if ( normsB1[i] != normsB2[i] ) {
00907 om->stream(Warnings)
00908 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00909 << "Input arguments were modified." << std::endl;
00910 return false;
00911 }
00912 else if ( normsC1[i] != normsC2[i] ) {
00913 om->stream(Warnings)
00914 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00915 << "Input arguments were modified." << std::endl;
00916 return false;
00917 }
00918 else if ( normsC1[i] != normsD1[i] ) {
00919 om->stream(Warnings)
00920 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00921 << "Assignment did not work." << std::endl;
00922 return false;
00923 }
00924 }
00925
00926
00927 MVT::MvAddMv(one,*B,zero,*C,*D);
00928 MVT::MvNorm(*B,normsB2);
00929 MVT::MvNorm(*C,normsC2);
00930 MVT::MvNorm(*D,normsD1);
00931 for (i=0; i<p; i++) {
00932 if ( normsB1[i] != normsB2[i] ) {
00933 om->stream(Warnings)
00934 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00935 << "Input arguments were modified." << std::endl;
00936 return false;
00937 }
00938 else if ( normsC1[i] != normsC2[i] ) {
00939 om->stream(Warnings)
00940 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00941 << "Input arguments were modified." << std::endl;
00942 return false;
00943 }
00944 else if ( normsB1[i] != normsD1[i] ) {
00945 om->stream(Warnings)
00946 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00947 << "Assignment did not work." << std::endl;
00948 return false;
00949 }
00950 }
00951
00952
00953
00954 MVT::MvRandom(*D);
00955 MVT::MvAddMv(alpha,*B,beta,*C,*D);
00956 MVT::MvNorm(*B,normsB2);
00957 MVT::MvNorm(*C,normsC2);
00958 MVT::MvNorm(*D,normsD1);
00959
00960 for (i=0; i<p; i++) {
00961 if ( normsB1[i] != normsB2[i] ) {
00962 om->stream(Warnings)
00963 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00964 << "Input arguments were modified." << std::endl;
00965 return false;
00966 }
00967 else if ( normsC1[i] != normsC2[i] ) {
00968 om->stream(Warnings)
00969 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00970 << "Input arguments were modified." << std::endl;
00971 return false;
00972 }
00973 }
00974
00975 MVT::MvInit(*D);
00976 MVT::MvAddMv(alpha,*B,beta,*C,*D);
00977 MVT::MvNorm(*B,normsB2);
00978 MVT::MvNorm(*C,normsC2);
00979 MVT::MvNorm(*D,normsD2);
00980
00981
00982 for (i=0; i<p; i++) {
00983 if ( normsB1[i] != normsB2[i] ) {
00984 om->stream(Warnings)
00985 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00986 << "Input arguments were modified." << std::endl;
00987 return false;
00988 }
00989 else if ( normsC1[i] != normsC2[i] ) {
00990 om->stream(Warnings)
00991 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00992 << "Input arguments were modified." << std::endl;
00993 return false;
00994 }
00995 else if ( normsD1[i] != normsD2[i] ) {
00996 om->stream(Warnings)
00997 << "*** ERROR *** MultiVecTraits::MvAddMv()." << std::endl
00998 << "Results varies depending on initial state of dest vectors." << std::endl;
00999 return false;
01000 }
01001 }
01002 }
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 {
01023 const int p = 7;
01024 Teuchos::RCP<MV> B, C, D;
01025 std::vector<MagType> normsB(p),
01026 normsD(p);
01027 std::vector<int> lclindex(p);
01028 for (i=0; i<p; i++) lclindex[i] = i;
01029
01030 B = MVT::Clone(*A,p);
01031 C = MVT::CloneView(*B,lclindex);
01032 D = MVT::CloneView(*B,lclindex);
01033
01034 MVT::MvRandom(*B);
01035 MVT::MvNorm(*B,normsB);
01036
01037
01038 MVT::MvAddMv(zero,*B,one,*C,*D);
01039 MVT::MvNorm(*D,normsD);
01040 for (i=0; i<p; i++) {
01041 if ( normsB[i] != normsD[i] ) {
01042 om->stream(Warnings)
01043 << "*** ERROR *** MultiVecTraits::MvAddMv() #2" << std::endl
01044 << "Assignment did not work." << std::endl;
01045 return false;
01046 }
01047 }
01048
01049
01050 MVT::MvAddMv(one,*B,zero,*C,*D);
01051 MVT::MvNorm(*D,normsD);
01052 for (i=0; i<p; i++) {
01053 if ( normsB[i] != normsD[i] ) {
01054 om->stream(Warnings)
01055 << "*** ERROR *** MultiVecTraits::MvAddMv() #2" << std::endl
01056 << "Assignment did not work." << std::endl;
01057 return false;
01058 }
01059 }
01060
01061 }
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073 {
01074 const int p = 7, q = 5;
01075 Teuchos::RCP<MV> B, C;
01076 Teuchos::SerialDenseMatrix<int,ScalarType> SDM(p,q);
01077 std::vector<MagType> normsC1(q), normsC2(q),
01078 normsB1(p), normsB2(p);
01079
01080 B = MVT::Clone(*A,p);
01081 C = MVT::Clone(*A,q);
01082
01083
01084 MVT::MvRandom(*B);
01085 MVT::MvRandom(*C);
01086 MVT::MvNorm(*B,normsB1);
01087 MVT::MvNorm(*C,normsC1);
01088 SDM.random();
01089 MVT::MvTimesMatAddMv(zero,*B,SDM,one,*C);
01090 MVT::MvNorm(*B,normsB2);
01091 MVT::MvNorm(*C,normsC2);
01092 for (i=0; i<p; i++) {
01093 if ( normsB1[i] != normsB2[i] ) {
01094 om->stream(Warnings)
01095 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01096 << "Input vectors were modified." << std::endl;
01097 return false;
01098 }
01099 }
01100 for (i=0; i<q; i++) {
01101 if ( normsC1[i] != normsC2[i] ) {
01102 om->stream(Warnings)
01103 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01104 << "Arithmetic test 1 failed." << std::endl;
01105 return false;
01106 }
01107 }
01108
01109
01110 MVT::MvRandom(*B);
01111 MVT::MvRandom(*C);
01112 MVT::MvNorm(*B,normsB1);
01113 MVT::MvNorm(*C,normsC1);
01114 SDM.random();
01115 MVT::MvTimesMatAddMv(zero,*B,SDM,zero,*C);
01116 MVT::MvNorm(*B,normsB2);
01117 MVT::MvNorm(*C,normsC2);
01118 for (i=0; i<p; i++) {
01119 if ( normsB1[i] != normsB2[i] ) {
01120 om->stream(Warnings)
01121 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01122 << "Input vectors were modified." << std::endl;
01123 return false;
01124 }
01125 }
01126 for (i=0; i<q; i++) {
01127 if ( normsC2[i] != zero ) {
01128 om->stream(Warnings)
01129 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01130 << "Arithmetic test 2 failed: "
01131 << normsC2[i]
01132 << " != "
01133 << zero
01134 << std::endl;
01135 return false;
01136 }
01137 }
01138
01139
01140
01141 MVT::MvRandom(*B);
01142 MVT::MvRandom(*C);
01143 MVT::MvNorm(*B,normsB1);
01144 MVT::MvNorm(*C,normsC1);
01145 SDM.scale(zero);
01146 for (i=0; i<q; i++) {
01147 SDM(i,i) = one;
01148 }
01149 MVT::MvTimesMatAddMv(one,*B,SDM,zero,*C);
01150 MVT::MvNorm(*B,normsB2);
01151 MVT::MvNorm(*C,normsC2);
01152 for (i=0; i<p; i++) {
01153 if ( normsB1[i] != normsB2[i] ) {
01154 om->stream(Warnings)
01155 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01156 << "Input vectors were modified." << std::endl;
01157 return false;
01158 }
01159 }
01160 for (i=0; i<q; i++) {
01161 if ( normsB1[i] != normsC2[i] ) {
01162 om->stream(Warnings)
01163 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01164 << "Arithmetic test 3 failed: "
01165 << normsB1[i]
01166 << " != "
01167 << normsC2[i]
01168 << std::endl;
01169 return false;
01170 }
01171 }
01172
01173
01174 MVT::MvRandom(*B);
01175 MVT::MvRandom(*C);
01176 MVT::MvNorm(*B,normsB1);
01177 MVT::MvNorm(*C,normsC1);
01178 SDM.scale(zero);
01179 MVT::MvTimesMatAddMv(one,*B,SDM,one,*C);
01180 MVT::MvNorm(*B,normsB2);
01181 MVT::MvNorm(*C,normsC2);
01182 for (i=0; i<p; i++) {
01183 if ( normsB1[i] != normsB2[i] ) {
01184 om->stream(Warnings)
01185 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01186 << "Input vectors were modified." << std::endl;
01187 return false;
01188 }
01189 }
01190 for (i=0; i<q; i++) {
01191 if ( normsC1[i] != normsC2[i] ) {
01192 om->stream(Warnings)
01193 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01194 << "Arithmetic test 4 failed." << std::endl;
01195 return false;
01196 }
01197 }
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209 {
01210 const int p = 5, q = 7;
01211 Teuchos::RCP<MV> B, C;
01212 Teuchos::SerialDenseMatrix<int,ScalarType> SDM(p,q);
01213 std::vector<MagType> normsC1(q), normsC2(q),
01214 normsB1(p), normsB2(p);
01215
01216 B = MVT::Clone(*A,p);
01217 C = MVT::Clone(*A,q);
01218
01219
01220 MVT::MvRandom(*B);
01221 MVT::MvRandom(*C);
01222 MVT::MvNorm(*B,normsB1);
01223 MVT::MvNorm(*C,normsC1);
01224 SDM.random();
01225 MVT::MvTimesMatAddMv(zero,*B,SDM,one,*C);
01226 MVT::MvNorm(*B,normsB2);
01227 MVT::MvNorm(*C,normsC2);
01228 for (i=0; i<p; i++) {
01229 if ( normsB1[i] != normsB2[i] ) {
01230 om->stream(Warnings)
01231 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01232 << "Input vectors were modified." << std::endl;
01233 return false;
01234 }
01235 }
01236 for (i=0; i<q; i++) {
01237 if ( normsC1[i] != normsC2[i] ) {
01238 om->stream(Warnings)
01239 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01240 << "Arithmetic test 5 failed." << std::endl;
01241 return false;
01242 }
01243 }
01244
01245
01246 MVT::MvRandom(*B);
01247 MVT::MvRandom(*C);
01248 MVT::MvNorm(*B,normsB1);
01249 MVT::MvNorm(*C,normsC1);
01250 SDM.random();
01251 MVT::MvTimesMatAddMv(zero,*B,SDM,zero,*C);
01252 MVT::MvNorm(*B,normsB2);
01253 MVT::MvNorm(*C,normsC2);
01254 for (i=0; i<p; i++) {
01255 if ( normsB1[i] != normsB2[i] ) {
01256 om->stream(Warnings)
01257 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01258 << "Input vectors were modified." << std::endl;
01259 return false;
01260 }
01261 }
01262 for (i=0; i<q; i++) {
01263 if ( normsC2[i] != zero ) {
01264 om->stream(Warnings)
01265 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01266 << "Arithmetic test 6 failed: "
01267 << normsC2[i]
01268 << " != "
01269 << zero
01270 << std::endl;
01271 return false;
01272 }
01273 }
01274
01275
01276 MVT::MvRandom(*B);
01277 MVT::MvRandom(*C);
01278 MVT::MvNorm(*B,normsB1);
01279 MVT::MvNorm(*C,normsC1);
01280 SDM.scale(zero);
01281 for (i=0; i<p; i++) {
01282 SDM(i,i) = one;
01283 }
01284 MVT::MvTimesMatAddMv(one,*B,SDM,zero,*C);
01285 MVT::MvNorm(*B,normsB2);
01286 MVT::MvNorm(*C,normsC2);
01287 for (i=0; i<p; i++) {
01288 if ( normsB1[i] != normsB2[i] ) {
01289 om->stream(Warnings)
01290 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01291 << "Input vectors were modified." << std::endl;
01292 return false;
01293 }
01294 }
01295 for (i=0; i<p; i++) {
01296 if ( normsB1[i] != normsC2[i] ) {
01297 om->stream(Warnings)
01298 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01299 << "Arithmetic test 7 failed." << std::endl;
01300 return false;
01301 }
01302 }
01303 for (i=p; i<q; i++) {
01304 if ( normsC2[i] != zero ) {
01305 om->stream(Warnings)
01306 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01307 << "Arithmetic test 7 failed." << std::endl;
01308 return false;
01309 }
01310 }
01311
01312
01313 MVT::MvRandom(*B);
01314 MVT::MvRandom(*C);
01315 MVT::MvNorm(*B,normsB1);
01316 MVT::MvNorm(*C,normsC1);
01317 SDM.scale(zero);
01318 MVT::MvTimesMatAddMv(one,*B,SDM,one,*C);
01319 MVT::MvNorm(*B,normsB2);
01320 MVT::MvNorm(*C,normsC2);
01321 for (i=0; i<p; i++) {
01322 if ( normsB1[i] != normsB2[i] ) {
01323 om->stream(Warnings)
01324 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01325 << "Input vectors were modified." << std::endl;
01326 return false;
01327 }
01328 }
01329 for (i=0; i<q; i++) {
01330 if ( normsC1[i] != normsC2[i] ) {
01331 om->stream(Warnings)
01332 << "*** ERROR *** MultiVecTraits::MvTimesMatAddMv()." << std::endl
01333 << "Arithmetic test 8 failed." << std::endl;
01334 return false;
01335 }
01336 }
01337 }
01338
01339 return true;
01340
01341 }
01342
01343
01344
01350 template< class ScalarType, class MV, class OP>
01351 bool TestOperatorTraits(
01352 const Teuchos::RCP<OutputManager<ScalarType> > &om,
01353 const Teuchos::RCP<const MV> &A,
01354 const Teuchos::RCP<const OP> &M) {
01355
01356
01357
01358
01359
01360
01361
01362
01363 typedef MultiVecTraits<ScalarType, MV> MVT;
01364 typedef Teuchos::ScalarTraits<ScalarType> SCT;
01365 typedef OperatorTraits<ScalarType, MV, OP> OPT;
01366 typedef typename SCT::magnitudeType MagType;
01367
01368 const int numvecs = 10;
01369
01370 Teuchos::RCP<MV> B = MVT::Clone(*A,numvecs),
01371 C = MVT::Clone(*A,numvecs);
01372
01373 std::vector<MagType> normsB1(numvecs), normsB2(numvecs),
01374 normsC1(numvecs), normsC2(numvecs);
01375 bool NonDeterministicWarning;
01376 int i;
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386 MVT::MvInit(*B);
01387 MVT::MvRandom(*C);
01388 MVT::MvNorm(*B,normsB1);
01389 OPT::Apply(*M,*B,*C);
01390 MVT::MvNorm(*B,normsB2);
01391 MVT::MvNorm(*C,normsC2);
01392 for (i=0; i<numvecs; i++) {
01393 if (normsB2[i] != normsB1[i]) {
01394 om->stream(Warnings)
01395 << "*** ERROR *** OperatorTraits::Apply() [1]" << std::endl
01396 << "Apply() modified the input vectors." << std::endl;
01397 return false;
01398 }
01399 if (normsC2[i] != SCT::zero()) {
01400 om->stream(Warnings)
01401 << "*** ERROR *** OperatorTraits::Apply() [1]" << std::endl
01402 << "Operator applied to zero did not return zero." << std::endl;
01403 return false;
01404 }
01405 }
01406
01407
01408 MVT::MvRandom(*B);
01409 MVT::MvNorm(*B,normsB1);
01410 OPT::Apply(*M,*B,*C);
01411 MVT::MvNorm(*B,normsB2);
01412 MVT::MvNorm(*C,normsC2);
01413 bool ZeroWarning = false;
01414 for (i=0; i<numvecs; i++) {
01415 if (normsB2[i] != normsB1[i]) {
01416 om->stream(Warnings)
01417 << "*** ERROR *** OperatorTraits::Apply() [2]" << std::endl
01418 << "Apply() modified the input vectors." << std::endl;
01419 return false;
01420 }
01421 if (normsC2[i] == SCT::zero() && ZeroWarning==false ) {
01422 om->stream(Warnings)
01423 << "*** ERROR *** OperatorTraits::Apply() [2]" << std::endl
01424 << "Operator applied to random vectors returned zero." << std::endl;
01425 ZeroWarning = true;
01426 }
01427 }
01428
01429
01430 MVT::MvRandom(*B);
01431 MVT::MvNorm(*B,normsB1);
01432 MVT::MvInit(*C);
01433 OPT::Apply(*M,*B,*C);
01434 MVT::MvNorm(*B,normsB2);
01435 MVT::MvNorm(*C,normsC1);
01436 for (i=0; i<numvecs; i++) {
01437 if (normsB2[i] != normsB1[i]) {
01438 om->stream(Warnings)
01439 << "*** ERROR *** OperatorTraits::Apply() [3]" << std::endl
01440 << "Apply() modified the input vectors." << std::endl;
01441 return false;
01442 }
01443 }
01444
01445
01446
01447
01448
01449
01450 MVT::MvRandom(*C);
01451 OPT::Apply(*M,*B,*C);
01452 MVT::MvNorm(*B,normsB2);
01453 MVT::MvNorm(*C,normsC2);
01454 NonDeterministicWarning = false;
01455 for (i=0; i<numvecs; i++) {
01456 if (normsB2[i] != normsB1[i]) {
01457 om->stream(Warnings)
01458 << "*** ERROR *** OperatorTraits::Apply() [4]" << std::endl
01459 << "Apply() modified the input vectors." << std::endl;
01460 return false;
01461 }
01462 if (normsC1[i] != normsC2[i] && !NonDeterministicWarning) {
01463 om->stream(Warnings)
01464 << std::endl
01465 << "*** WARNING *** OperatorTraits::Apply() [4]" << std::endl
01466 << "Apply() returned two different results." << std::endl << std::endl;
01467 NonDeterministicWarning = true;
01468 }
01469 }
01470
01471 return true;
01472
01473 }
01474
01475 }
01476
01477 #endif