|
Anasazi Version of the Day
|
00001 // @HEADER 00002 // *********************************************************************** 00003 // 00004 // Anasazi: Block Eigensolvers Package 00005 // Copyright (2010) Sandia Corporation 00006 // 00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00008 // license for use of this work by or on behalf of the U.S. Government. 00009 // 00010 // This library is free software; you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as 00012 // published by the Free Software Foundation; either version 2.1 of the 00013 // License, or (at your option) any later version. 00014 // 00015 // This library is distributed in the hope that it will be useful, but 00016 // WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 // Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public 00021 // License along with this library; if not, write to the Free Software 00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 00023 // USA 00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 00025 // 00026 // *********************************************************************** 00027 // @HEADER 00028 00029 #include "Tsqr_CombineTest.hpp" 00030 00031 #include <Tsqr_Random_NormalGenerator.hpp> 00032 #include <Tsqr_Random_MatrixGenerator.hpp> 00033 00034 #include <Tsqr_Combine.hpp> 00035 #include <Tsqr_LocalVerify.hpp> 00036 #include <Tsqr_Matrix.hpp> 00037 #include <Tsqr_ScalarTraits.hpp> 00038 #include <Tsqr_Util.hpp> 00039 00040 #include <algorithm> 00041 #include <iostream> 00042 #include <limits> 00043 #include <sstream> 00044 #include <stdexcept> 00045 #include <vector> 00046 00049 00050 namespace TSQR { 00051 namespace Test { 00052 00053 template< class Ordinal, class MagnitudeType, class NormalGenType > 00054 static void 00055 generateSingularValues (NormalGenType& magGen, 00056 std::vector< MagnitudeType >& sigma, 00057 const Ordinal numValues) 00058 { 00059 typedef MagnitudeType magnitude_type; 00060 const magnitude_type machEps = 00061 std::numeric_limits< magnitude_type >::epsilon(); 00062 sigma.resize (numValues); 00063 00064 // Relative amount by which to perturb each singular value. The 00065 // perturbation will be multiplied by a normal(0,1) pseudorandom 00066 // number drawn from magGen. 00067 const magnitude_type perturbationFactor = magnitude_type(10) * machEps; 00068 00069 sigma[0] = magnitude_type (1); 00070 for (Ordinal k = 1; k < numValues; ++k) 00071 { 00072 const magnitude_type perturbation = perturbationFactor * magGen(); 00073 const magnitude_type beforePerturb = sigma[k-1] / magnitude_type(2); 00074 const magnitude_type candidate = beforePerturb + perturbation; 00075 00076 // If adding the perturbation to beforePerturb would result 00077 // in a nonpositive number, subtract instead. 00078 if (candidate <= magnitude_type(0)) 00079 sigma[k] = beforePerturb - perturbation; 00080 else 00081 sigma[k] = candidate; 00082 } 00083 } 00084 00085 template< class MagnitudeType > 00086 static void 00087 printR1R2results (const std::string& datatype, 00088 const int numCols, 00089 const std::vector< MagnitudeType >& results) 00090 { 00091 using std::cout; 00092 using std::endl; 00093 00094 cout << "Combine" 00095 << "," << datatype 00096 << "," << "R1R2" 00097 << "," << numCols 00098 << "," << numCols 00099 << "," << results[0] 00100 << "," << results[1] 00101 << endl; 00102 } 00103 00104 template< class MagnitudeType > 00105 static void 00106 printR3Aresults (const std::string& datatype, 00107 const int numRows, 00108 const int numCols, 00109 const std::vector< MagnitudeType >& results) 00110 { 00111 using std::cout; 00112 using std::endl; 00113 00114 cout << "Combine" 00115 << "," << datatype 00116 << "," << "R3A" 00117 << "," << numRows 00118 << "," << numCols 00119 << "," << results[2] 00120 << "," << results[3] 00121 << endl; 00122 } 00123 00124 template< class MagnitudeType > 00125 static void 00126 printResults (const std::string& datatype, 00127 const int numRows, 00128 const int numCols, 00129 const std::vector< MagnitudeType >& results) 00130 { 00131 printR1R2results (datatype, numCols, results); 00132 printR3Aresults (datatype, numRows, numCols, results); 00133 } 00134 00135 template< class MagnitudeType > 00136 static void 00137 printSimSeqTsqrResults (const std::string& datatype, 00138 const int numRows, 00139 const int numCols, 00140 const std::pair< MagnitudeType, MagnitudeType >& results) 00141 { 00142 using std::cout; 00143 using std::endl; 00144 00145 cout << "CombineSimSeqTsqr" 00146 << "," << datatype 00147 << "," << numRows 00148 << "," << numCols 00149 << "," << results.first 00150 << "," << results.second 00151 << endl; 00152 } 00153 00154 template< class MatrixViewType > 00155 static void 00156 printMatrix (std::ostream& out, 00157 const MatrixViewType& A) 00158 { 00159 print_local_matrix (out, A.nrows(), A.ncols(), A.get(), A.lda()); 00160 } 00161 00162 template< class MatrixViewType > 00163 static 00164 std::pair< typename ScalarTraits< typename MatrixViewType::scalar_type >::magnitude_type, 00165 typename ScalarTraits< typename MatrixViewType::scalar_type >::magnitude_type > 00166 localVerify (const MatrixViewType& A, 00167 const MatrixViewType& Q, 00168 const MatrixViewType& R) 00169 { 00170 return local_verify (A.nrows(), A.ncols(), A.get(), A.lda(), 00171 Q.get(), Q.lda(), R.get(), R.lda()); 00172 } 00173 00186 template< class Ordinal, class Scalar > 00187 static std::vector< typename ScalarTraits< Scalar >::magnitude_type > 00188 verifyCombineTemplate (TSQR::Random::NormalGenerator< Ordinal, Scalar >& gen, 00189 TSQR::Random::NormalGenerator< Ordinal, typename ScalarTraits< Scalar >::magnitude_type >& magGen, 00190 const Ordinal numRows, 00191 const Ordinal numCols, 00192 const bool debug) 00193 { 00194 using TSQR::Random::MatrixGenerator; 00195 using TSQR::Random::NormalGenerator; 00196 using std::cerr; 00197 using std::endl; 00198 using std::invalid_argument; 00199 using std::ostringstream; 00200 using std::pair; 00201 using std::vector; 00202 00203 typedef typename ScalarTraits< Scalar >::magnitude_type magnitude_type; 00204 typedef NormalGenerator< Ordinal, Scalar > normgen_type; 00205 typedef NormalGenerator< Ordinal, magnitude_type > normgen_mag_type; 00206 typedef MatrixGenerator< Ordinal, Scalar, normgen_type > matgen_type; 00207 typedef Matrix< Ordinal, Scalar > matrix_type; 00208 typedef pair< magnitude_type, magnitude_type > results_type; 00209 00210 if (numRows < numCols) 00211 { 00212 ostringstream os; 00213 os << "# rows < # columns is not allowed. You specified # rows = " 00214 << numRows << " and # columns = " << numCols << "."; 00215 throw invalid_argument (os.str()); 00216 } 00217 else if (numCols == 0) 00218 throw invalid_argument ("ncols == 0 is not allowed"); 00219 00220 // 00221 // Generate four different sets of singular values. Randomly 00222 // perturb them, but make sure all are positive. 00223 // 00224 vector< magnitude_type > sigma_R1 (numCols); 00225 vector< magnitude_type > sigma_R2 (numCols); 00226 vector< magnitude_type > sigma_R3 (numCols); 00227 vector< magnitude_type > sigma_A (numCols); 00228 generateSingularValues (magGen, sigma_R1, numCols); 00229 generateSingularValues (magGen, sigma_R2, numCols); 00230 generateSingularValues (magGen, sigma_R3, numCols); 00231 generateSingularValues (magGen, sigma_A, numCols); 00232 00233 matrix_type R1 (numCols, numCols, Scalar(0)); 00234 matrix_type R2 (numCols, numCols, Scalar(0)); 00235 matrix_type R3 (numCols, numCols, Scalar(0)); 00236 matrix_type A (numRows, numCols, Scalar(0)); 00237 matgen_type matgen (gen); 00238 matgen.fill_random_R (numCols, R1.get(), R1.lda(), &sigma_R1[0]); 00239 matgen.fill_random_R (numCols, R2.get(), R2.lda(), &sigma_R2[0]); 00240 matgen.fill_random_R (numCols, R3.get(), R3.lda(), &sigma_R3[0]); 00241 matgen.fill_random_svd (numRows, numCols, A.get(), A.lda(), &sigma_A[0]); 00242 00243 if (false && debug) 00244 { 00245 cerr << endl << "First test problem:" << endl; 00246 print_local_matrix (cerr, numCols, numCols, R1.get(), R1.lda()); 00247 print_local_matrix (cerr, numCols, numCols, R2.get(), R2.lda()); 00248 cerr << endl; 00249 00250 cerr << endl << "Second test problem:" << endl; 00251 print_local_matrix (cerr, numCols, numCols, R3.get(), R3.lda()); 00252 print_local_matrix (cerr, numRows, numCols, A.get(), A.lda()); 00253 cerr << endl; 00254 } 00255 00256 // Space to put the original test problem, expressed as one 00257 // dense matrix rather than in two blocks. These will be deep 00258 // copies of the test problems, since the test problem matrices 00259 // will be overwritten by the factorizations. 00260 matrix_type A_R1R2 (Ordinal(2) * numCols, numCols, Scalar(0)); 00261 matrix_type A_R3A (numRows + numCols, numCols, Scalar(0)); 00262 00263 // Copy [R1; R2] into A_R1R2. 00264 copy_matrix (numCols, numCols, &A_R1R2(0, 0), A_R1R2.lda(), 00265 R1.get(), R1.lda()); 00266 copy_matrix (numCols, numCols, &A_R1R2(numCols, 0), A_R1R2.lda(), 00267 R2.get(), R2.lda()); 00268 00269 // Copy [R3; A] into A_R3A. 00270 copy_matrix (numCols, numCols, &A_R3A(0, 0), A_R3A.lda(), 00271 R3.get(), R3.lda()); 00272 copy_matrix (numRows, numCols, &A_R3A(numCols, 0), A_R3A.lda(), 00273 A.get(), A.lda()); 00274 00275 // Space to put the explicit Q factors. 00276 matrix_type Q_R1R2 (Ordinal(2) * numCols, numCols, Scalar(0)); 00277 matrix_type Q_R3A (numRows + numCols, numCols, Scalar(0)); 00278 00279 // Fill the explicit Q factor matrices with the first numCols 00280 // columns of the identity matrix. 00281 for (Ordinal k = 0; k < numCols; ++k) 00282 { 00283 Q_R1R2(k, k) = Scalar(1); 00284 Q_R3A(k, k) = Scalar(1); 00285 } 00286 00287 // tau factor arrays, one for each factorization test. 00288 vector< Scalar > tau_R1R2 (numCols); 00289 vector< Scalar > tau_R3A (numCols); 00290 00291 // Workspace array for factorization and applying the Q factor. 00292 // We recycle this workspace for all tests. 00293 vector< Scalar > work (numCols); 00294 00295 if (debug) 00296 cerr << endl << "----------------------------------------" << endl 00297 << "TSQR::Combine first test problem:" << endl 00298 << "qr( [R1; R2] ), with R1 and R2 " << numCols 00299 << " by " << numCols << endl << endl; 00300 00301 Combine< Ordinal, Scalar > combiner; 00302 combiner.factor_pair (numCols, R1.get(), R1.lda(), R2.get(), R2.lda(), 00303 &tau_R1R2[0], &work[0]); 00304 combiner.apply_pair (ApplyType("N"), numCols, numCols, 00305 R2.get(), R2.lda(), &tau_R1R2[0], 00306 &Q_R1R2(0, 0), Q_R1R2.lda(), 00307 &Q_R1R2(numCols, 0), Q_R1R2.lda(), 00308 &work[0]); 00309 if (debug) 00310 { 00311 cerr << "Results of first test problem:" << endl; 00312 cerr << "-- Copy of test problem:" << endl; 00313 print_local_matrix (cerr, A_R1R2.nrows(), A_R1R2.ncols(), 00314 A_R1R2.get(), A_R1R2.lda()); 00315 cerr << endl << "-- Q factor:" << endl; 00316 print_local_matrix (cerr, Q_R1R2.nrows(), Q_R1R2.ncols(), 00317 Q_R1R2.get(), Q_R1R2.lda()); 00318 cerr << endl << "-- R factor:" << endl; 00319 print_local_matrix (cerr, R1.nrows(), R1.ncols(), 00320 R1.get(), R1.lda()); 00321 cerr << endl; 00322 } 00323 const results_type firstResults = 00324 local_verify (A_R1R2.nrows(), A_R1R2.ncols(), 00325 A_R1R2.get(), A_R1R2.lda(), 00326 Q_R1R2.get(), Q_R1R2.lda(), 00327 R1.get(), R1.lda()); 00328 if (debug) 00329 cerr << "\\| A - Q*R \\|_F = " << firstResults.first << endl 00330 << "\\| I - Q'*Q \\|_F = " << firstResults.second << endl; 00331 00332 if (debug) 00333 cerr << endl << "----------------------------------------" << endl 00334 << "TSQR::Combine second test problem:" << endl 00335 << "qr( [R3; A] ), with R3 " << numCols << " by " << numCols 00336 << " and A " << numRows << " by " << numCols << endl << endl; 00337 00338 combiner.factor_inner (numRows, numCols, R3.get(), R3.lda(), 00339 A.get(), A.lda(), &tau_R3A[0], &work[0]); 00340 combiner.apply_inner (ApplyType("N"), numRows, numCols, numCols, 00341 A.get(), A.lda(), &tau_R3A[0], 00342 &Q_R3A(0, 0), Q_R3A.lda(), 00343 &Q_R3A(numCols, 0), Q_R3A.lda(), 00344 &work[0]); 00345 if (debug) 00346 { 00347 cerr << "Results of second test problem:" << endl; 00348 cerr << "-- Copy of test problem:" << endl; 00349 print_local_matrix (cerr, A_R3A.nrows(), A_R3A.ncols(), 00350 A_R3A.get(), A_R3A.lda()); 00351 cerr << endl << "-- Q factor:" << endl; 00352 print_local_matrix (cerr, Q_R3A.nrows(), Q_R3A.ncols(), 00353 Q_R3A.get(), Q_R3A.lda()); 00354 cerr << endl << "-- R factor:" << endl; 00355 print_local_matrix (cerr, R3.nrows(), R3.ncols(), 00356 R3.get(), R3.lda()); 00357 cerr << endl; 00358 } 00359 const results_type secondResults = 00360 local_verify (A_R3A.nrows(), A_R3A.ncols(), 00361 A_R3A.get(), A_R3A.lda(), 00362 Q_R3A.get(), Q_R3A.lda(), 00363 R3.get(), R3.lda()); 00364 if (debug) 00365 cerr << "\\| A - Q*R \\|_F = " << secondResults.first << endl 00366 << "\\| I - Q'*Q \\|_F = " << secondResults.second << endl; 00367 00368 vector< magnitude_type > finalResults (4); 00369 finalResults[0] = firstResults.first; 00370 finalResults[1] = firstResults.second; 00371 finalResults[2] = secondResults.first; 00372 finalResults[3] = secondResults.second; 00373 return finalResults; 00374 } 00375 00376 00377 00378 00381 template< class Ordinal, class Scalar > 00382 static std::pair< typename ScalarTraits< Scalar >::magnitude_type, typename ScalarTraits< Scalar >::magnitude_type > 00383 verifyCombineSeqTemplate (TSQR::Random::NormalGenerator< Ordinal, Scalar >& gen, 00384 TSQR::Random::NormalGenerator< Ordinal, typename ScalarTraits< Scalar >::magnitude_type >& magGen, 00385 const Ordinal numRows, 00386 const Ordinal numCols, 00387 const bool debug) 00388 { 00389 using TSQR::Random::MatrixGenerator; 00390 using TSQR::Random::NormalGenerator; 00391 using std::cerr; 00392 using std::endl; 00393 using std::invalid_argument; 00394 using std::ostringstream; 00395 using std::pair; 00396 using std::vector; 00397 00398 typedef typename ScalarTraits< Scalar >::magnitude_type magnitude_type; 00399 typedef NormalGenerator< Ordinal, Scalar > normgen_type; 00400 typedef NormalGenerator< Ordinal, magnitude_type > normgen_mag_type; 00401 typedef MatrixGenerator< Ordinal, Scalar, normgen_type > matgen_type; 00402 typedef Matrix< Ordinal, Scalar > matrix_type; 00403 typedef MatView< Ordinal, Scalar > mat_view_type; 00404 typedef pair< magnitude_type, magnitude_type > results_type; 00405 00406 if (numRows < numCols) 00407 { 00408 ostringstream os; 00409 os << "# rows < # columns is not allowed. You specified # rows = " 00410 << numRows << " and # columns = " << numCols << "."; 00411 throw invalid_argument (os.str()); 00412 } 00413 else if (numCols == 0) 00414 throw invalid_argument ("ncols == 0 is not allowed"); 00415 00416 // Generate two different sets of singular values. 00417 vector< magnitude_type > sigma_A1 (numCols); 00418 vector< magnitude_type > sigma_A2 (numCols); 00419 generateSingularValues (magGen, sigma_A1, numCols); 00420 generateSingularValues (magGen, sigma_A2, numCols); 00421 00422 // Matrix consisting of two cache blocks. 00423 matrix_type A (Ordinal(2)*numRows, numCols, Scalar(0)); 00424 // Views of the two cache blocks. 00425 mat_view_type A1 (numRows, numCols, &A(0,0), A.lda()); 00426 mat_view_type A2 (numRows, numCols, &A(numRows,0), A.lda()); 00427 00428 // Fill the two cache blocks with random test problems. 00429 matgen_type matgen (gen); 00430 matgen.fill_random_svd (numRows, numCols, A1.get(), A1.lda(), &sigma_A1[0]); 00431 matgen.fill_random_svd (numRows, numCols, A2.get(), A2.lda(), &sigma_A2[0]); 00432 00433 if (false && debug) 00434 { 00435 cerr << endl << "Test problem:" << endl; 00436 cerr << endl << "Original matrix:" << endl; 00437 printMatrix (cerr, A); 00438 cerr << endl << "First cache block:" << endl; 00439 printMatrix (cerr, A1); 00440 cerr << endl << "Second cache block:" << endl; 00441 printMatrix (cerr, A2); 00442 cerr << endl; 00443 } 00444 00445 // Copy of the resulting test problem, stored as one dense 00446 // matrix rather than as two blocks. We will use A_copy to 00447 // measure the residual error once we've completed the 00448 // factorization and computed the explicit Q factor. 00449 matrix_type A_copy (A); 00450 00451 // Space to put the explicit Q factor. 00452 matrix_type Q (Ordinal(2) * numRows, numCols, Scalar(0)); 00453 00454 // Fill Q with the first numCols columns of the identity matrix. 00455 for (Ordinal k = 0; k < numCols; ++k) 00456 Q(k, k) = Scalar(1); 00457 00458 // Two cache blocks (as views) of Q. 00459 mat_view_type Q1 (numRows, numCols, &Q(0,0), Q.lda()); 00460 mat_view_type Q2 (numRows, numCols, &Q(numRows,0), Q.lda()); 00461 00462 // Two tau factor arrays, one for each cache block. 00463 vector< Scalar > tau1 (numCols); 00464 vector< Scalar > tau2 (numCols); 00465 00466 // Workspace array for factorization and applying the Q factor. 00467 // We recycle this workspace for all tests. 00468 vector< Scalar > work (numCols); 00469 00470 if (debug) 00471 cerr << endl << "----------------------------------------" << endl 00472 << "TSQR::Combine SequentialTsqr simulation with 2 cache blocks:" 00473 << endl << "qr( [A1; A2] ), with A1 and A2 being each " 00474 << numRows << " by " << numCols << endl << endl; 00475 00476 Combine< Ordinal, Scalar > combiner; 00477 // qr( A1 ) 00478 combiner.factor_first (numRows, numCols, A1.get(), A1.lda(), 00479 &tau1[0], &work[0]); 00480 // View of numCols by numCols upper triangle of A1. 00481 mat_view_type R1 (numCols, numCols, A1.get(), A1.lda()); 00482 // qr( [R1; A2] ) 00483 combiner.factor_inner (numRows, numCols, R1.get(), R1.lda(), 00484 A2.get(), A2.lda(), &tau2[0], &work[0]); 00485 // Extract (a deep copy of) the R factor. 00486 matrix_type R (R1); 00487 // Zero out everything below the diagonal of R. 00488 for (Ordinal j = 0; j < numCols; ++j) 00489 for (Ordinal i = j+1; i < numCols; ++i) 00490 R(i,j) = Scalar(0); 00491 00492 // Compute the explicit Q factor, by starting with A2 and 00493 // (working up the matrix A,) finishing with A1. 00494 combiner.apply_inner (ApplyType::NoTranspose, 00495 numRows, numCols, numCols, 00496 A2.get(), A2.lda(), &tau2[0], 00497 Q1.get(), Q1.lda(), 00498 Q2.get(), Q2.lda(), &work[0]); 00499 combiner.apply_first (ApplyType::NoTranspose, 00500 numRows, numCols, numCols, 00501 A1.get(), A.lda(), &tau1[0], 00502 Q1.get(), Q1.lda(), &work[0]); 00503 if (debug) 00504 { 00505 cerr << "Results of first test problem:" << endl; 00506 cerr << "-- Test matrix A:" << endl; 00507 printMatrix (cerr, A_copy); 00508 cerr << endl << "-- Q factor:" << endl; 00509 printMatrix (cerr, Q); 00510 cerr << endl << "-- R factor:" << endl; 00511 printMatrix (cerr, R); 00512 cerr << endl; 00513 } 00514 const results_type results = localVerify (A_copy, Q, R); 00515 00516 if (debug) 00517 cerr << "\\| A - Q*R \\|_F = " << results.first << endl 00518 << "\\| I - Q'*Q \\|_F = " << results.second << endl; 00519 00520 return results; 00521 } 00522 00523 00524 void 00525 verifyCombine (const int numRows, 00526 const int numCols, 00527 const bool test_complex, 00528 const bool simulate_sequential_tsqr, 00529 const bool debug) 00530 { 00531 using TSQR::Random::NormalGenerator; 00532 using std::cerr; 00533 using std::complex; 00534 using std::cout; 00535 using std::endl; 00536 using std::pair; 00537 using std::string; 00538 using std::vector; 00539 00540 // 00541 // We do tests one after another, using the seed from the 00542 // previous test in the current test, so that the pseudorandom 00543 // streams used by the tests are independent. 00544 // 00545 00546 // On output: Seed for the next pseudorandom number generator. 00547 vector< int > iseed(4); 00548 00549 if (! simulate_sequential_tsqr) 00550 { 00551 // First test. The PRNG seeds itself with a default value. 00552 // This will be the same each time, so if you want 00553 // nondeterministic behavior, you should pick the seed values 00554 // yourself. 00555 NormalGenerator< int, float > normgenS; 00556 const vector< float > resultsS = 00557 verifyCombineTemplate (normgenS, normgenS, numRows, numCols, debug); 00558 printResults (string("float"), numRows, numCols, resultsS); 00559 // Fetch the pseudorandom seed from the previous test. 00560 normgenS.getSeed (iseed); 00561 00562 if (test_complex) 00563 { 00564 // Next test. 00565 NormalGenerator< int, complex<float> > normgenC (iseed); 00566 const vector< float > resultsC = 00567 verifyCombineTemplate (normgenC, normgenS, numRows, numCols, debug); 00568 printResults (string("complex<float>"), numRows, numCols, resultsC); 00569 // Fetch the seed from this test 00570 normgenC.getSeed (iseed); 00571 } 00572 00573 // Next test. 00574 NormalGenerator< int, double > normgenD (iseed); 00575 const vector< double > resultsD = 00576 verifyCombineTemplate (normgenD, normgenD, numRows, numCols, debug); 00577 printResults (string("double"), numRows, numCols, resultsD); 00578 normgenD.getSeed (iseed); 00579 00580 if (test_complex) 00581 { 00582 // Next test. 00583 NormalGenerator< int, complex<double> > normgenZ (iseed); 00584 const vector< double > resultsZ = 00585 verifyCombineTemplate (normgenZ, normgenD, numRows, numCols, debug); 00586 printResults (string("complex<double>"), numRows, numCols, resultsZ); 00587 } 00588 } 00589 else // simulate_sequential_tsqr 00590 { 00591 // First test. 00592 NormalGenerator< int, float > normgenS2; 00593 const pair< float, float > resultsS2 = 00594 verifyCombineSeqTemplate (normgenS2, normgenS2, numRows, numCols, debug); 00595 printSimSeqTsqrResults (string("float"), numRows, numCols, resultsS2); 00596 normgenS2.getSeed (iseed); 00597 00598 if (test_complex) 00599 { 00600 // Next test. 00601 NormalGenerator< int, complex<float> > normgenC2 (iseed); 00602 const pair< float, float > resultsC2 = 00603 verifyCombineSeqTemplate (normgenC2, normgenS2, numRows, numCols, debug); 00604 printSimSeqTsqrResults (string("complex<float>"), numRows, numCols, resultsC2); 00605 normgenC2.getSeed (iseed); 00606 } 00607 00608 // Next test. 00609 NormalGenerator< int, double > normgenD2 (iseed); 00610 const pair< double, double > resultsD2 = 00611 verifyCombineSeqTemplate (normgenD2, normgenD2, numRows, numCols, debug); 00612 printSimSeqTsqrResults (string("double"), numRows, numCols, resultsD2); 00613 normgenD2.getSeed (iseed); 00614 00615 if (test_complex) 00616 { 00617 // Next test. 00618 NormalGenerator< int, complex<double> > normgenZ2 (iseed); 00619 const pair< double, double > resultsZ2 = 00620 verifyCombineSeqTemplate (normgenZ2, normgenD2, numRows, numCols, debug); 00621 printSimSeqTsqrResults (string("complex<double>"), numRows, numCols, resultsZ2); 00622 } 00623 } 00624 } 00625 00626 } // namespace Test 00627 } // namespace TSQR 00628
1.7.4