TSFMatrixMatrixTester.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
00005 //                 Copyright (2004) 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 
00030 #ifndef TSF_MATRIXMATRIXTESTER_HPP
00031 #define TSF_MATRIXMATRIXTESTER_HPP
00032 
00033 #include "TSFLinearOperatorDecl.hpp"
00034 #include "TSFEpetraMatrixMatrixProduct.hpp"
00035 #include "TSFEpetraMatrixMatrixSum.hpp"
00036 #include "TSFEpetraMatrixOps.hpp"
00037 #include "TSFEpetraMatrix.hpp"
00038 #include "Teuchos_ScalarTraits.hpp"
00039 #include "TSFLinearCombinationImpl.hpp"
00040 
00041 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00042 #include "TSFSimpleComposedOpImpl.hpp"
00043 #include "TSFSimpleScaledOpImpl.hpp"
00044 #include "TSFSimpleAddedOpImpl.hpp"
00045 #include "TSFSimpleDiagonalOpImpl.hpp"
00046 #include "TSFRandomSparseMatrixBuilderImpl.hpp"
00047 #endif
00048 
00049 using namespace TSFExtended;
00050 using namespace Teuchos;
00051 
00052 using Thyra::TestSpecifier;
00053 
00054 namespace TSFExtended
00055 {
00056 
00057 /** */
00058 template <class Scalar>
00059 class MatrixMatrixTester : public TesterBase<Scalar>
00060 {
00061 public:
00062   /** \brief Local typedef for promoted scalar magnitude */
00063   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00064 
00065   /** */
00066   MatrixMatrixTester(const LinearOperator<Scalar>& A,
00067     const LinearOperator<Scalar>& B,
00068     const TestSpecifier<Scalar>& sumSpec,
00069     const TestSpecifier<Scalar>& prodSpec,
00070     const TestSpecifier<Scalar>& diagSpec,
00071     const TestSpecifier<Scalar>& diagLeftProdSpec,
00072     const TestSpecifier<Scalar>& diagRightProdSpec);
00073 
00074   /** */
00075   bool runAllTests() const ;
00076 
00077   /** */
00078   bool sumTest() const ;
00079 
00080   /** */
00081   bool prodTest() const ;
00082 
00083   /** */
00084   bool diagTest() const ;
00085 
00086   /** */
00087   bool diagLeftProdTest() const ;
00088 
00089   /** */
00090   bool diagRightProdTest() const ;
00091 
00092 
00093 private:
00094 
00095   LinearOperator<Scalar> A_;
00096 
00097   LinearOperator<Scalar> B_;
00098 
00099   TestSpecifier<Scalar> sumSpec_;
00100 
00101   TestSpecifier<Scalar> prodSpec_;
00102 
00103   TestSpecifier<Scalar> diagSpec_;
00104 
00105   TestSpecifier<Scalar> diagLeftProdSpec_;
00106 
00107   TestSpecifier<Scalar> diagRightProdSpec_;
00108 
00109 };
00110 
00111 template <class Scalar> 
00112 inline MatrixMatrixTester<Scalar>
00113 ::MatrixMatrixTester(const LinearOperator<Scalar>& A,
00114   const LinearOperator<Scalar>& B,
00115   const TestSpecifier<Scalar>& sumSpec,
00116   const TestSpecifier<Scalar>& prodSpec,
00117   const TestSpecifier<Scalar>& diagSpec,
00118   const TestSpecifier<Scalar>& diagRightProdSpec,
00119   const TestSpecifier<Scalar>& diagLeftProdSpec)
00120   : TesterBase<Scalar>(), 
00121     A_(A),
00122     B_(B),
00123     sumSpec_(sumSpec),
00124     prodSpec_(prodSpec),
00125     diagSpec_(diagSpec),
00126     diagLeftProdSpec_(diagLeftProdSpec),
00127     diagRightProdSpec_(diagRightProdSpec)
00128 {;}
00129 
00130 template <class Scalar> 
00131 inline bool MatrixMatrixTester<Scalar>
00132 ::runAllTests() const
00133 {
00134   bool pass = true;
00135 
00136   pass = this->sumTest() && pass;
00137   pass = this->prodTest() && pass;
00138   pass = this->diagTest() && pass;
00139   pass = this->diagLeftProdTest() && pass;
00140   pass = this->diagRightProdTest() && pass;
00141 
00142   return pass;
00143 }
00144 
00145 template <class Scalar> 
00146 inline bool MatrixMatrixTester<Scalar>
00147 ::diagTest() const 
00148 {
00149   if (diagSpec_.doTest())
00150   {
00151     Vector<Scalar> x = B_.domain().createMember();
00152     Vector<Scalar> d = B_.domain().createMember();
00153     randomizeVec(x);
00154     randomizeVec(d);
00155     LinearOperator<Scalar> D0 = diagonalOperator(d);
00156     LinearOperator<Scalar> D = makeEpetraDiagonalMatrix(d);
00157     Vector<Scalar> d1 = getEpetraDiagonal(D);
00158 
00159     Out::root() << "computing implicit product y1 = D*x..." << std::endl;
00160     Vector<Scalar> y1 = D0*x;
00161     Out::root() << "computing explicit product y2 = D*x..." << std::endl;
00162     Vector<Scalar> y2 = D*x;
00163 
00164     ScalarMag err = (y1 - y2).norm2();
00165 
00166     Out::root() << "|y1-y2| = " << err << std::endl;
00167     
00168     Out::root() << "comparing recovered and original diagonals" << std::endl;
00169     ScalarMag err2 = (d - d1).norm2();
00170     Out::root() << "|d1-d2| = " << err2 << std::endl;
00171     
00172     return checkTest(prodSpec_, err+err2, "matrix-matrix multiply");
00173     
00174   }
00175   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00176   return true;
00177 }
00178 
00179 
00180 
00181 template <class Scalar> 
00182 inline bool MatrixMatrixTester<Scalar>
00183 ::sumTest() const 
00184 {
00185   if (sumSpec_.doTest())
00186   {
00187     /* skip incompatible matrices. This will occur when we're testing
00188      * multiplication of rectangular matrices */
00189     if (A_.range() != B_.range() || A_.domain() != B_.domain())
00190     {
00191       Out::root() << "skipping sum on incompatible matrices" << std::endl;
00192       return true;
00193     }
00194     /* If here, the sum should work */
00195     Out::root() << "running matrix-matrix multiply test..." << std::endl;
00196     LinearOperator<Scalar> implicitAdd = A_ + B_;
00197     LinearOperator<Scalar> explicitAdd = epetraMatrixMatrixSum(A_, B_);
00198 
00199     Vector<Scalar> x = B_.domain().createMember();
00200     randomizeVec(x);
00201     Out::root() << "computing implicit sum y1 = (A+B)*x..." << std::endl;
00202     Vector<Scalar> y1 = implicitAdd*x;
00203     Out::root() << "computing explicit sum y2 = (A+B)*x..." << std::endl;
00204     Vector<Scalar> y2 = explicitAdd*x;
00205 
00206     ScalarMag err = (y1 - y2).norm2();
00207 
00208     Out::root() << "|y1-y2| = " << err << std::endl;
00209     return checkTest(prodSpec_, err, "matrix-matrix multiply");
00210     
00211   }
00212   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00213   return true;
00214 }
00215 
00216 
00217 template <class Scalar> 
00218 inline bool MatrixMatrixTester<Scalar>
00219 ::prodTest() const 
00220 {
00221   if (prodSpec_.doTest())
00222   {
00223     Out::root() << "running matrix-matrix multiply test..." << std::endl;
00224     LinearOperator<Scalar> composed = A_ * B_;
00225     LinearOperator<Scalar> multiplied = epetraMatrixMatrixProduct(A_, B_);
00226 
00227     Vector<Scalar> x = B_.domain().createMember();
00228     randomizeVec(x);
00229     Out::root() << "computing implicit product y1 = (A*B)*x..." << std::endl;
00230     Vector<Scalar> y1 = composed*x;
00231     Out::root() << "computing explicit product y2 = (A*B)*x..." << std::endl;
00232     Vector<Scalar> y2 = multiplied*x;
00233 
00234     ScalarMag err = (y1 - y2).norm2();
00235 
00236     Out::root() << "|y1-y2| = " << err << std::endl;
00237     return checkTest(prodSpec_, err, "matrix-matrix multiply");
00238   }
00239   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00240   return true;
00241 }
00242 
00243 
00244 template <class Scalar> 
00245 inline bool MatrixMatrixTester<Scalar>
00246 ::diagLeftProdTest() const 
00247 {
00248   if (diagLeftProdSpec_.doTest())
00249   {
00250     Out::root() << "running diagonal*matrix multiplication test..." << std::endl;
00251 
00252     Vector<Scalar> x = A_.domain().createMember();
00253     randomizeVec(x);
00254 
00255     Vector<Scalar> d = A_.range().createMember();
00256     randomizeVec(d);
00257         
00258     LinearOperator<Scalar> D = diagonalOperator(d);
00259     LinearOperator<Scalar> DA = epetraLeftScale(d, A_);
00260 
00261     Out::root() << "computing implicit y1 = D*A*x..." << std::endl;
00262     Vector<Scalar> y1 = D*A_*x;
00263     Out::root() << "computing explicit y2 = D*A*x..." << std::endl;
00264     Vector<Scalar> y2 = DA*x;
00265 
00266     ScalarMag err = (y1 - y2).norm2();
00267 
00268     Out::root() << "|y1-y2| = " << err << std::endl;
00269 
00270     return checkTest(diagLeftProdSpec_, err, "diagonal*matrix multiplication");
00271   }
00272   Out::root() << "skipping diagonal matrix-matrix test..." << std::endl;
00273   return true;
00274 }
00275 
00276   
00277 template <class Scalar> 
00278 inline bool MatrixMatrixTester<Scalar>
00279 ::diagRightProdTest() const 
00280 {
00281   if (diagRightProdSpec_.doTest())
00282   {
00283     Out::root() << "running diagonal*matrix multiplication test..." << std::endl;
00284 
00285     Vector<Scalar> x = A_.domain().createMember();
00286     randomizeVec(x);
00287 
00288     Vector<Scalar> d = A_.domain().createMember();
00289     randomizeVec(d);
00290         
00291     LinearOperator<Scalar> D = diagonalOperator(d);
00292     LinearOperator<Scalar> AD = epetraRightScale(A_, d);
00293 
00294     Out::root() << "computing implicit y1 = A*D*x..." << std::endl;
00295     Vector<Scalar> y1 = A_*D*x;
00296     Out::root() << "computing explicit y2 = A*D*x..." << std::endl;
00297     Vector<Scalar> y2 = AD*x;
00298 
00299     ScalarMag err = (y1 - y2).norm2();
00300 
00301     Out::root() << "|y1-y2| = " << err << std::endl;
00302 
00303     return checkTest(diagLeftProdSpec_, err, "matrix*diagonal multiplication");
00304   }
00305   Out::root() << "skipping diagonal matrix-matrix test..." << std::endl;
00306   return true;
00307 }
00308 
00309   
00310   
00311 }
00312 #endif

Site Contact