FadUnitTests.hpp

Go to the documentation of this file.
00001 // $Id$ 
00002 // $Source$ 
00003 // @HEADER
00004 // ***********************************************************************
00005 // 
00006 //                           Sacado Package
00007 //                 Copyright (2006) Sandia Corporation
00008 // 
00009 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00010 // the U.S. Government retains certain rights in this software.
00011 // 
00012 // This library is free software; you can redistribute it and/or modify
00013 // it under the terms of the GNU Lesser General Public License as
00014 // published by the Free Software Foundation; either version 2.1 of the
00015 // License, or (at your option) any later version.
00016 //  
00017 // This library is distributed in the hope that it will be useful, but
00018 // WITHOUT ANY WARRANTY; without even the implied warranty of
00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020 // Lesser General Public License for more details.
00021 //  
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License along with this library; if not, write to the Free Software
00024 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00025 // USA
00026 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00027 // (etphipp@sandia.gov).
00028 // 
00029 // ***********************************************************************
00030 // @HEADER
00031 
00032 #ifndef FADUNITTESTS_HPP
00033 #define FADUNITTESTS_HPP
00034 
00035 // Sacado includes
00036 #include "Sacado.hpp"
00037 #include "Sacado_Random.hpp"
00038 
00039 // Fad includes
00040 #include "Fad/fad.h"
00041 
00042 // Cppunit includes
00043 #include <cppunit/extensions/HelperMacros.h>
00044 
00045 #define COMPARE_VALUES(a, b) \
00046   CPPUNIT_ASSERT( std::abs(a-b) < this->tol_a + this->tol_r*std::abs(a) );
00047 
00048 #define COMPARE_FADS(a, b)                              \
00049 CPPUNIT_ASSERT(a.size() == b.size());     \
00050 CPPUNIT_ASSERT(a.hasFastAccess() == b.hasFastAccess()); \
00051 COMPARE_VALUES(a.val(), b.val());     \
00052 for (int i=0; i<a.size(); i++) {      \
00053   COMPARE_VALUES(a.dx(i), b.dx(i));     \
00054   COMPARE_VALUES(a.fastAccessDx(i), b.fastAccessDx(i)); \
00055  }              \
00056  ;
00057 
00058 #define BINARY_OP_TEST(TESTNAME,OP) \
00059   void TESTNAME () {        \
00060     c_dfad = a_dfad OP b_dfad;      \
00061     c_fad = a_fad OP b_fad;     \
00062     COMPARE_FADS(c_dfad, c_fad);      \
00063             \
00064     double val = urand.number();    \
00065     c_dfad = a_dfad OP val;     \
00066     c_fad = a_fad OP val;     \
00067     COMPARE_FADS(c_dfad, c_fad);      \
00068             \
00069     c_dfad = val OP b_dfad;     \
00070     c_fad = val OP b_fad;     \
00071     COMPARE_FADS(c_dfad, c_fad);      \
00072   }
00073 
00074 #define RELOP_TEST(TESTNAME,OP)     \
00075   void TESTNAME () {        \
00076     bool r1 = a_dfad OP b_dfad;     \
00077     bool r2 = a_fad OP b_fad;     \
00078     CPPUNIT_ASSERT(r1 == r2);     \
00079             \
00080     double val = urand.number();    \
00081     r1 = a_dfad OP val;             \
00082     r2 = a_fad OP val;              \
00083     CPPUNIT_ASSERT(r1 == r2);     \
00084             \
00085     r1 = val OP b_dfad;             \
00086     r2 = val OP b_fad;              \
00087     CPPUNIT_ASSERT(r1 == r2);     \
00088   }
00089 
00090 #define BINARY_FUNC_TEST(TESTNAME,FUNC) \
00091   void TESTNAME () {      \
00092     c_dfad = FUNC (a_dfad,b_dfad);  \
00093     c_fad = FUNC (a_fad,b_fad);   \
00094     COMPARE_FADS(c_dfad, c_fad);    \
00095               \
00096     double val = urand.number();  \
00097     c_dfad = FUNC (a_dfad,val);   \
00098     c_fad = FUNC (a_fad,val);   \
00099     COMPARE_FADS(c_dfad, c_fad);    \
00100               \
00101     c_dfad = FUNC (val,b_dfad);   \
00102     c_fad = FUNC (val,b_fad);   \
00103     COMPARE_FADS(c_dfad, c_fad);    \
00104   }
00105 
00106 #define UNARY_OP_TEST(TESTNAME,OP)      \
00107   void TESTNAME () {          \
00108     c_dfad = OP a_dfad;         \
00109     c_fad = OP a_fad;         \
00110     COMPARE_FADS(c_dfad, c_fad);        \
00111   }
00112 
00113 #define UNARY_FUNC_TEST(TESTNAME,FUNC)      \
00114   void TESTNAME () {          \
00115     c_dfad = FUNC (a_dfad);       \
00116     c_fad = FUNC (a_fad);       \
00117     COMPARE_FADS(c_dfad, c_fad);        \
00118   }
00119 
00120 #define UNARY_ASSIGNOP_TEST(TESTNAME,OP)    \
00121   void TESTNAME () {          \
00122     c_dfad OP a_dfad;         \
00123     c_fad OP a_fad;         \
00124     COMPARE_FADS(c_dfad, c_fad);        \
00125               \
00126     double val = urand.number();      \
00127     c_dfad OP val;          \
00128     c_fad OP val;         \
00129     COMPARE_FADS(c_dfad, c_fad);        \
00130   }
00131 
00132 // A class for testing each Fad operation
00133 template <class FadType, class ScalarType>
00134 class FadOpsUnitTest : public CppUnit::TestFixture {
00135 
00136   CPPUNIT_TEST_SUITE( FadOpsUnitTest );
00137   
00138   CPPUNIT_TEST(testAddition);
00139   CPPUNIT_TEST(testSubtraction);
00140   CPPUNIT_TEST(testMultiplication);
00141   CPPUNIT_TEST(testDivision);
00142 
00143   CPPUNIT_TEST(testEquals);
00144   CPPUNIT_TEST(testNotEquals);
00145   CPPUNIT_TEST(testLessThanOrEquals);
00146   CPPUNIT_TEST(testGreaterThanOrEquals);
00147   CPPUNIT_TEST(testLessThan);
00148   CPPUNIT_TEST(testGreaterThan);
00149 
00150   CPPUNIT_TEST(testPow);
00151   CPPUNIT_TEST(testMax);
00152   CPPUNIT_TEST(testMin);
00153 
00154   CPPUNIT_TEST(testUnaryPlus);
00155   CPPUNIT_TEST(testUnaryMinus);
00156   
00157   CPPUNIT_TEST(testExp);
00158   CPPUNIT_TEST(testLog);
00159   CPPUNIT_TEST(testLog10);
00160   CPPUNIT_TEST(testSqrt);
00161   CPPUNIT_TEST(testCos);
00162   CPPUNIT_TEST(testSin);
00163   CPPUNIT_TEST(testTan);
00164   CPPUNIT_TEST(testACos);
00165   CPPUNIT_TEST(testASin);
00166   CPPUNIT_TEST(testATan);
00167   CPPUNIT_TEST(testCosh);
00168   CPPUNIT_TEST(testSinh);
00169   CPPUNIT_TEST(testTanh);
00170   CPPUNIT_TEST(testAbs);
00171   CPPUNIT_TEST(testFAbs);
00172 
00173   CPPUNIT_TEST(testPlusEquals);
00174   CPPUNIT_TEST(testMinusEquals);
00175   CPPUNIT_TEST(testTimesEquals);
00176   CPPUNIT_TEST(testDivideEquals);
00177 
00178   CPPUNIT_TEST(testComposite1);
00179 
00180   CPPUNIT_TEST(testPlusLR);
00181   CPPUNIT_TEST(testMinusLR);
00182   CPPUNIT_TEST(testTimesLR);
00183   CPPUNIT_TEST(testDivideLR);
00184 
00185   CPPUNIT_TEST_SUITE_END();
00186 
00187 public:
00188 
00189   FadOpsUnitTest();
00190 
00191   FadOpsUnitTest(int numComponents, ScalarType absolute_tolerance, 
00192      ScalarType relative_tolerance);
00193 
00194   void setUp();
00195 
00196   void tearDown();
00197 
00198   BINARY_OP_TEST(testAddition, +);
00199   BINARY_OP_TEST(testSubtraction, -);
00200   BINARY_OP_TEST(testMultiplication, *);
00201   BINARY_OP_TEST(testDivision, /);
00202 
00203   RELOP_TEST(testEquals, ==);
00204   RELOP_TEST(testNotEquals, !=);
00205   RELOP_TEST(testLessThanOrEquals, <=);
00206   RELOP_TEST(testGreaterThanOrEquals, >=);
00207   RELOP_TEST(testLessThan, <);
00208   RELOP_TEST(testGreaterThan, >);
00209 
00210   BINARY_FUNC_TEST(testPow, pow);
00211 
00212   UNARY_OP_TEST(testUnaryPlus, +);
00213   UNARY_OP_TEST(testUnaryMinus, -);
00214 
00215   UNARY_FUNC_TEST(testExp, exp);
00216   UNARY_FUNC_TEST(testLog, log);
00217   UNARY_FUNC_TEST(testLog10, log10);
00218   UNARY_FUNC_TEST(testSqrt, sqrt);
00219   UNARY_FUNC_TEST(testCos, cos);
00220   UNARY_FUNC_TEST(testSin, sin);
00221   UNARY_FUNC_TEST(testTan, tan);
00222   UNARY_FUNC_TEST(testACos, acos);
00223   UNARY_FUNC_TEST(testASin, asin);
00224   UNARY_FUNC_TEST(testATan, atan);
00225   UNARY_FUNC_TEST(testCosh, cosh);
00226   UNARY_FUNC_TEST(testSinh, sinh);
00227   UNARY_FUNC_TEST(testTanh, tanh);
00228   UNARY_FUNC_TEST(testAbs, abs);
00229   UNARY_FUNC_TEST(testFAbs, fabs);
00230 
00231   UNARY_ASSIGNOP_TEST(testPlusEquals, +=);
00232   UNARY_ASSIGNOP_TEST(testMinusEquals, -=);
00233   UNARY_ASSIGNOP_TEST(testTimesEquals, *=);
00234   UNARY_ASSIGNOP_TEST(testDivideEquals, /=);
00235 
00236   void testMax();
00237   void testMin();
00238 
00239   template <typename ScalarT>
00240   ScalarT composite1(const ScalarT& a, const ScalarT& b) {
00241     ScalarT t1 = 3. * a + sin(b) / log(fabs(a - b * 7.));
00242     ScalarT t2 = 1.0e3;
00243     ScalarT t3 = 5.7e4;
00244     ScalarT t4 = 3.2e5;
00245     t1 *= cos(a + exp(t1)) / 6. - tan(t1*sqrt(abs(a * log10(abs(b)))));
00246     t1 -= acos((6.+asin(pow(fabs(a),b)/t2))/t3) * asin(pow(fabs(b),2.)*1.0/t4) * atan((b*pow(2.,log(abs(a))))/(t3*t4));
00247     t1 /= cosh(b - 0.7) + 7.*sinh(t1 + 0.8)*tanh(9./a) - 9.;
00248     t1 += pow(abs(a*4.),b-8.)/cos(a*b*a);
00249     
00250   return t1;
00251 }
00252 
00253   void testComposite1() {
00254     c_dfad = composite1(a_dfad, b_dfad);
00255     c_fad = composite1(a_fad, b_fad);
00256     COMPARE_FADS(c_dfad, c_fad);
00257   }
00258 
00259   void testPlusLR() {
00260     FadType aa_dfad = a_dfad;
00261     FAD::Fad<ScalarType> aa_fad = a_fad;
00262     aa_dfad = 1.0;
00263     aa_fad = 1.0;
00264     aa_dfad = aa_dfad + b_dfad;
00265     aa_fad = aa_fad + b_fad;
00266     COMPARE_FADS(aa_dfad, aa_fad);
00267   }
00268 
00269   void testMinusLR() {
00270     FadType aa_dfad = a_dfad;
00271     FAD::Fad<ScalarType> aa_fad = a_fad;
00272     aa_dfad = 1.0;
00273     aa_fad = 1.0;
00274     aa_dfad = aa_dfad - b_dfad;
00275     aa_fad = aa_fad - b_fad;
00276     COMPARE_FADS(aa_dfad, aa_fad);
00277   }
00278 
00279   void testTimesLR() {
00280     FadType aa_dfad = a_dfad;
00281     FAD::Fad<ScalarType> aa_fad = a_fad;
00282     aa_dfad = 2.0;
00283     aa_fad = 2.0;
00284     aa_dfad = aa_dfad * b_dfad;
00285     aa_fad = aa_fad * b_fad;
00286     COMPARE_FADS(aa_dfad, aa_fad);
00287   }
00288 
00289   void testDivideLR() {
00290     FadType aa_dfad = a_dfad;
00291     FAD::Fad<ScalarType> aa_fad = a_fad;
00292     aa_dfad = 2.0;
00293     aa_fad = 2.0;
00294     aa_dfad = aa_dfad / b_dfad;
00295     aa_fad = aa_fad / b_fad;
00296     COMPARE_FADS(aa_dfad, aa_fad);
00297   }
00298 
00299 protected:
00300 
00301   // DFad variables
00302   FadType a_dfad, b_dfad, c_dfad;
00303 
00304   // Fad variables
00305   FAD::Fad<ScalarType> a_fad, b_fad, c_fad;
00306 
00307   // Random number generator
00308   Sacado::Random<ScalarType> urand;
00309 
00310   // Number of derivative components
00311   int n;
00312 
00313   // Tolerances to which fad objects should be the same
00314   ScalarType tol_a, tol_r;
00315 
00316 }; // class FadOpsUnitTest
00317 
00318 template <class FadType, class ScalarType>
00319 FadOpsUnitTest<FadType,ScalarType>::
00320 FadOpsUnitTest() :
00321   urand(), n(5), tol_a(1.0e-15), tol_r(1.0e-14) {}
00322 
00323 template <class FadType, class ScalarType>
00324 FadOpsUnitTest<FadType,ScalarType>::
00325 FadOpsUnitTest(int numComponents, ScalarType absolute_tolerance, 
00326          ScalarType relative_tolerance) :
00327   urand(), 
00328   n(numComponents), 
00329   tol_a(absolute_tolerance), 
00330   tol_r(relative_tolerance) {}
00331 
00332 template <class FadType, class ScalarType>
00333 void FadOpsUnitTest<FadType,ScalarType>::setUp() {
00334   ScalarType val;
00335 
00336   val = urand.number();
00337   a_dfad = FadType(n,val);
00338   a_fad = FAD::Fad<ScalarType>(n,val);
00339   
00340   val = urand.number();
00341   b_dfad = FadType(n,val);
00342   b_fad = FAD::Fad<ScalarType>(n,val);
00343 
00344   for (int i=0; i<n; i++) {
00345     val = urand.number();
00346     a_dfad.fastAccessDx(i) = val;
00347     a_fad.fastAccessDx(i) = val;
00348 
00349     val = urand.number();
00350     b_dfad.fastAccessDx(i) = val;
00351     b_fad.fastAccessDx(i) = val;
00352   }
00353 }
00354 
00355 template <class FadType, class ScalarType>
00356 void FadOpsUnitTest<FadType,ScalarType>::
00357 tearDown() {}
00358 
00359 template <class FadType, class ScalarType>
00360 void FadOpsUnitTest<FadType,ScalarType>::
00361 testMax() {
00362   ScalarType val;
00363 
00364   FadType aa_dfad = a_dfad + 1.0;
00365   c_dfad = max(aa_dfad, a_dfad);
00366   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00367   for (int i=0; i<n; i++) {
00368     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00369     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00370   }
00371   
00372   c_dfad = max(a_dfad, aa_dfad);
00373   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00374   for (int i=0; i<n; i++) {
00375     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00376     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00377   }
00378 
00379   c_dfad = max(a_dfad+1.0, a_dfad);
00380   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00381   for (int i=0; i<n; i++) {
00382     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00383     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00384   }
00385   
00386   c_dfad = max(a_dfad, a_dfad+1.0);
00387   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00388   for (int i=0; i<n; i++) {
00389     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00390     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00391   }
00392   
00393   val = a_dfad.val() + 1;
00394   c_dfad = max(a_dfad, val);
00395   COMPARE_VALUES(c_dfad.val(), val);
00396   for (int i=0; i<n; i++)
00397     COMPARE_VALUES(c_dfad.dx(i), 0.0);
00398   
00399   val = a_dfad.val() - 1;
00400   c_dfad = max(a_dfad, val);
00401   COMPARE_VALUES(c_dfad.val(), a_dfad.val());
00402   for (int i=0; i<n; i++) {
00403     COMPARE_VALUES(c_dfad.dx(i), a_dfad.dx(i));
00404     COMPARE_VALUES(c_dfad.fastAccessDx(i), a_dfad.fastAccessDx(i));
00405   }
00406 
00407   val = b_dfad.val() + 1;
00408   c_dfad = max(val, b_dfad);
00409   COMPARE_VALUES(c_dfad.val(), val);
00410   for (int i=0; i<n; i++)
00411     COMPARE_VALUES(c_dfad.dx(i), 0.0);
00412   
00413   val = b_dfad.val() - 1;
00414   c_dfad = max(val, b_dfad);
00415   COMPARE_VALUES(c_dfad.val(), b_dfad.val());
00416   for (int i=0; i<n; i++) {
00417     COMPARE_VALUES(c_dfad.dx(i), b_dfad.dx(i));
00418     COMPARE_VALUES(c_dfad.fastAccessDx(i), b_dfad.fastAccessDx(i));
00419   }
00420 }
00421 
00422 template <class FadType, class ScalarType>
00423 void FadOpsUnitTest<FadType,ScalarType>::
00424 testMin() {
00425   ScalarType val;
00426 
00427   FadType aa_dfad = a_dfad - 1.0;
00428   c_dfad = min(aa_dfad, a_dfad);
00429   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00430   for (int i=0; i<n; i++) {
00431     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00432     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00433   }
00434 
00435   c_dfad = min(a_dfad, aa_dfad);
00436   COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
00437   for (int i=0; i<n; i++) {
00438     COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
00439     COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
00440   }
00441 
00442   val = a_dfad.val() - 1;
00443   c_dfad = min(a_dfad, val);
00444   COMPARE_VALUES(c_dfad.val(), val);
00445   for (int i=0; i<n; i++)
00446     COMPARE_VALUES(c_dfad.dx(i), 0.0);
00447   
00448   val = a_dfad.val() + 1;
00449   c_dfad = min(a_dfad, val);
00450   COMPARE_VALUES(c_dfad.val(), a_dfad.val());
00451   for (int i=0; i<n; i++) {
00452     COMPARE_VALUES(c_dfad.dx(i), a_dfad.dx(i));
00453     COMPARE_VALUES(c_dfad.fastAccessDx(i), a_dfad.fastAccessDx(i));
00454   }
00455 
00456   val = b_dfad.val() - 1;
00457   c_dfad = min(val, b_dfad);
00458   COMPARE_VALUES(c_dfad.val(), val);
00459   for (int i=0; i<n; i++)
00460     COMPARE_VALUES(c_dfad.dx(i), 0.0);
00461   
00462   val = b_dfad.val() + 1;
00463   c_dfad = min(val, b_dfad);
00464   COMPARE_VALUES(c_dfad.val(), b_dfad.val());
00465   for (int i=0; i<n; i++) {
00466     COMPARE_VALUES(c_dfad.dx(i), b_dfad.dx(i));
00467     COMPARE_VALUES(c_dfad.fastAccessDx(i), b_dfad.fastAccessDx(i));
00468   }
00469 }
00470 
00471 #undef COMPARE_VALUES
00472 #undef COMPARE_FADS
00473 
00474 #endif // FADUNITTESTS_HPP

Generated on Wed May 12 21:39:32 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7