PlayaMatrixMatrixTester.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 
00043 #ifndef PLAYA_MATRIXMATRIXTESTER_HPP
00044 #define PLAYA_MATRIXMATRIXTESTER_HPP
00045 
00046 #include "PlayaLinearOperatorDecl.hpp"
00047 #include "PlayaEpetraMatrixMatrixProduct.hpp"
00048 #include "PlayaEpetraMatrixMatrixSum.hpp"
00049 #include "PlayaEpetraMatrixOps.hpp"
00050 #include "PlayaEpetraMatrix.hpp"
00051 #include "Teuchos_ScalarTraits.hpp"
00052 #include "PlayaLinearCombinationImpl.hpp"
00053 
00054 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00055 #include "PlayaSimpleComposedOpImpl.hpp"
00056 #include "PlayaSimpleScaledOpImpl.hpp"
00057 #include "PlayaSimpleAddedOpImpl.hpp"
00058 #include "PlayaSimpleDiagonalOpImpl.hpp"
00059 #include "PlayaSimpleTransposedOpImpl.hpp"
00060 #include "PlayaRandomSparseMatrixBuilderImpl.hpp"
00061 #endif
00062 
00063 using namespace Playa;
00064 using namespace Teuchos;
00065 
00066 
00067 
00068 namespace Playa
00069 {
00070 
00071 /** */
00072 template <class Scalar>
00073 class MatrixMatrixTester : public TesterBase<Scalar>
00074 {
00075 public:
00076   /** \brief Local typedef for promoted scalar magnitude */
00077   typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00078 
00079   /** */
00080   MatrixMatrixTester(const LinearOperator<Scalar>& A,
00081     const LinearOperator<Scalar>& B,
00082     const TestSpecifier<Scalar>& sumSpec,
00083     const TestSpecifier<Scalar>& prodSpec,
00084     const TestSpecifier<Scalar>& diagSpec,
00085     const TestSpecifier<Scalar>& diagLeftProdSpec,
00086     const TestSpecifier<Scalar>& diagRightProdSpec);
00087 
00088   /** */
00089   bool runAllTests() const ;
00090 
00091   /** */
00092   bool sumTest() const ;
00093 
00094   /** */
00095   bool prodTest() const ;
00096 
00097   /** */
00098   bool diagTest() const ;
00099 
00100   /** */
00101   bool diagLeftProdTest() const ;
00102 
00103   /** */
00104   bool diagRightProdTest() const ;
00105 
00106 
00107 private:
00108 
00109   LinearOperator<Scalar> A_;
00110 
00111   LinearOperator<Scalar> B_;
00112 
00113   TestSpecifier<Scalar> sumSpec_;
00114 
00115   TestSpecifier<Scalar> prodSpec_;
00116 
00117   TestSpecifier<Scalar> diagSpec_;
00118 
00119   TestSpecifier<Scalar> diagLeftProdSpec_;
00120 
00121   TestSpecifier<Scalar> diagRightProdSpec_;
00122 
00123 };
00124 
00125 template <class Scalar> 
00126 inline MatrixMatrixTester<Scalar>
00127 ::MatrixMatrixTester(const LinearOperator<Scalar>& A,
00128   const LinearOperator<Scalar>& B,
00129   const TestSpecifier<Scalar>& sumSpec,
00130   const TestSpecifier<Scalar>& prodSpec,
00131   const TestSpecifier<Scalar>& diagSpec,
00132   const TestSpecifier<Scalar>& diagRightProdSpec,
00133   const TestSpecifier<Scalar>& diagLeftProdSpec)
00134   : TesterBase<Scalar>(), 
00135     A_(A),
00136     B_(B),
00137     sumSpec_(sumSpec),
00138     prodSpec_(prodSpec),
00139     diagSpec_(diagSpec),
00140     diagLeftProdSpec_(diagLeftProdSpec),
00141     diagRightProdSpec_(diagRightProdSpec)
00142 {;}
00143 
00144 template <class Scalar> 
00145 inline bool MatrixMatrixTester<Scalar>
00146 ::runAllTests() const
00147 {
00148   bool pass = true;
00149 
00150   pass = this->sumTest() && pass;
00151   pass = this->prodTest() && pass;
00152   pass = this->diagTest() && pass;
00153   pass = this->diagLeftProdTest() && pass;
00154   pass = this->diagRightProdTest() && pass;
00155 
00156   return pass;
00157 }
00158 
00159 template <class Scalar> 
00160 inline bool MatrixMatrixTester<Scalar>
00161 ::diagTest() const 
00162 {
00163   if (diagSpec_.doTest())
00164   {
00165     Vector<Scalar> x = B_.domain().createMember();
00166     Vector<Scalar> d = B_.domain().createMember();
00167     this->randomizeVec(x);
00168     this->randomizeVec(d);
00169     LinearOperator<Scalar> D0 = diagonalOperator(d);
00170     LinearOperator<Scalar> D = makeEpetraDiagonalMatrix(d);
00171     Vector<Scalar> d1 = getEpetraDiagonal(D);
00172 
00173     Out::root() << "computing implicit product y1 = D*x..." << std::endl;
00174     Vector<Scalar> y1 = D0*x;
00175     Out::root() << "computing explicit product y2 = D*x..." << std::endl;
00176     Vector<Scalar> y2 = D*x;
00177 
00178     ScalarMag err = (y1 - y2).norm2();
00179 
00180     Out::root() << "|y1-y2| = " << err << std::endl;
00181     
00182     Out::root() << "comparing recovered and original diagonals" << std::endl;
00183     ScalarMag err2 = (d - d1).norm2();
00184     Out::root() << "|d1-d2| = " << err2 << std::endl;
00185     
00186     return this->checkTest(prodSpec_, err+err2, "matrix-matrix multiply");
00187     
00188   }
00189   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00190   return true;
00191 }
00192 
00193 
00194 
00195 template <class Scalar> 
00196 inline bool MatrixMatrixTester<Scalar>
00197 ::sumTest() const 
00198 {
00199   if (sumSpec_.doTest())
00200   {
00201     /* skip incompatible matrices. This will occur when we're testing
00202      * multiplication of rectangular matrices */
00203     if (A_.range() != B_.range() || A_.domain() != B_.domain())
00204     {
00205       Out::root() << "skipping sum on incompatible matrices" << std::endl;
00206       return true;
00207     }
00208     /* If here, the sum should work */
00209     Out::root() << "running matrix-matrix multiply test..." << std::endl;
00210     LinearOperator<Scalar> implicitAdd = A_ + B_;
00211     LinearOperator<Scalar> explicitAdd = epetraMatrixMatrixSum(A_, B_);
00212 
00213     Vector<Scalar> x = B_.domain().createMember();
00214     this->randomizeVec(x);
00215     Out::root() << "computing implicit sum y1 = (A+B)*x..." << std::endl;
00216     Vector<Scalar> y1 = implicitAdd*x;
00217     Out::root() << "computing explicit sum y2 = (A+B)*x..." << std::endl;
00218     Vector<Scalar> y2 = explicitAdd*x;
00219 
00220     ScalarMag err = (y1 - y2).norm2();
00221 
00222     Out::root() << "|y1-y2| = " << err << std::endl;
00223     return this->checkTest(prodSpec_, err, "matrix-matrix multiply");
00224     
00225   }
00226   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00227   return true;
00228 }
00229 
00230 
00231 template <class Scalar> 
00232 inline bool MatrixMatrixTester<Scalar>
00233 ::prodTest() const 
00234 {
00235   if (prodSpec_.doTest())
00236   {
00237     Out::root() << "running matrix-matrix multiply test..." << std::endl;
00238     LinearOperator<Scalar> composed = A_ * B_;
00239     LinearOperator<Scalar> multiplied = epetraMatrixMatrixProduct(A_, B_);
00240 
00241     Vector<Scalar> x = B_.domain().createMember();
00242     this->randomizeVec(x);
00243     Out::root() << "computing implicit product y1 = (A*B)*x..." << std::endl;
00244     Vector<Scalar> y1 = composed*x;
00245     Out::root() << "computing explicit product y2 = (A*B)*x..." << std::endl;
00246     Vector<Scalar> y2 = multiplied*x;
00247 
00248     ScalarMag err = (y1 - y2).norm2();
00249 
00250     Out::root() << "|y1-y2| = " << err << std::endl;
00251     return this->checkTest(prodSpec_, err, "matrix-matrix multiply");
00252   }
00253   Out::root() << "skipping matrix-matrix multiply test..." << std::endl;
00254   return true;
00255 }
00256 
00257 
00258 template <class Scalar> 
00259 inline bool MatrixMatrixTester<Scalar>
00260 ::diagLeftProdTest() const 
00261 {
00262   if (diagLeftProdSpec_.doTest())
00263   {
00264     Out::root() << "running diagonal*matrix multiplication test..." << std::endl;
00265 
00266     Vector<Scalar> x = A_.domain().createMember();
00267     this->randomizeVec(x);
00268 
00269     Vector<Scalar> d = A_.range().createMember();
00270     this->randomizeVec(d);
00271         
00272     LinearOperator<Scalar> D = diagonalOperator(d);
00273     LinearOperator<Scalar> DA = epetraLeftScale(d, A_);
00274 
00275     Out::root() << "computing implicit y1 = D*A*x..." << std::endl;
00276     Vector<Scalar> y1 = D*A_*x;
00277     Out::root() << "computing explicit y2 = D*A*x..." << std::endl;
00278     Vector<Scalar> y2 = DA*x;
00279 
00280     ScalarMag err = (y1 - y2).norm2();
00281 
00282     Out::root() << "|y1-y2| = " << err << std::endl;
00283 
00284     return this->checkTest(diagLeftProdSpec_, err, "diagonal*matrix multiplication");
00285   }
00286   Out::root() << "skipping diagonal matrix-matrix test..." << std::endl;
00287   return true;
00288 }
00289 
00290   
00291 template <class Scalar> 
00292 inline bool MatrixMatrixTester<Scalar>
00293 ::diagRightProdTest() const 
00294 {
00295   if (diagRightProdSpec_.doTest())
00296   {
00297     Out::root() << "running diagonal*matrix multiplication test..." << std::endl;
00298 
00299     Vector<Scalar> x = A_.domain().createMember();
00300     this->randomizeVec(x);
00301 
00302     Vector<Scalar> d = A_.domain().createMember();
00303     this->randomizeVec(d);
00304         
00305     LinearOperator<Scalar> D = diagonalOperator(d);
00306     LinearOperator<Scalar> AD = epetraRightScale(A_, d);
00307 
00308     Out::root() << "computing implicit y1 = A*D*x..." << std::endl;
00309     Vector<Scalar> y1 = A_*D*x;
00310     Out::root() << "computing explicit y2 = A*D*x..." << std::endl;
00311     Vector<Scalar> y2 = AD*x;
00312 
00313     ScalarMag err = (y1 - y2).norm2();
00314 
00315     Out::root() << "|y1-y2| = " << err << std::endl;
00316 
00317     return this->checkTest(diagLeftProdSpec_, err, "matrix*diagonal multiplication");
00318   }
00319   Out::root() << "skipping diagonal matrix-matrix test..." << std::endl;
00320   return true;
00321 }
00322 
00323   
00324   
00325 }
00326 #endif

Site Contact