Anasazi Version of the Day
Tsqr_CombineTest.cpp
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends