Sacado Package Browser (Single Doxygen Collection) Version of the Day
FadUnitTests2.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 FADUNITTESTS2_HPP
00033 #define FADUNITTESTS2_HPP
00034 
00035 // Sacado includes
00036 #include "Sacado.hpp"
00037 #include "Sacado_Random.hpp"
00038 
00039 // Cppunit includes
00040 #include <cppunit/extensions/HelperMacros.h>
00041 
00042 #define COMPARE_VALUES(a, b) \
00043   CPPUNIT_ASSERT( std::abs(a-b) < this->tol_a + this->tol_r*std::abs(a) );
00044 
00045 #define COMPARE_FADS(a, b)                              \
00046 CPPUNIT_ASSERT(a.size() == b.size());     \
00047 CPPUNIT_ASSERT(a.hasFastAccess() == b.hasFastAccess()); \
00048 COMPARE_VALUES(a.val(), b.val());     \
00049 for (int i=0; i<a.size(); i++) {      \
00050   COMPARE_VALUES(a.dx(i), b.dx(i));     \
00051   COMPARE_VALUES(a.fastAccessDx(i), b.fastAccessDx(i)); \
00052  }              \
00053  ;
00054 
00055 // A class for testing each Fad operation based on hand-coded derivatives.
00056 // Only those operations that are defined for both real and complex
00057 // types are tested here.  The others are tested below
00058 template <class FadType, class ScalarType>
00059 class FadOpsUnitTest2 : public CppUnit::TestFixture {
00060 
00061   CPPUNIT_TEST_SUITE( FadOpsUnitTest2 );
00062   
00063   CPPUNIT_TEST(testAddition);
00064   CPPUNIT_TEST(testSubtraction);
00065   CPPUNIT_TEST(testMultiplication);
00066   CPPUNIT_TEST(testDivision);
00067 
00068   CPPUNIT_TEST(testEquals);
00069   CPPUNIT_TEST(testNotEquals);
00070 
00071   CPPUNIT_TEST(testPow);
00072 
00073   CPPUNIT_TEST(testUnaryPlus);
00074   CPPUNIT_TEST(testUnaryMinus);
00075   
00076   CPPUNIT_TEST(testExp);
00077   CPPUNIT_TEST(testLog);
00078   CPPUNIT_TEST(testLog10);
00079   CPPUNIT_TEST(testSqrt);
00080   CPPUNIT_TEST(testCos);
00081   CPPUNIT_TEST(testSin);
00082   CPPUNIT_TEST(testTan);
00083   CPPUNIT_TEST(testCosh);
00084   CPPUNIT_TEST(testSinh);
00085   CPPUNIT_TEST(testTanh);
00086 
00087   CPPUNIT_TEST(testPlusEquals);
00088   CPPUNIT_TEST(testMinusEquals);
00089   CPPUNIT_TEST(testTimesEquals);
00090   CPPUNIT_TEST(testDivideEquals);
00091 
00092   CPPUNIT_TEST(testPlusLR);
00093   CPPUNIT_TEST(testMinusLR);
00094   CPPUNIT_TEST(testTimesLR);
00095   CPPUNIT_TEST(testDivideLR);
00096 
00097   CPPUNIT_TEST_SUITE_END();
00098 
00099 public:
00100 
00101   FadOpsUnitTest2();
00102 
00103   FadOpsUnitTest2(int numComponents, double absolute_tolerance, 
00104      double relative_tolerance);
00105 
00106   void setUp();
00107 
00108   void tearDown();
00109 
00110   void testAddition();
00111   void testSubtraction();
00112   void testMultiplication ();
00113   void testDivision();
00114 
00115   void testEquals();
00116   void testNotEquals();
00117 
00118   void testPow();
00119 
00120   void testUnaryPlus();
00121   void testUnaryMinus();
00122 
00123   void testExp();
00124   void testLog();
00125   void testLog10();
00126   void testSqrt();
00127   void testCos();
00128   void testSin();
00129   void testTan();
00130   void testCosh();
00131   void testSinh();
00132   void testTanh();
00133 
00134   void testPlusEquals();
00135   void testMinusEquals();
00136   void testTimesEquals();
00137   void testDivideEquals();
00138 
00139   void testPlusLR();
00140   void testMinusLR();
00141   void testTimesLR();
00142   void testDivideLR();
00143 
00144 protected:
00145 
00146   // DFad variables
00147   FadType a_fad, b_fad, c_fad;
00148 
00149   // Random number generator
00150   Sacado::Random<ScalarType> urand;
00151 
00152   // Number of derivative components
00153   int n;
00154 
00155   // Tolerances to which fad objects should be the same
00156   double tol_a, tol_r;
00157 
00158 }; // class FadOpsUnitTest2
00159 
00160 template <class FadType, class ScalarType>
00161 FadOpsUnitTest2<FadType,ScalarType>::
00162 FadOpsUnitTest2() :
00163   urand(), n(5), tol_a(1.0e-15), tol_r(1.0e-14) {}
00164 
00165 template <class FadType, class ScalarType>
00166 FadOpsUnitTest2<FadType,ScalarType>::
00167 FadOpsUnitTest2(int numComponents, double absolute_tolerance, 
00168          double relative_tolerance) :
00169   urand(), 
00170   n(numComponents), 
00171   tol_a(absolute_tolerance), 
00172   tol_r(relative_tolerance) {}
00173 
00174 template <class FadType, class ScalarType>
00175 void FadOpsUnitTest2<FadType,ScalarType>::setUp() {
00176   ScalarType val;
00177 
00178   val = urand.number();
00179   a_fad = FadType(n,val);
00180   
00181   val = urand.number();
00182   b_fad = FadType(n,val);
00183 
00184   for (int i=0; i<n; i++) {
00185     val = urand.number();
00186     a_fad.fastAccessDx(i) = val;
00187 
00188     val = urand.number();
00189     b_fad.fastAccessDx(i) = val;
00190   }
00191 }
00192 
00193 template <class FadType, class ScalarType>
00194 void FadOpsUnitTest2<FadType,ScalarType>::
00195 tearDown() {}
00196 
00197 template <class FadType, class ScalarType>
00198 void
00199 FadOpsUnitTest2<FadType,ScalarType>::
00200 testAddition() {
00201   c_fad = a_fad + b_fad;
00202   FadType t1(n, a_fad.val()+b_fad.val());
00203   for (int i=0; i<n; i++)
00204     t1.fastAccessDx(i) = a_fad.dx(i) + b_fad.dx(i);
00205   COMPARE_FADS(c_fad, t1);
00206   
00207   ScalarType val = urand.number();
00208   c_fad = a_fad + val;
00209   FadType t2(n, a_fad.val()+val);
00210   for (int i=0; i<n; i++)
00211     t2.fastAccessDx(i) = a_fad.dx(i);
00212   COMPARE_FADS(c_fad, t2);
00213 
00214   c_fad = val + b_fad;
00215   FadType t3(n, val+b_fad.val());
00216   for (int i=0; i<n; i++)
00217     t3.fastAccessDx(i) = b_fad.dx(i);
00218   COMPARE_FADS(c_fad, t3);
00219 }
00220 
00221 template <class FadType, class ScalarType>
00222 void
00223 FadOpsUnitTest2<FadType,ScalarType>::
00224 testSubtraction() {
00225   c_fad = a_fad - b_fad;
00226   FadType t1(n, a_fad.val()-b_fad.val());
00227   for (int i=0; i<n; i++)
00228     t1.fastAccessDx(i) = a_fad.dx(i) - b_fad.dx(i);
00229   COMPARE_FADS(c_fad, t1);
00230 
00231   ScalarType val = urand.number();
00232   c_fad = a_fad - val;
00233   FadType t2(n, a_fad.val()-val);
00234   for (int i=0; i<n; i++)
00235     t2.fastAccessDx(i) = a_fad.dx(i);
00236   COMPARE_FADS(c_fad, t2);
00237 
00238   c_fad = val - b_fad;
00239   FadType t3(n, val-b_fad.val());
00240   for (int i=0; i<n; i++)
00241     t3.fastAccessDx(i) = -b_fad.dx(i);
00242   COMPARE_FADS(c_fad, t3);
00243 }
00244 
00245 template <class FadType, class ScalarType>
00246 void
00247 FadOpsUnitTest2<FadType,ScalarType>::
00248 testMultiplication() {
00249   c_fad = a_fad * b_fad;
00250   FadType t1(n, a_fad.val()*b_fad.val());
00251   for (int i=0; i<n; i++)
00252     t1.fastAccessDx(i) = a_fad.dx(i)*b_fad.val() + a_fad.val()*b_fad.dx(i);
00253   COMPARE_FADS(c_fad, t1);
00254 
00255   ScalarType val = urand.number();
00256   c_fad = a_fad * val;
00257   FadType t2(n, a_fad.val()*val);
00258   for (int i=0; i<n; i++)
00259     t2.fastAccessDx(i) = a_fad.dx(i)*val;
00260   COMPARE_FADS(c_fad, t2);
00261 
00262   c_fad = val * b_fad;
00263   FadType t3(n, val*b_fad.val());
00264   for (int i=0; i<n; i++)
00265     t3.fastAccessDx(i) = val*b_fad.dx(i);
00266   COMPARE_FADS(c_fad, t3);
00267 }
00268 
00269 template <class FadType, class ScalarType>
00270 void
00271 FadOpsUnitTest2<FadType,ScalarType>::
00272 testDivision() {
00273   c_fad = a_fad / b_fad;
00274   FadType t1(n, a_fad.val()/b_fad.val());
00275   for (int i=0; i<n; i++)
00276     t1.fastAccessDx(i) = 
00277       (a_fad.dx(i)*b_fad.val() - a_fad.val()*b_fad.dx(i)) / 
00278       (b_fad.val()*b_fad.val());
00279   COMPARE_FADS(c_fad, t1);
00280 
00281   ScalarType val = urand.number();
00282   c_fad = a_fad / val;
00283   FadType t2(n, a_fad.val()/val);
00284   for (int i=0; i<n; i++)
00285     t2.fastAccessDx(i) = a_fad.dx(i)/val;
00286   COMPARE_FADS(c_fad, t2);
00287 
00288   c_fad = val / b_fad;
00289   FadType t3(n, val/b_fad.val());
00290   for (int i=0; i<n; i++)
00291     t3.fastAccessDx(i) = -val*b_fad.dx(i)/(b_fad.val()*b_fad.val());
00292   COMPARE_FADS(c_fad, t3);
00293 }
00294 
00295 template <class FadType, class ScalarType>
00296 void
00297 FadOpsUnitTest2<FadType,ScalarType>::
00298 testEquals() {
00299   bool r1 = a_fad == b_fad;
00300   bool r2 = a_fad.val() == b_fad.val();
00301   CPPUNIT_ASSERT(r1 == r2);
00302 
00303   ScalarType val = urand.number();
00304   r1 = a_fad == val;
00305   r2 = a_fad.val() == val;
00306   CPPUNIT_ASSERT(r1 == r2);
00307 
00308   r1 = val == b_fad;
00309   r2 = val == b_fad.val();
00310   CPPUNIT_ASSERT(r1 == r2);
00311 }
00312 
00313 template <class FadType, class ScalarType>
00314 void
00315 FadOpsUnitTest2<FadType,ScalarType>::
00316 testNotEquals() {
00317   bool r1 = a_fad != b_fad;
00318   bool r2 = a_fad.val() != b_fad.val();
00319   CPPUNIT_ASSERT(r1 == r2);
00320 
00321   ScalarType val = urand.number();
00322   r1 = a_fad != val;
00323   r2 = a_fad.val() != val;
00324   CPPUNIT_ASSERT(r1 == r2);
00325 
00326   r1 = val != b_fad;
00327   r2 = val != b_fad.val();
00328   CPPUNIT_ASSERT(r1 == r2);
00329 }
00330 
00331 template <class FadType, class ScalarType>
00332 void
00333 FadOpsUnitTest2<FadType,ScalarType>::
00334 testUnaryPlus() {
00335   c_fad = +(a_fad);
00336   FadType t1(n, a_fad.val());
00337   for (int i=0; i<n; i++)
00338     t1.fastAccessDx(i) = a_fad.dx(i);
00339   COMPARE_FADS(c_fad, t1);
00340 }
00341 
00342 template <class FadType, class ScalarType>
00343 void
00344 FadOpsUnitTest2<FadType,ScalarType>::
00345 testUnaryMinus() {
00346   c_fad = -(a_fad);
00347   FadType t1(n, -a_fad.val());
00348   for (int i=0; i<n; i++)
00349     t1.fastAccessDx(i) = -a_fad.dx(i);
00350   COMPARE_FADS(c_fad, t1);
00351 }
00352 
00353 template <class FadType, class ScalarType>
00354 void
00355 FadOpsUnitTest2<FadType,ScalarType>::
00356 testExp() {
00357   c_fad = std::exp(a_fad);
00358   FadType t1(n, std::exp(a_fad.val()));
00359   for (int i=0; i<n; i++)
00360     t1.fastAccessDx(i) = std::exp(a_fad.val())*a_fad.dx(i);
00361   COMPARE_FADS(c_fad, t1);
00362 }
00363 
00364 template <class FadType, class ScalarType>
00365 void
00366 FadOpsUnitTest2<FadType,ScalarType>::
00367 testLog() {
00368   c_fad = std::log(a_fad);
00369   FadType t1(n, std::log(a_fad.val()));
00370   for (int i=0; i<n; i++)
00371     t1.fastAccessDx(i) = a_fad.dx(i)/a_fad.val();
00372   COMPARE_FADS(c_fad, t1);
00373 }
00374 
00375 template <class FadType, class ScalarType>
00376 void
00377 FadOpsUnitTest2<FadType,ScalarType>::
00378 testLog10() {
00379   c_fad = std::log10(a_fad);
00380   FadType t1(n, std::log10(a_fad.val()));
00381   for (int i=0; i<n; i++)
00382     t1.fastAccessDx(i) = a_fad.dx(i)/(a_fad.val()*std::log(10));
00383   COMPARE_FADS(c_fad, t1);
00384 }
00385 
00386 template <class FadType, class ScalarType>
00387 void
00388 FadOpsUnitTest2<FadType,ScalarType>::
00389 testSqrt() {
00390   c_fad = std::sqrt(a_fad);
00391   FadType t1(n, std::sqrt(a_fad.val()));
00392   for (int i=0; i<n; i++)
00393     t1.fastAccessDx(i) = a_fad.dx(i)/(2.*std::sqrt(a_fad.val()));
00394   COMPARE_FADS(c_fad, t1);
00395 }
00396 
00397 template <class FadType, class ScalarType>
00398 void
00399 FadOpsUnitTest2<FadType,ScalarType>::
00400 testCos() {
00401   c_fad = std::cos(a_fad);
00402   FadType t1(n, std::cos(a_fad.val()));
00403   for (int i=0; i<n; i++)
00404     t1.fastAccessDx(i) = -std::sin(a_fad.val())*a_fad.dx(i);
00405   COMPARE_FADS(c_fad, t1);
00406 }
00407 
00408 template <class FadType, class ScalarType>
00409 void
00410 FadOpsUnitTest2<FadType,ScalarType>::
00411 testSin() {
00412   c_fad = std::sin(a_fad);
00413   FadType t1(n, std::sin(a_fad.val()));
00414   for (int i=0; i<n; i++)
00415     t1.fastAccessDx(i) = std::cos(a_fad.val())*a_fad.dx(i);
00416   COMPARE_FADS(c_fad, t1);
00417 }
00418 
00419 template <class FadType, class ScalarType>
00420 void
00421 FadOpsUnitTest2<FadType,ScalarType>::
00422 testTan() {
00423   c_fad = std::tan(a_fad);
00424   FadType t1(n, std::tan(a_fad.val()));
00425   for (int i=0; i<n; i++)
00426     t1.fastAccessDx(i) = 
00427       a_fad.dx(i)/(std::cos(a_fad.val())*std::cos(a_fad.val()));;
00428   COMPARE_FADS(c_fad, t1);
00429 }
00430 
00431 template <class FadType, class ScalarType>
00432 void
00433 FadOpsUnitTest2<FadType,ScalarType>::
00434 testCosh() {
00435   c_fad = std::cosh(a_fad);
00436   FadType t1(n, std::cosh(a_fad.val()));
00437   for (int i=0; i<n; i++)
00438     t1.fastAccessDx(i) = std::sinh(a_fad.val())*a_fad.dx(i);
00439   COMPARE_FADS(c_fad, t1);
00440 }
00441 
00442 template <class FadType, class ScalarType>
00443 void
00444 FadOpsUnitTest2<FadType,ScalarType>::
00445 testSinh() {
00446   c_fad = std::sinh(a_fad);
00447   FadType t1(n, std::sinh(a_fad.val()));
00448   for (int i=0; i<n; i++)
00449     t1.fastAccessDx(i) = std::cosh(a_fad.val())*a_fad.dx(i);
00450   COMPARE_FADS(c_fad, t1);
00451 }
00452 
00453 template <class FadType, class ScalarType>
00454 void
00455 FadOpsUnitTest2<FadType,ScalarType>::
00456 testTanh() {
00457   c_fad = std::tanh(a_fad);
00458   FadType t1(n, std::tanh(a_fad.val()));
00459   for (int i=0; i<n; i++)
00460     t1.fastAccessDx(i) = 
00461       a_fad.dx(i)/(std::cosh(a_fad.val())*std::cosh(a_fad.val()));
00462   COMPARE_FADS(c_fad, t1);
00463 }
00464 
00465 template <class FadType, class ScalarType>
00466 void
00467 FadOpsUnitTest2<FadType,ScalarType>::
00468 testPlusEquals() {
00469   FadType t1(n, c_fad.val()+a_fad.val());
00470   for (int i=0; i<n; i++)
00471     t1.fastAccessDx(i) = c_fad.dx(i) + a_fad.dx(i);
00472   c_fad += a_fad;
00473   COMPARE_FADS(c_fad, t1);
00474   
00475   ScalarType val = urand.number();
00476   FadType t2(n, c_fad.val()+val);
00477   for (int i=0; i<n; i++)
00478     t2.fastAccessDx(i) = c_fad.dx(i);
00479   c_fad += val;
00480   COMPARE_FADS(c_fad, t2);
00481 }
00482 
00483 template <class FadType, class ScalarType>
00484 void
00485 FadOpsUnitTest2<FadType,ScalarType>::
00486 testMinusEquals() {
00487   FadType t1(n, c_fad.val()-a_fad.val());
00488   for (int i=0; i<n; i++)
00489     t1.fastAccessDx(i) = c_fad.dx(i) - a_fad.dx(i);
00490   c_fad -= a_fad;
00491   COMPARE_FADS(c_fad, t1);
00492   
00493   ScalarType val = urand.number();
00494   FadType t2(n, c_fad.val()-val);
00495   for (int i=0; i<n; i++)
00496     t2.fastAccessDx(i) = c_fad.dx(i);
00497   c_fad -= val;
00498   COMPARE_FADS(c_fad, t2);
00499 }
00500 
00501 template <class FadType, class ScalarType>
00502 void
00503 FadOpsUnitTest2<FadType,ScalarType>::
00504 testTimesEquals() {
00505   FadType t1(n, c_fad.val()*a_fad.val());
00506   for (int i=0; i<n; i++)
00507     t1.fastAccessDx(i) = c_fad.dx(i)*a_fad.val() + a_fad.dx(i)*c_fad.val();
00508   c_fad *= a_fad;
00509   COMPARE_FADS(c_fad, t1);
00510   
00511   ScalarType val = urand.number();
00512   FadType t2(n, c_fad.val()*val);
00513   for (int i=0; i<n; i++)
00514     t2.fastAccessDx(i) = c_fad.dx(i)*val;
00515   c_fad *= val;
00516   COMPARE_FADS(c_fad, t2);
00517 }
00518 
00519 template <class FadType, class ScalarType>
00520 void
00521 FadOpsUnitTest2<FadType,ScalarType>::
00522 testDivideEquals() {
00523   FadType t1(n, c_fad.val()/a_fad.val());
00524   for (int i=0; i<n; i++)
00525     t1.fastAccessDx(i) = 
00526       (a_fad.dx(i)*c_fad.val() - c_fad.dx(i)*a_fad.val()) /
00527       (a_fad.val()*a_fad.val());
00528   c_fad /= a_fad;
00529   COMPARE_FADS(c_fad, t1);
00530   
00531   ScalarType val = urand.number();
00532   FadType t2(n, c_fad.val()/val);
00533   for (int i=0; i<n; i++)
00534     t2.fastAccessDx(i) = c_fad.dx(i)/val;
00535   c_fad /= val;
00536   COMPARE_FADS(c_fad, t2);
00537 }
00538 
00539 template <class FadType, class ScalarType>
00540 void
00541 FadOpsUnitTest2<FadType,ScalarType>::
00542 testPow() {
00543   c_fad = std::pow(a_fad, b_fad);
00544   FadType t1(n, std::pow(a_fad.val(),b_fad.val()));
00545   for (int i=0; i<n; i++)
00546     t1.fastAccessDx(i) = 
00547       std::pow(a_fad.val(),b_fad.val())*(b_fad.val()*a_fad.dx(i)/a_fad.val() + 
00548            std::log(a_fad.val())*b_fad.dx(i));
00549   COMPARE_FADS(c_fad, t1);
00550   
00551   ScalarType val = urand.number();
00552   c_fad = std::pow(a_fad, val);
00553   FadType t2(n, std::pow(a_fad.val(), val));
00554   for (int i=0; i<n; i++)
00555     t2.fastAccessDx(i) = 
00556       std::pow(a_fad.val(), val)*(val*a_fad.dx(i)/a_fad.val());
00557   COMPARE_FADS(c_fad, t2);
00558 
00559   c_fad = std::pow(val, b_fad);
00560   FadType t3(n, std::pow(val, b_fad.val()));
00561   for (int i=0; i<n; i++)
00562     t3.fastAccessDx(i) = 
00563       std::pow(val, b_fad.val())*std::log(val)*b_fad.dx(i);
00564   COMPARE_FADS(c_fad, t3);
00565 
00566   val = 0.0;
00567   c_fad = std::pow(a_fad, val);
00568   FadType t4(n, std::pow(a_fad.val(), val));
00569   for (int i=0; i<n; i++)
00570     t4.fastAccessDx(i) = 0.0;
00571   COMPARE_FADS(c_fad, t4);
00572 
00573   c_fad = std::pow(val, b_fad);
00574   FadType t5(n, std::pow(val, b_fad.val()));
00575   for (int i=0; i<n; i++)
00576     t5.fastAccessDx(i) = 0.0;
00577   COMPARE_FADS(c_fad, t5);
00578 
00579   FadType aa_fad = a_fad;
00580   aa_fad.val() = 0.0;
00581   c_fad = std::pow(aa_fad, b_fad);
00582   FadType t6(n, std::pow(aa_fad.val(),b_fad.val()));
00583   for (int i=0; i<n; i++)
00584     t6.fastAccessDx(i) = 0.0;
00585   COMPARE_FADS(c_fad, t6);
00586 
00587   FadType bb_fad = b_fad;
00588   bb_fad.val() = 0.0;
00589   c_fad = std::pow(a_fad, bb_fad);
00590   FadType t7(n, std::pow(a_fad.val(),bb_fad.val()));
00591   for (int i=0; i<n; i++)
00592     t7.fastAccessDx(i) = 
00593       std::pow(a_fad.val(),bb_fad.val())*(bb_fad.val()*a_fad.dx(i)/a_fad.val() 
00594             + std::log(a_fad.val())*b_fad.dx(i));
00595   COMPARE_FADS(c_fad, t7);
00596 }
00597 
00598 template <class FadType, class ScalarType>
00599 void 
00600 FadOpsUnitTest2<FadType,ScalarType>::
00601 testPlusLR() {
00602   FadType aa_fad = a_fad;
00603   aa_fad = 1.0;
00604   aa_fad = aa_fad + b_fad;
00605   c_fad = 1.0 + b_fad;
00606   COMPARE_FADS(aa_fad, c_fad);
00607 }
00608 
00609 template <class FadType, class ScalarType>
00610 void 
00611 FadOpsUnitTest2<FadType,ScalarType>::
00612 testMinusLR() {
00613   FadType aa_fad = a_fad;
00614   aa_fad = 1.0;
00615   aa_fad = aa_fad - b_fad;
00616   c_fad = 1.0 - b_fad;
00617   COMPARE_FADS(aa_fad, c_fad);
00618 }
00619 
00620 template <class FadType, class ScalarType>
00621 void 
00622 FadOpsUnitTest2<FadType,ScalarType>::
00623 testTimesLR() {
00624   FadType aa_fad = a_fad;
00625   aa_fad = 2.0;
00626   aa_fad = aa_fad * b_fad;
00627   c_fad = 2.0 * b_fad;
00628   COMPARE_FADS(aa_fad, c_fad);
00629 }
00630 
00631 template <class FadType, class ScalarType>
00632 void 
00633 FadOpsUnitTest2<FadType,ScalarType>::
00634 testDivideLR() {
00635   FadType aa_fad = a_fad;
00636   aa_fad = 2.0;
00637   aa_fad = aa_fad / b_fad;
00638   c_fad = 2.0 / b_fad;
00639   COMPARE_FADS(aa_fad, c_fad);
00640 }
00641 
00642 // A class for testing each real Fad operation
00643 // This class tests additional functions that aren't define for complex
00644 // types
00645 template <class FadType, class ScalarType>
00646 class RealFadOpsUnitTest2 : public FadOpsUnitTest2<FadType,ScalarType> {
00647 
00648   CPPUNIT_TEST_SUITE( RealFadOpsUnitTest2 );
00649   
00650   CPPUNIT_TEST(testAddition);
00651   CPPUNIT_TEST(testSubtraction);
00652   CPPUNIT_TEST(testMultiplication);
00653   CPPUNIT_TEST(testDivision);
00654 
00655   CPPUNIT_TEST(testEquals);
00656   CPPUNIT_TEST(testNotEquals);
00657   CPPUNIT_TEST(testLessThanOrEquals);
00658   CPPUNIT_TEST(testGreaterThanOrEquals);
00659   CPPUNIT_TEST(testLessThan);
00660   CPPUNIT_TEST(testGreaterThan);
00661 
00662   CPPUNIT_TEST(testPow);
00663   CPPUNIT_TEST(testATan2);
00664   CPPUNIT_TEST(testMax);
00665   CPPUNIT_TEST(testMin);
00666 
00667   CPPUNIT_TEST(testUnaryPlus);
00668   CPPUNIT_TEST(testUnaryMinus);
00669   
00670   CPPUNIT_TEST(testExp);
00671   CPPUNIT_TEST(testLog);
00672   CPPUNIT_TEST(testLog10);
00673   CPPUNIT_TEST(testSqrt);
00674   CPPUNIT_TEST(testCos);
00675   CPPUNIT_TEST(testSin);
00676   CPPUNIT_TEST(testTan);
00677   CPPUNIT_TEST(testACos);
00678   CPPUNIT_TEST(testASin);
00679   CPPUNIT_TEST(testATan);
00680   CPPUNIT_TEST(testCosh);
00681   CPPUNIT_TEST(testSinh);
00682   CPPUNIT_TEST(testTanh);
00683   CPPUNIT_TEST(testACosh);
00684   CPPUNIT_TEST(testASinh);
00685   CPPUNIT_TEST(testATanh);
00686   CPPUNIT_TEST(testAbs);
00687   CPPUNIT_TEST(testFAbs);
00688 
00689   CPPUNIT_TEST(testPlusEquals);
00690   CPPUNIT_TEST(testMinusEquals);
00691   CPPUNIT_TEST(testTimesEquals);
00692   CPPUNIT_TEST(testDivideEquals);
00693 
00694   CPPUNIT_TEST(testPlusLR);
00695   CPPUNIT_TEST(testMinusLR);
00696   CPPUNIT_TEST(testTimesLR);
00697   CPPUNIT_TEST(testDivideLR);
00698 
00699   CPPUNIT_TEST_SUITE_END();
00700 
00701 public:
00702 
00703   RealFadOpsUnitTest2() {}
00704 
00705   RealFadOpsUnitTest2(int numComponents, double absolute_tolerance, 
00706           double relative_tolerance) :
00707     FadOpsUnitTest2<FadType,ScalarType>(numComponents, absolute_tolerance, relative_tolerance) {}
00708 
00709   void testLessThanOrEquals();
00710   void testGreaterThanOrEquals();
00711   void testLessThan();
00712   void testGreaterThan();
00713 
00714   void testACos();
00715   void testASin();
00716   void testATan();
00717   void testACosh();
00718   void testASinh();
00719   void testATanh();
00720   void testAbs();
00721   void testFAbs();
00722 
00723   void testATan2();
00724   void testMax();
00725   void testMin();
00726 };
00727 
00728 template <class FadType, class ScalarType>
00729 void
00730 RealFadOpsUnitTest2<FadType,ScalarType>::
00731 testLessThanOrEquals() {
00732   bool r1 = this->a_fad <= this->b_fad;
00733   bool r2 = this->a_fad.val() <= this->b_fad.val();
00734   CPPUNIT_ASSERT(r1 == r2);
00735 
00736   ScalarType val = this->urand.number();
00737   r1 = this->a_fad <= val;
00738   r2 = this->a_fad.val() <= val;
00739   CPPUNIT_ASSERT(r1 == r2);
00740 
00741   r1 = val <= this->b_fad;
00742   r2 = val <= this->b_fad.val();
00743   CPPUNIT_ASSERT(r1 == r2);
00744 }
00745 
00746 template <class FadType, class ScalarType>
00747 void
00748 RealFadOpsUnitTest2<FadType,ScalarType>::
00749 testGreaterThanOrEquals() {
00750   bool r1 = this->a_fad >= this->b_fad;
00751   bool r2 = this->a_fad.val() >= this->b_fad.val();
00752   CPPUNIT_ASSERT(r1 == r2);
00753 
00754   ScalarType val = this->urand.number();
00755   r1 = this->a_fad >= val;
00756   r2 = this->a_fad.val() >= val;
00757   CPPUNIT_ASSERT(r1 == r2);
00758 
00759   r1 = val >= this->b_fad;
00760   r2 = val >= this->b_fad.val();
00761   CPPUNIT_ASSERT(r1 == r2);
00762 }
00763 
00764 template <class FadType, class ScalarType>
00765 void
00766 RealFadOpsUnitTest2<FadType,ScalarType>::
00767 testLessThan() {
00768   bool r1 = this->a_fad < this->b_fad;
00769   bool r2 = this->a_fad.val() < this->b_fad.val();
00770   CPPUNIT_ASSERT(r1 == r2);
00771 
00772   ScalarType val = this->urand.number();
00773   r1 = this->a_fad < val;
00774   r2 = this->a_fad.val() < val;
00775   CPPUNIT_ASSERT(r1 == r2);
00776 
00777   r1 = val < this->b_fad;
00778   r2 = val < this->b_fad.val();
00779   CPPUNIT_ASSERT(r1 == r2);
00780 }
00781 
00782 template <class FadType, class ScalarType>
00783 void
00784 RealFadOpsUnitTest2<FadType,ScalarType>::
00785 testGreaterThan() {
00786   bool r1 = this->a_fad > this->b_fad;
00787   bool r2 = this->a_fad.val() > this->b_fad.val();
00788   CPPUNIT_ASSERT(r1 == r2);
00789 
00790   ScalarType val = this->urand.number();
00791   r1 = this->a_fad > val;
00792   r2 = this->a_fad.val() > val;
00793   CPPUNIT_ASSERT(r1 == r2);
00794 
00795   r1 = val > this->b_fad;
00796   r2 = val > this->b_fad.val();
00797   CPPUNIT_ASSERT(r1 == r2);
00798 }
00799 
00800 template <class FadType, class ScalarType>
00801 void
00802 RealFadOpsUnitTest2<FadType,ScalarType>::
00803 testACos() {
00804   this->c_fad = std::acos(this->a_fad);
00805   FadType t1(this->n, std::acos(this->a_fad.val()));
00806   for (int i=0; i<this->n; i++)
00807     t1.fastAccessDx(i) = -this->a_fad.dx(i)/std::sqrt(1.0 - this->a_fad.val()*this->a_fad.val());
00808   COMPARE_FADS(this->c_fad, t1);
00809 }
00810 
00811 template <class FadType, class ScalarType>
00812 void
00813 RealFadOpsUnitTest2<FadType,ScalarType>::
00814 testASin() {
00815   this->c_fad = std::asin(this->a_fad);
00816   FadType t1(this->n, std::asin(this->a_fad.val()));
00817   for (int i=0; i<this->n; i++)
00818     t1.fastAccessDx(i) = this->a_fad.dx(i)/std::sqrt(1.0 - this->a_fad.val()*this->a_fad.val());
00819   COMPARE_FADS(this->c_fad, t1);
00820 }
00821 
00822 template <class FadType, class ScalarType>
00823 void
00824 RealFadOpsUnitTest2<FadType,ScalarType>::
00825 testATan() {
00826   this->c_fad = std::atan(this->a_fad);
00827   FadType t1(this->n, std::atan(this->a_fad.val()));
00828   for (int i=0; i<this->n; i++)
00829     t1.fastAccessDx(i) = this->a_fad.dx(i)/(1.0 + this->a_fad.val()*this->a_fad.val());
00830   COMPARE_FADS(this->c_fad, t1);
00831 }
00832 
00833 template <class FadType, class ScalarType>
00834 void
00835 RealFadOpsUnitTest2<FadType,ScalarType>::
00836 testACosh() {
00837   FadType aa_fad = this->a_fad;
00838   if (this->a_fad.val() < 1.0)
00839     aa_fad.val() = 1.0 / this->a_fad.val();
00840   this->c_fad = std::acosh(aa_fad);
00841   FadType t1(this->n, std::acosh(aa_fad.val()));
00842   for (int i=0; i<this->n; i++)
00843     t1.fastAccessDx(i) = aa_fad.dx(i)/std::sqrt(aa_fad.val()*aa_fad.val()-1.0);
00844   COMPARE_FADS(this->c_fad, t1);
00845 }
00846 
00847 template <class FadType, class ScalarType>
00848 void
00849 RealFadOpsUnitTest2<FadType,ScalarType>::
00850 testASinh() {
00851   this->c_fad = std::asinh(this->a_fad);
00852   FadType t1(this->n, std::asinh(this->a_fad.val()));
00853   for (int i=0; i<this->n; i++)
00854     t1.fastAccessDx(i) = this->a_fad.dx(i)/std::sqrt(this->a_fad.val()*this->a_fad.val()+1.0);
00855   COMPARE_FADS(this->c_fad, t1);
00856 }
00857 
00858 template <class FadType, class ScalarType>
00859 void
00860 RealFadOpsUnitTest2<FadType,ScalarType>::
00861 testATanh() {
00862   this->c_fad = std::atanh(this->a_fad);
00863   FadType t1(this->n, std::atanh(this->a_fad.val()));
00864   for (int i=0; i<this->n; i++)
00865     t1.fastAccessDx(i) = this->a_fad.dx(i)/(1.0 - this->a_fad.val()*this->a_fad.val());
00866   COMPARE_FADS(this->c_fad, t1);
00867 }
00868 
00869 template <class FadType, class ScalarType>
00870 void
00871 RealFadOpsUnitTest2<FadType,ScalarType>::
00872 testAbs() {
00873   this->c_fad = std::abs(this->a_fad);
00874   FadType t1(this->n, std::abs(this->a_fad.val()));
00875   for (int i=0; i<this->n; i++) {
00876     if (this->a_fad.val() >= 0)
00877       t1.fastAccessDx(i) = this->a_fad.dx(i);
00878     else
00879       t1.fastAccessDx(i) = -this->a_fad.dx(i);
00880   }
00881   COMPARE_FADS(this->c_fad, t1);
00882 }
00883 
00884 template <class FadType, class ScalarType>
00885 void
00886 RealFadOpsUnitTest2<FadType,ScalarType>::
00887 testFAbs() {
00888   this->c_fad = std::fabs(this->a_fad);
00889   FadType t1(this->n, std::fabs(this->a_fad.val()));
00890   for (int i=0; i<this->n; i++) {
00891     if (this->a_fad.val() >= 0)
00892       t1.fastAccessDx(i) = this->a_fad.dx(i);
00893     else
00894       t1.fastAccessDx(i) = -this->a_fad.dx(i);
00895   }
00896   COMPARE_FADS(this->c_fad, t1);
00897 }
00898 
00899 template <class FadType, class ScalarType>
00900 void
00901 RealFadOpsUnitTest2<FadType,ScalarType>::
00902 testATan2() {
00903   this->c_fad = std::atan2(this->a_fad, this->b_fad);
00904   FadType t1(this->n, std::atan2(this->a_fad.val(),this->b_fad.val()));
00905   ScalarType t = this->a_fad.val()*this->a_fad.val() + 
00906     this->b_fad.val()*this->b_fad.val();
00907   for (int i=0; i<this->n; i++)
00908     t1.fastAccessDx(i) = (this->b_fad.val()*this->a_fad.dx(i) - 
00909         this->a_fad.val()*this->b_fad.dx(i))/t; 
00910   COMPARE_FADS(this->c_fad, t1);
00911   
00912   ScalarType val = this->urand.number();
00913   this->c_fad = std::atan2(this->a_fad, val);
00914   FadType t2(this->n, std::atan2(this->a_fad.val(), val));
00915   t = this->a_fad.val()*this->a_fad.val() + val*val;
00916   for (int i=0; i<this->n; i++)
00917     t2.fastAccessDx(i) = val*this->a_fad.dx(i)/t;
00918   COMPARE_FADS(this->c_fad, t2);
00919 
00920   this->c_fad = std::atan2(val, this->b_fad);
00921   FadType t3(this->n, std::atan2(val, this->b_fad.val()));
00922   t = val*val + this->b_fad.val()*this->b_fad.val();
00923   for (int i=0; i<this->n; i++)
00924     t3.fastAccessDx(i) = -val*this->b_fad.dx(i)/t;
00925   COMPARE_FADS(this->c_fad, t3);
00926 }
00927 
00928 template <class FadType, class ScalarType>
00929 void 
00930 RealFadOpsUnitTest2<FadType,ScalarType>::
00931 testMax() {
00932   ScalarType val;
00933 
00934   // Fad, Fad
00935   FadType aa_fad = this->a_fad + 1.0;
00936   this->c_fad = max(aa_fad, this->a_fad);
00937   COMPARE_FADS(this->c_fad, aa_fad);
00938   this->c_fad = max(this->a_fad, aa_fad);
00939   COMPARE_FADS(this->c_fad, aa_fad);
00940 
00941   // Expr, Fad
00942   this->c_fad = max(this->a_fad+1.0, this->a_fad);
00943   COMPARE_FADS(this->c_fad, aa_fad);
00944   this->c_fad = max(this->a_fad, this->a_fad+1.0);
00945   COMPARE_FADS(this->c_fad, aa_fad);
00946 
00947   // Expr, Expr (same)
00948   this->c_fad = max(this->a_fad+1.0, this->a_fad+1.0);
00949   COMPARE_FADS(this->c_fad, aa_fad);
00950 
00951   // Expr, Expr (different)
00952   this->c_fad = max(this->a_fad+1.0, this->a_fad-1.0);
00953   COMPARE_FADS(this->c_fad, aa_fad);
00954   this->c_fad = max(this->a_fad-1.0, this->a_fad+1.0);
00955   COMPARE_FADS(this->c_fad, aa_fad);
00956   
00957   // Fad, const
00958   val = this->a_fad.val() + 1;
00959   this->c_fad = max(this->a_fad, val);
00960   COMPARE_VALUES(this->c_fad.val(), val);
00961   for (int i=0; i<this->n; i++)
00962     COMPARE_VALUES(this->c_fad.dx(i), 0.0);
00963   val = this->a_fad.val() - 1;
00964   this->c_fad = max(this->a_fad, val);
00965   COMPARE_FADS(this->c_fad, this->a_fad);
00966   val = this->b_fad.val() + 1;
00967   this->c_fad = max(val, this->b_fad);
00968   COMPARE_VALUES(this->c_fad.val(), val);
00969   for (int i=0; i<this->n; i++)
00970     COMPARE_VALUES(this->c_fad.dx(i), 0.0);
00971   val = this->b_fad.val() - 1;
00972   this->c_fad = max(val, this->b_fad);
00973   COMPARE_FADS(this->c_fad, this->b_fad);
00974 
00975   // Expr, const
00976   val = this->a_fad.val();
00977   this->c_fad = max(this->a_fad+1.0, val);
00978   COMPARE_FADS(this->c_fad, aa_fad);
00979   this->c_fad = max(val, this->a_fad+1.0);
00980   COMPARE_FADS(this->c_fad, aa_fad);
00981 }
00982 
00983 template <class FadType, class ScalarType>
00984 void 
00985 RealFadOpsUnitTest2<FadType,ScalarType>::
00986 testMin() {
00987   ScalarType val;
00988 
00989   // Fad, Fad
00990   FadType aa_fad = this->a_fad - 1.0;
00991   this->c_fad = min(aa_fad, this->a_fad);
00992   COMPARE_FADS(this->c_fad, aa_fad);
00993   this->c_fad = min(this->a_fad, aa_fad);
00994   COMPARE_FADS(this->c_fad, aa_fad);
00995 
00996   // Expr, Fad
00997   this->c_fad = min(this->a_fad-1.0, this->a_fad);
00998   COMPARE_FADS(this->c_fad, aa_fad);
00999   this->c_fad = min(this->a_fad, this->a_fad-1.0);
01000   COMPARE_FADS(this->c_fad, aa_fad);
01001 
01002   // Expr, Expr (same)
01003   this->c_fad = min(this->a_fad-1.0, this->a_fad-1.0);
01004   COMPARE_FADS(this->c_fad, aa_fad);
01005 
01006   // Expr, Expr (different)
01007   this->c_fad = min(this->a_fad+1.0, this->a_fad-1.0);
01008   COMPARE_FADS(this->c_fad, aa_fad);
01009   this->c_fad = min(this->a_fad-1.0, this->a_fad+1.0);
01010   COMPARE_FADS(this->c_fad, aa_fad);
01011 
01012   // Fad, const
01013   val = this->a_fad.val() - 1;
01014   this->c_fad = min(this->a_fad, val);
01015   COMPARE_VALUES(this->c_fad.val(), val);
01016   for (int i=0; i<this->n; i++)
01017     COMPARE_VALUES(this->c_fad.dx(i), 0.0);
01018   val = this->a_fad.val() + 1;
01019   this->c_fad = min(this->a_fad, val);
01020   COMPARE_FADS(this->c_fad, this->a_fad);
01021   val = this->b_fad.val() - 1;
01022   this->c_fad = min(val, this->b_fad);
01023   COMPARE_VALUES(this->c_fad.val(), val);
01024   for (int i=0; i<this->n; i++)
01025     COMPARE_VALUES(this->c_fad.dx(i), 0.0);
01026   val = this->b_fad.val() + 1;
01027   this->c_fad = min(val, this->b_fad);
01028   COMPARE_FADS(this->c_fad, this->b_fad);
01029 
01030   // Expr, const
01031   val = this->a_fad.val();
01032   this->c_fad = min(this->a_fad-1.0, val);
01033   COMPARE_FADS(this->c_fad, aa_fad);
01034   this->c_fad = min(val, this->a_fad-1.0);
01035   COMPARE_FADS(this->c_fad, aa_fad);
01036 }
01037 
01038 #undef COMPARE_VALUES
01039 #undef COMPARE_FADS
01040 
01041 #endif // FADUNITTESTS2_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines