TSFLinearCombinationTester.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 /* ***********************************************************************
00003 // 
00004 //           TSFExtended: Trilinos Solver Framework Extended
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // **********************************************************************/
00027  /* @HEADER@ */
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   /** \brief Local typedef for promoted scalar magnitude */
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   /* test assignment of OpTimesLC into empty and non-empty vectors */
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   /* test assignment of LC2 into empty and non-empty vectors */
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

Site Contact