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 #ifndef TSF_LINEARCOMBINATIONTESTER_HPP
00031 #define TSF_LINEARCOMBINATIONTESTER_HPP
00032
00033 #include "TSFLinearOperatorDecl.hpp"
00034 #include "TSFLinearCombinationImpl.hpp"
00035 #include "TSFSimpleComposedOpDecl.hpp"
00036 #include "TSFSimpleScaledOpDecl.hpp"
00037 #include "TSFSimpleAddedOpDecl.hpp"
00038 #include "SundanceOut.hpp"
00039 #include "TSFVectorDecl.hpp"
00040 #include "TSFTesterBase.hpp"
00041 #include "TSFRandomSparseMatrixBuilderDecl.hpp"
00042 #include "Thyra_TestSpecifier.hpp"
00043 #include "Teuchos_ScalarTraits.hpp"
00044
00045 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00046 #include "TSFVectorImpl.hpp"
00047 #include "TSFLinearOperatorImpl.hpp"
00048 #include "TSFRandomSparseMatrixBuilderImpl.hpp"
00049 #include "TSFSimpleComposedOpImpl.hpp"
00050 #include "TSFSimpleScaledOpImpl.hpp"
00051 #include "TSFSimpleAddedOpImpl.hpp"
00052 #endif
00053
00054 using namespace TSFExtended;
00055 using namespace Teuchos;
00056 using namespace Sundance;
00057
00058 using Thyra::TestSpecifier;
00059
00060
00061 #define TESTER(form1, form2)\
00062 {\
00063 Out::os() << "testing " #form1 << std::endl;\
00064 Vector<Scalar> _val1 = form1;\
00065 Out::os() << "testing " #form2 << std::endl;\
00066 Vector<Scalar> _val2 = form2;\
00067 Out::os() << "done testing... checking error" << std::endl;\
00068 ScalarMag err = (_val1-_val2).norm2();\
00069 if (!checkTest(spec_, err, "[" #form1 "] == [" #form2 "]")) pass = false;\
00070 }
00071
00072
00073
00074
00075
00076
00077
00078 namespace TSFExtended
00079 {
00080
00081
00082 template <class Scalar>
00083 class LinearCombinationTester : public TesterBase<Scalar>
00084 {
00085 public:
00086
00087 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00088
00089
00090 LinearCombinationTester(int nLocalRows, double onProcDensity,
00091 double offProcDensity,
00092 const VectorType<Scalar>& vecType,
00093 const TestSpecifier<Scalar>& spec);
00094
00095
00096 bool runAllTests() const ;
00097
00098
00099 private:
00100
00101
00102 bool nonModifyingOpTests() const ;
00103
00104
00105 bool selfModifyingOpTests() const ;
00106
00107 TestSpecifier<Scalar> spec_;
00108
00109 int nLocalRows_;
00110 double onProcDensity_;
00111 double offProcDensity_;
00112 VectorType<Scalar> vecType_;
00113
00114 };
00115
00116 template <class Scalar>
00117 inline LinearCombinationTester<Scalar>
00118 ::LinearCombinationTester(int nLocalRows, double onProcDensity,
00119 double offProcDensity,
00120 const VectorType<Scalar>& vecType,
00121 const TestSpecifier<Scalar>& spec)
00122 : TesterBase<Scalar>(),
00123 spec_(spec),
00124 nLocalRows_(nLocalRows),
00125 onProcDensity_(onProcDensity),
00126 offProcDensity_(offProcDensity),
00127 vecType_(vecType)
00128 {;}
00129
00130 template <class Scalar>
00131 inline bool LinearCombinationTester<Scalar>
00132 ::runAllTests() const
00133 {
00134 bool pass = true;
00135
00136 pass = nonModifyingOpTests() && pass;
00137 pass = selfModifyingOpTests() && pass;
00138
00139 return pass;
00140 }
00141
00142 template <class Scalar>
00143 inline bool LinearCombinationTester<Scalar>
00144 ::nonModifyingOpTests() const
00145 {
00146 bool pass = true;
00147
00148 RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_,
00149 onProcDensity_, offProcDensity_,
00150 vecType_);
00151 RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_,
00152 onProcDensity_, offProcDensity_,
00153 vecType_);
00154 RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_,
00155 onProcDensity_, offProcDensity_,
00156 vecType_);
00157
00158
00159 LinearOperator<double> A = ABuilder.getOp();
00160
00161
00162 LinearOperator<Scalar> B = BBuilder.getOp();
00163 LinearOperator<Scalar> C = CBuilder.getOp();
00164
00165 Vector<Scalar> x = A.domain().createMember();
00166 Vector<Scalar> y = A.domain().createMember();
00167 Vector<Scalar> z = A.domain().createMember();
00168
00169 randomizeVec(x);
00170 randomizeVec(y);
00171 randomizeVec(z);
00172
00173
00174 TESTER(x*2.0, 2.0*x);
00175
00176 TESTER(2.0*(x + y), 2.0*x + 2.0*y);
00177
00178 TESTER(2.0*(x - y), 2.0*x - 2.0*y);
00179
00180 TESTER((x + y)*2.0, 2.0*x + 2.0*y);
00181
00182 TESTER((x - y)*2.0, 2.0*x - 2.0*y);
00183
00184 TESTER(2.0*(x - y), -2.0*(y - x));
00185
00186 TESTER(0.25*(2.0*(x + y) - 2.0*(x - y)), y);
00187
00188 TESTER((2.0*A)*x, 2.0*(A*x));
00189
00190 TESTER(2.0*(A*x), (A*x)*2.0);
00191
00192 TESTER(A*(B*x), (A*B)*x);
00193
00194 TESTER(2.0*A*(B*x), A*(B*(2.0*x)));
00195
00196 TESTER(3.0*(2.0*A)*x, 6.0*(A*x));
00197
00198 TESTER(y + A*x, A*x + y);
00199
00200
00201 TESTER(z + (A*x + B*y), (B*y + A*x) + z);
00202
00203
00204 TESTER(z - (A*x + B*y), -1.0*((B*y + A*x) - z));
00205
00206 TESTER(C*z + (A*x + B*y), (B*y + A*x) + C*z);
00207
00208 TESTER(C*z - (A*x + B*y), -1.0*((B*y + A*x) - C*z));
00209
00210 TESTER(2.0*z + (A*x + B*y), (B*y + A*x) + 2.0*z);
00211
00212 TESTER(2.0*z - (A*x + B*y), -1.0*((B*y + A*x) - 2.0*z));
00213
00214 TESTER(A*x - y, -1.0*(y - A*x));
00215
00216 TESTER(A*x + B*y, B*y + A*x);
00217
00218 TESTER(A*x - B*y - A*x + B*y +z, z);
00219
00220 TESTER(2.0*(A*x + y), 2.0*A*x + 2.0*y);
00221
00222 TESTER(2.0*(A*x + B*y), A*x + B*y + A*x + B*y);
00223
00224 TESTER(2.0*(y + A*x), 2.0*y + 2.0*(A*x));
00225
00226 TESTER(x + 2.0*A*y, x + 2.0*(A*y));
00227
00228 TESTER(2.0*A*y + x, 2.0*(A*y) + x);
00229
00230 TESTER(2.0*(A*x + B*y), 2.0*A*x + 2.0*B*y);
00231
00232 TESTER(2.0*(A*x - B*y), 2.0*A*x - 2.0*B*y);
00233
00234 TESTER(2.0*(A*x + B*y + z), 2.0*A*x + 2.0*B*y + 2.0*z);
00235
00236 TESTER(2.0*(A*x + 3.0*B*y), 2.0*A*x + 6.0*B*y);
00237
00238 TESTER(2.0*(A*x + 3.0*(z + B*y)), 2.0*A*x + 6.0*B*y + 6.0*z);
00239
00240 TESTER(2.0*(z + A*x + B*y + z), 2.0*A*x + 2.0*B*y + 4.0*z);
00241
00242 TESTER(2.0*(3.0*(z + A*x) + B*y), 6.0*z + 6.0*A*x + 2.0*B*y);
00243
00244 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);
00245
00246 TESTER((A*x + B*y) + (A*y + B*x), (A + B)*x + (A+B)*y);
00247 TESTER((A*x + B*y) - (A*y + B*x), A*x - A*y + B*y - B*x);
00248
00249 TESTER((A*x + B*y) + 2.0*(A*y + B*x), A*(x + 2.0*y) + B*(2.0*x + y));
00250 TESTER((A*x + B*y) - 2.0*(A*y + B*x), A*(x - 2.0*y) + B*(y - 2.0*x));
00251
00252
00253 return pass;
00254 }
00255
00256
00257 template <class Scalar>
00258 inline bool LinearCombinationTester<Scalar>
00259 ::selfModifyingOpTests() const
00260 {
00261 bool pass = true;
00262
00263 RandomSparseMatrixBuilder<double> ABuilder(nLocalRows_, nLocalRows_,
00264 onProcDensity_, offProcDensity_,
00265 vecType_);
00266 RandomSparseMatrixBuilder<double> BBuilder(nLocalRows_, nLocalRows_,
00267 onProcDensity_, offProcDensity_,
00268 vecType_);
00269 RandomSparseMatrixBuilder<double> CBuilder(nLocalRows_, nLocalRows_,
00270 onProcDensity_, offProcDensity_,
00271 vecType_);
00272
00273 LinearOperator<double> A = ABuilder.getOp();
00274 LinearOperator<double> B = BBuilder.getOp();
00275 LinearOperator<double> C = CBuilder.getOp();
00276
00277 Vector<Scalar> x = A.domain().createMember();
00278 Vector<Scalar> y = A.domain().createMember();
00279 Vector<Scalar> z = A.domain().createMember();
00280
00281 randomizeVec(x);
00282 randomizeVec(y);
00283 randomizeVec(z);
00284
00285 Vector<Scalar> a = x.copy();
00286 Vector<Scalar> b = y.copy();
00287 Vector<Scalar> c = z.copy();
00288
00289
00290 Out::os() << "starting linear combination tests" << std::endl;
00291
00292 x = 2.0*A*x;
00293 Scalar err = (x - 2.0*A*a).norm2();
00294 if (!checkTest(spec_, err, "x=2.0*A*x")) pass = false;
00295
00296 a = x.copy();
00297 x = x + y;
00298 err = (x - (a + y)).norm2();
00299 if (!checkTest(spec_, err, "x=x+y")) pass = false;
00300
00301 a = x.copy();
00302 x = y + x;
00303 err = (x - (y + a)).norm2();
00304 if (!checkTest(spec_, err, "x=y+x")) pass = false;
00305
00306 a = x.copy();
00307 x = A*x + B*y;
00308 err = (x - (A*a + B*y)).norm2();
00309 if (!checkTest(spec_, err, "x=A*x+B*y")) pass = false;
00310
00311 a = x.copy();
00312 x = B*y + A*x;
00313 err = (x - (B*y + A*a)).norm2();
00314 if (!checkTest(spec_, err, "x=B*y+A*x")) pass = false;
00315
00316 a = x.copy();
00317 x = A*x + (B*y + C*x);
00318 err = (x - (A*a + (B*y + C*a))).norm2();
00319 if (!checkTest(spec_, err, "x=A*x + (B*y + C*x)")) pass = false;
00320
00321 a = x.copy();
00322 x = (A*x + B*y) + C*x;
00323 err = (x - ((A*a + B*y) + C*a)).norm2();
00324 if (!checkTest(spec_, err, "x=(A*x + B*y) + C*x")) pass = false;
00325
00326
00327 Vector<Scalar> u;
00328 u = 2.0*A*B*x;
00329 err = (u - 2.0*A*B*x).norm2();
00330 if (!checkTest(spec_, err, "(empty) u=2*A*B*x")) pass = false;
00331
00332 u = 2.0*A*B*x;
00333 err = (u - 2.0*A*B*x).norm2();
00334 if (!checkTest(spec_, err, "(non-empty) u=2*A*B*x")) pass = false;
00335
00336
00337 Vector<Scalar> v;
00338 v = 2.0*x + 3.0*y;
00339 err = (v - (2.0*x + 3.0*y)).norm2();
00340 if (!checkTest(spec_, err, "(empty) v=2*x + 3*y")) pass = false;
00341
00342 v = 2.0*x + 3.0*y;
00343 err = (v - (2.0*x + 3.0*y)).norm2();
00344 if (!checkTest(spec_, err, "(non-empty) v=2*x + 3*y")) pass = false;
00345
00346
00347
00348
00349
00350 return pass;
00351 }
00352
00353
00354 }
00355 #endif