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_LINEARCOMBINATIONTESTER_HPP
00044 #define PLAYA_LINEARCOMBINATIONTESTER_HPP
00045
00046 #include "PlayaLinearOperatorDecl.hpp"
00047 #include "PlayaLinearCombinationImpl.hpp"
00048 #include "PlayaSimpleComposedOpDecl.hpp"
00049 #include "PlayaSimpleScaledOpDecl.hpp"
00050 #include "PlayaSimpleAddedOpDecl.hpp"
00051 #include "PlayaSimpleIdentityOpDecl.hpp"
00052 #include "PlayaOut.hpp"
00053 #include "PlayaVectorDecl.hpp"
00054 #include "PlayaTesterBase.hpp"
00055 #include "PlayaRandomSparseMatrixBuilderDecl.hpp"
00056 #include "PlayaTestSpecifier.hpp"
00057 #include "Teuchos_ScalarTraits.hpp"
00058
00059 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00060 #include "PlayaVectorImpl.hpp"
00061 #include "PlayaLinearOperatorImpl.hpp"
00062 #include "PlayaRandomSparseMatrixBuilderImpl.hpp"
00063 #include "PlayaSimpleComposedOpImpl.hpp"
00064 #include "PlayaSimpleScaledOpImpl.hpp"
00065 #include "PlayaSimpleAddedOpImpl.hpp"
00066 #include "PlayaSimpleTransposedOpImpl.hpp"
00067 #include "PlayaSimpleIdentityOpDecl.hpp"
00068 #endif
00069
00070 using namespace Playa;
00071 using namespace Teuchos;
00072
00073
00074
00075
00076
00077 #define TESTER(form1, form2)\
00078 {\
00079 Out::os() << "testing " #form1 << std::endl;\
00080 Vector<Scalar> _val1 = form1;\
00081 Out::os() << "testing " #form2 << std::endl;\
00082 Vector<Scalar> _val2 = form2;\
00083 Out::os() << "done testing... checking error" << std::endl;\
00084 ScalarMag err = (_val1-_val2).norm2();\
00085 if (!this->checkTest(spec_, err, "[" #form1 "] == [" #form2 "]")) pass = false;\
00086 }
00087
00088
00089
00090
00091
00092
00093
00094 namespace Playa
00095 {
00096
00097
00098 template <class Scalar>
00099 class LinearCombinationTester : public TesterBase<Scalar>
00100 {
00101 public:
00102
00103 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00104
00105
00106 LinearCombinationTester(int nLocalRows, double onProcDensity,
00107 double offProcDensity,
00108 const VectorType<Scalar>& vecType,
00109 const TestSpecifier<Scalar>& spec);
00110
00111
00112 bool runAllTests() const ;
00113
00114
00115 private:
00116
00117
00118 bool nonModifyingOpTests() const ;
00119
00120
00121 bool selfModifyingOpTests() const ;
00122
00123 TestSpecifier<Scalar> spec_;
00124
00125 int nLocalRows_;
00126 double onProcDensity_;
00127 double offProcDensity_;
00128 VectorType<Scalar> vecType_;
00129
00130 };
00131
00132 template <class Scalar>
00133 inline LinearCombinationTester<Scalar>
00134 ::LinearCombinationTester(int nLocalRows, double onProcDensity,
00135 double offProcDensity,
00136 const VectorType<Scalar>& vecType,
00137 const TestSpecifier<Scalar>& spec)
00138 : TesterBase<Scalar>(),
00139 spec_(spec),
00140 nLocalRows_(nLocalRows),
00141 onProcDensity_(onProcDensity),
00142 offProcDensity_(offProcDensity),
00143 vecType_(vecType)
00144 {;}
00145
00146 template <class Scalar>
00147 inline bool LinearCombinationTester<Scalar>
00148 ::runAllTests() const
00149 {
00150 bool pass = true;
00151
00152 pass = nonModifyingOpTests() && pass;
00153 pass = selfModifyingOpTests() && pass;
00154
00155 return pass;
00156 }
00157
00158 template <class Scalar>
00159 inline bool LinearCombinationTester<Scalar>
00160 ::nonModifyingOpTests() const
00161 {
00162 bool pass = true;
00163
00164 RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_,
00165 onProcDensity_, offProcDensity_,
00166 vecType_);
00167 RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_,
00168 onProcDensity_, offProcDensity_,
00169 vecType_);
00170 RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_,
00171 onProcDensity_, offProcDensity_,
00172 vecType_);
00173
00174
00175 LinearOperator<double> A = ABuilder.getOp();
00176 LinearOperator<Scalar> B = BBuilder.getOp();
00177 LinearOperator<Scalar> C = CBuilder.getOp();
00178
00179 Vector<Scalar> x = A.domain().createMember();
00180 Vector<Scalar> y = A.domain().createMember();
00181 Vector<Scalar> z = A.domain().createMember();
00182
00183 this->randomizeVec(x);
00184 this->randomizeVec(y);
00185 this->randomizeVec(z);
00186
00187
00188 TESTER(x*2.0, 2.0*x);
00189
00190 TESTER(2.0*(x + y), 2.0*x + 2.0*y);
00191
00192 TESTER(2.0*(x - y), 2.0*x - 2.0*y);
00193
00194 TESTER((2.0*x + y) - y, 2.0*x);
00195
00196 TESTER(-1.0*y + (2.0*x + y), 2.0*x);
00197
00198 TESTER((x + y)*2.0, 2.0*x + 2.0*y);
00199
00200 TESTER((x - y)*2.0, 2.0*x - 2.0*y);
00201
00202 TESTER(2.0*(x - y), -2.0*(y - x));
00203
00204 TESTER(0.25*(2.0*(x + y) - 2.0*(x - y)), y);
00205
00206 TESTER((2.0*A)*x, 2.0*(A*x));
00207
00208 TESTER(2.0*(A*x), (A*x)*2.0);
00209
00210 TESTER(A*(B*x), (A*B)*x);
00211
00212 TESTER(2.0*A*(B*x), A*(B*(2.0*x)));
00213
00214 TESTER(3.0*(2.0*A)*x, 6.0*(A*x));
00215
00216 TESTER(y + A*x, A*x + y);
00217
00218
00219 TESTER(z + (A*x + B*y), (B*y + A*x) + z);
00220
00221
00222 TESTER(z - (A*x + B*y), -1.0*((B*y + A*x) - z));
00223
00224 TESTER(C*z + (A*x + B*y), (B*y + A*x) + C*z);
00225
00226 TESTER(C*z - (A*x + B*y), -1.0*((B*y + A*x) - C*z));
00227
00228 TESTER(2.0*z + (A*x + B*y), (B*y + A*x) + 2.0*z);
00229
00230 TESTER(2.0*z - (A*x + B*y), -1.0*((B*y + A*x) - 2.0*z));
00231
00232 TESTER(A*x - y, -1.0*(y - A*x));
00233
00234 TESTER(A*x + B*y, B*y + A*x);
00235
00236 TESTER(A*x - B*y - A*x + B*y +z, z);
00237
00238 TESTER(2.0*(A*x + y), 2.0*A*x + 2.0*y);
00239
00240 TESTER(2.0*(A*x + B*y), A*x + B*y + A*x + B*y);
00241
00242 TESTER(2.0*(y + A*x), 2.0*y + 2.0*(A*x));
00243
00244 TESTER(x + 2.0*A*y, x + 2.0*(A*y));
00245
00246 TESTER(2.0*A*y + x, 2.0*(A*y) + x);
00247
00248 TESTER(2.0*A*(3.0*B)*y, 6.0*(A*B*y));
00249
00250 TESTER(2.0*A*(3.0*B)*y, 6.0*(A*(B*y)));
00251
00252 TESTER(2.0*A*(3.0*B + 2.0*A)*x, 6.0*A*B*x + 4.0*A*A*x );
00253
00254 TESTER(2.0*(A*x + B*y), 2.0*A*x + 2.0*B*y);
00255
00256 TESTER(2.0*(A*x - B*y), 2.0*A*x - 2.0*B*y);
00257
00258 TESTER(2.0*(A*x + B*y + z), 2.0*A*x + 2.0*B*y + 2.0*z);
00259
00260 TESTER(2.0*(A*x + 3.0*B*y), 2.0*A*x + 6.0*B*y);
00261
00262 TESTER(2.0*(A*x + 3.0*(z + B*y)), 2.0*A*x + 6.0*B*y + 6.0*z);
00263
00264 TESTER(2.0*(z + A*x + B*y + z), 2.0*A*x + 2.0*B*y + 4.0*z);
00265
00266 TESTER(2.0*(3.0*(z + A*x) + B*y), 6.0*z + 6.0*A*x + 2.0*B*y);
00267
00268 TESTER(2.0*(3.0*(z + A*x) + 4.0*(B*y + z)), 6.0*z + 6.0*A*x + 8.0*B*y + 8.0*z);
00269
00270 TESTER((A*x + B*y) + (A*y + B*x), (A + B)*x + (A+B)*y);
00271 TESTER((A*x + B*y) - (A*y + B*x), A*x - A*y + B*y - B*x);
00272
00273 TESTER((A*x + B*y) + 2.0*(A*y + B*x), A*(x + 2.0*y) + B*(2.0*x + y));
00274 TESTER((A*x + B*y) - 2.0*(A*y + B*x), A*(x - 2.0*y) + B*(y - 2.0*x));
00275
00276
00277 return pass;
00278 }
00279
00280
00281 template <class Scalar>
00282 inline bool LinearCombinationTester<Scalar>
00283 ::selfModifyingOpTests() const
00284 {
00285 bool pass = true;
00286
00287 RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_,
00288 onProcDensity_, offProcDensity_,
00289 vecType_);
00290 RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_,
00291 onProcDensity_, offProcDensity_,
00292 vecType_);
00293 RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_,
00294 onProcDensity_, offProcDensity_,
00295 vecType_);
00296
00297
00298 LinearOperator<double> A = ABuilder.getOp();
00299 LinearOperator<double> B = BBuilder.getOp();
00300 LinearOperator<double> C = CBuilder.getOp();
00301
00302 VectorSpace<Scalar> vs = A.domain();
00303 A = identityOperator(vs);
00304 B = identityOperator(vs);
00305 C = identityOperator(vs);
00306
00307 Vector<Scalar> x = A.domain().createMember();
00308 Vector<Scalar> y = A.domain().createMember();
00309 Vector<Scalar> z = A.domain().createMember();
00310
00311 this->randomizeVec(x);
00312 this->randomizeVec(y);
00313 this->randomizeVec(z);
00314
00315 Vector<Scalar> a = x.copy();
00316 Vector<Scalar> b = y.copy();
00317 Vector<Scalar> c = z.copy();
00318
00319
00320 Out::os() << "starting linear combination tests" << std::endl;
00321
00322 x = 2.0*A*x;
00323 Scalar err = (x - 2.0*A*a).norm2();
00324 if (!this->checkTest(spec_, err, "x=2.0*A*x")) pass = false;
00325
00326 a = x.copy();
00327 x = x + y;
00328 err = (x - (a + y)).norm2();
00329 if (!this->checkTest(spec_, err, "x=x+y")) pass = false;
00330
00331 a = x.copy();
00332 x = y + x;
00333 err = (x - (y + a)).norm2();
00334 if (!this->checkTest(spec_, err, "x=y+x")) pass = false;
00335
00336 a = x.copy();
00337 x = A*x + B*y;
00338 err = (x - (A*a + B*y)).norm2();
00339 if (!this->checkTest(spec_, err, "x=A*x+B*y")) pass = false;
00340
00341 a = x.copy();
00342 x = B*y + A*x;
00343 err = (x - (B*y + A*a)).norm2();
00344 if (!this->checkTest(spec_, err, "x=B*y+A*x")) pass = false;
00345
00346 a = x.copy();
00347 x = A*x + (B*y + C*x);
00348 err = (x - (A*a + (B*y + C*a))).norm2();
00349 if (!this->checkTest(spec_, err, "x=A*x + (B*y + C*x)")) pass = false;
00350
00351 a = x.copy();
00352 x = (A*x + B*y) + C*x;
00353 err = (x - ((A*a + B*y) + C*a)).norm2();
00354 if (!this->checkTest(spec_, err, "x=(A*x + B*y) + C*x")) pass = false;
00355
00356
00357 Vector<Scalar> u;
00358 u = 2.0*A*B*x;
00359 err = (u - 2.0*A*B*x).norm2();
00360 if (!this->checkTest(spec_, err, "(empty) u=2*A*B*x")) pass = false;
00361
00362 u = 2.0*A*B*x;
00363 err = (u - 2.0*A*B*x).norm2();
00364 if (!this->checkTest(spec_, err, "(non-empty) u=2*A*B*x")) pass = false;
00365
00366
00367 Vector<Scalar> v;
00368 v = 2.0*x + 3.0*y;
00369 err = (v - (2.0*x + 3.0*y)).norm2();
00370 if (!this->checkTest(spec_, err, "(empty) v=2*x + 3*y")) pass = false;
00371
00372 v = 2.0*x + 3.0*y;
00373 err = (v - (2.0*x + 3.0*y)).norm2();
00374 if (!this->checkTest(spec_, err, "(non-empty) v=2*x + 3*y")) pass = false;
00375
00376
00377 Vector<Scalar> w;
00378 w = 2.0*x + 3.0*y + 5.0*z;
00379 err = (w - (2.0*x + 3.0*y + 5.0*z)).norm2();
00380 if (!this->checkTest(spec_, err, "(empty) w=2*x + 3*y + 5*z")) pass = false;
00381
00382 w = 2.0*x + 3.0*y + 5.0*z;
00383 err = (w - (2.0*x + 3.0*y + 5.0*z)).norm2();
00384 if (!this->checkTest(spec_, err, "(non-empty) w=2*x + 3*y + 5*z")) pass = false;
00385
00386
00387 Vector<Scalar> w2;
00388 w2 = 2.0*x + 3.0*y + 5.0*z + 7.0*u;
00389 err = (w2 - (2.0*x + 3.0*y + 5.0*z + 7.0*u)).norm2();
00390 if (!this->checkTest(spec_, err,
00391 "(empty) w2=2*x + 3*y + 5*z + 7*u")) pass = false;
00392
00393 w2 = 2.0*x + 3.0*y + 5.0*z + 7.0*u;
00394 err = (w2 - (2.0*x + 3.0*y + 5.0*z + 7.0*u)).norm2();
00395 if (!this->checkTest(spec_, err,
00396 "(non-empty) w2=2*x + 3*y + 5*z + 7*u")) pass = false;
00397
00398
00399 x = 2.0*x + 3.0*y + 5.0*z;
00400 err = (w - x).norm2();
00401 if (!this->checkTest(spec_, err, "x=2*x + 3*y + 5*z")) pass = false;
00402
00403
00404 return pass;
00405 }
00406
00407
00408 }
00409 #endif