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 #ifndef THYRA_VECTOROPTESTER_HPP
00030 #define THYRA_VECTOROPTESTER_HPP
00031
00032 #include "Thyra_VectorImpl.hpp"
00033 #include "Thyra_VectorSpaceImpl.hpp"
00034 #include "Thyra_TesterBase.hpp"
00035 #include "Teuchos_ScalarTraits.hpp"
00036 #include "Teuchos_CommHelpers.hpp"
00037 #include "Thyra_ProductVectorSpaceBase.hpp"
00038 #include "Thyra_LinearCombinationImpl.hpp"
00039
00040 namespace Thyra
00041 {
00042 using namespace Teuchos;
00043 using std::ostream;
00044
00049 template <class Scalar>
00050 class VectorOpTester : public TesterBase<Scalar>
00051 {
00052 public:
00054 typedef typename Teuchos::ScalarTraits<Scalar>::magnitudeType ScalarMag;
00055
00057 VectorOpTester(const RCP<const Comm<int> >& comm,
00058 const VectorSpace<Scalar>& space,
00059 Teuchos::RCP<Teuchos::FancyOStream>& out,
00060 const TestSpecifier<Scalar>& spec);
00061
00063 bool runAllTests() const ;
00064
00066 bool sumTest() const ;
00067
00069 bool setElementUsingBracketTest() const ;
00070
00072 bool dotStarTest() const ;
00073
00075 bool scalarMultTest() const ;
00076
00078 bool overloadedUpdateTest() const ;
00079
00080 private:
00081 TestSpecifier<Scalar> spec_;
00082 };
00083
00084 template <class Scalar>
00085 inline VectorOpTester<Scalar>
00086 ::VectorOpTester(const RCP<const Comm<int> >& comm,
00087 const VectorSpace<Scalar>& space,
00088 Teuchos::RCP<Teuchos::FancyOStream>& out,
00089 const TestSpecifier<Scalar>& spec)
00090 : TesterBase<Scalar>(comm, space, 1, out),
00091 spec_(spec)
00092 {;}
00093
00094 template <class Scalar>
00095 inline bool VectorOpTester<Scalar>
00096 ::runAllTests() const
00097 {
00098 bool pass = true;
00099
00100 pass = setElementUsingBracketTest() && pass;
00101 pass = sumTest() && pass;
00102 pass = dotStarTest() && pass;
00103 pass = scalarMultTest() && pass;
00104 pass = overloadedUpdateTest() && pass;
00105
00106 return pass;
00107 }
00108
00109 template <class Scalar>
00110 inline bool VectorOpTester<Scalar>
00111 ::sumTest() const
00112 {
00113
00114 using std::endl;
00115
00116 typedef Teuchos::ScalarTraits<Scalar> ST;
00117 ScalarMag err = ST::magnitude(ST::zero());
00118
00119 this->out() << "running vector addition test..." << endl;
00120
00121 Vector<Scalar> a = this->space().createMember();
00122 Vector<Scalar> b = this->space().createMember();
00123 Vector<Scalar> x = this->space().createMember();
00124 Vector<Scalar> y = this->space().createMember();
00125 randomizeVec(a);
00126 randomizeVec(b);
00127
00128
00129 x = a + b ;
00130
00131
00132
00133 for (int i=0; i<this->space().dim(); i++)
00134 {
00135 Scalar a_i = a[i];
00136 Scalar b_i = b[i];
00137 y[i] = a_i + b_i;
00138 }
00139 err = normInf(x-y);
00140 return this->checkTest(spec_, err, "vector addition");
00141 }
00142
00143
00144
00145
00146 template <class Scalar>
00147 inline bool VectorOpTester<Scalar>
00148 ::setElementUsingBracketTest() const
00149 {
00150
00151 using std::endl;
00152
00153 typedef Teuchos::ScalarTraits<Index> IST;
00154 typedef Teuchos::ScalarTraits<Scalar> ST;
00155
00156
00157 if (ST::isComparable && spec_.doTest())
00158 {
00159 ScalarMag err = ST::magnitude(ST::zero());
00160
00161 Vector<Scalar> a = this->space().createMember();
00162
00163
00164
00165
00166
00167
00168 zeroOut(a);
00169
00170 int N = this->space().dim();
00171 int nTrials = 50;
00172
00173
00174 unsigned int seed = 107*N % 101;
00175 ST::seedrandom( seed );
00176
00177 for (int t=0; t<nTrials; t++)
00178 {
00179 zeroOut(a);
00180 Index minIndex = IST::random() % N;
00181 Index maxIndex = IST::random() % N;
00182
00183 if (minIndex == maxIndex) continue;
00184 a[minIndex] = -ST::one();
00185 a[maxIndex] = ST::one();
00186 Index findMin = -1;
00187 Index findMax = -1;
00188 Scalar minVal = Thyra::minloc(a, findMin);
00189 Scalar maxVal = Thyra::maxloc(a, findMax);
00190 err += ST::magnitude(-ST::one() - minVal);
00191 err += ST::magnitude(ST::one() - maxVal);
00192 err += ST::magnitude(findMin - minIndex);
00193 err += ST::magnitude(findMax - maxIndex);
00194 }
00195
00196 return this->checkTest(spec_, err, "bracket operator");
00197 }
00198 else
00199 {
00200 this->out() << "skipping bracket operator test..." << endl;
00201 return true;
00202 }
00203 }
00204
00205
00206
00207
00208 #ifdef HAVE_THYRA_COMPLEX
00209
00210
00211 template <>
00212 inline bool VectorOpTester<std::complex<double> >
00213 ::setElementUsingBracketTest() const
00214 {
00215 using std::endl;
00216 this->out() << "skipping vector bracket operator test..." << endl;
00217 return true;
00218 }
00219
00220
00221 #if defined(HAVE_THYRA_FLOAT)
00222 template <>
00223 inline bool VectorOpTester<std::complex<float> >
00224 ::setElementUsingBracketTest() const
00225 {
00226 using std::endl;
00227 this->out() << "skipping vector bracket operator test..." << endl;
00228 return true;
00229 }
00230 #endif
00231
00232
00233 #endif // HAVE_THYRA_COMPLEX
00234
00235
00236 template <class Scalar>
00237 inline bool VectorOpTester<Scalar>
00238 ::dotStarTest() const
00239 {
00240
00241 using std::endl;
00242
00243 typedef Teuchos::ScalarTraits<Scalar> ST;
00244 ScalarMag err = ST::magnitude(ST::zero());
00245
00246 this->out() << "running vector dotStar test..." << endl;
00247
00248 Vector<Scalar> a = this->space().createMember();
00249 Vector<Scalar> b = this->space().createMember();
00250 Vector<Scalar> x = this->space().createMember();
00251 Vector<Scalar> y = this->space().createMember();
00252 Vector<Scalar> z = this->space().createMember();
00253 randomizeVec(a);
00254 randomizeVec(b);
00255
00256 x = dotStar(a,b);
00257 z = dotSlash(x, b);
00258
00259 err = normInf(a-z);
00260
00261 this->out() << "|dotStar error|=" << err << endl;
00262 return this->checkTest(spec_, err, "dot-star");
00263 }
00264
00265
00266
00267 template <class Scalar>
00268 inline bool VectorOpTester<Scalar>
00269 ::scalarMultTest() const
00270 {
00271
00272 using std::endl;
00273
00274 typedef Teuchos::ScalarTraits<Scalar> ST;
00275 ScalarMag err = ST::magnitude(ST::zero());
00276
00277 this->out() << "running vector scalarMult test..." << endl;
00278
00279 Vector<Scalar> a = this->space().createMember();
00280 Vector<Scalar> x = this->space().createMember();
00281 Vector<Scalar> y = this->space().createMember();
00282 randomizeVec(a);
00283
00284
00285
00286 Scalar alpha = 3.14;
00287 x = alpha * a;
00288
00289
00290
00291 for (int i=0; i<this->space().dim(); i++)
00292 {
00293 Scalar a_i = a[i];
00294 y[i]= alpha *a_i;
00295 }
00296
00297 err = normInf(x-y);
00298
00299 this->out() << "|scalarMult error|=" << err << endl;
00300 return this->checkTest(spec_, err, "scalar multiplication");
00301
00302 }
00303
00304 template <class Scalar>
00305 inline bool VectorOpTester<Scalar>
00306 ::overloadedUpdateTest() const
00307 {
00308
00309 using std::endl;
00310
00311 typedef Teuchos::ScalarTraits<Scalar> ST;
00312 ScalarMag err = ST::magnitude(ST::zero());
00313
00314 this->out() << "running vector overloadedUpdate test..." << endl;
00315
00316 Vector<Scalar> a = this->space().createMember();
00317 Vector<Scalar> b = this->space().createMember();
00318 Vector<Scalar> x = this->space().createMember();
00319 Vector<Scalar> y = this->space().createMember();
00320 randomizeVec(a);
00321 randomizeVec(b);
00322
00323
00324 Scalar alpha = 3.14;
00325 Scalar beta = 1.4;
00326 x = alpha*a + beta*b;
00327
00328
00329 for (int i=0; i<this->space().dim(); i++)
00330 {
00331 Scalar a_i = a[i];
00332 Scalar b_i = b[i];
00333 y[i] = alpha*a_i + beta*b_i;
00334 }
00335
00336 err = normInf(x-y);
00337
00338 this->out() << "|overloadedUpdate error|=" << err << endl;
00339 return this->checkTest(spec_, err, "overloaded update");
00340
00341 }
00342
00343
00344 }
00345
00346 #endif