Go to the documentation of this file.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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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
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
00202
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
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