Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FadUnitTests.hpp
Go to the documentation of this file.
1 // $Id$
2 // $Source$
3 // @HEADER
4 // ***********************************************************************
5 //
6 // Sacado Package
7 // Copyright (2006) Sandia Corporation
8 //
9 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
10 // the U.S. Government retains certain rights in this software.
11 //
12 // This library is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU Lesser General Public License as
14 // published by the Free Software Foundation; either version 2.1 of the
15 // License, or (at your option) any later version.
16 //
17 // This library is distributed in the hope that it will be useful, but
18 // WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License along with this library; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
25 // USA
26 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
27 // (etphipp@sandia.gov).
28 //
29 // ***********************************************************************
30 // @HEADER
31 
32 #ifndef FADUNITTESTS_HPP
33 #define FADUNITTESTS_HPP
34 
35 // Sacado includes
36 #include "Sacado_No_Kokkos.hpp"
37 #include "Sacado_Random.hpp"
38 
39 // Fad includes
40 #include "Fad/fad.h"
41 
42 // Cppunit includes
43 #include <cppunit/extensions/HelperMacros.h>
44 
45 #define COMPARE_VALUES(a, b) \
46  CPPUNIT_ASSERT( std::abs(a-b) < this->tol_a + this->tol_r*std::abs(a) );
47 
48 #define COMPARE_FADS(a, b) \
49 CPPUNIT_ASSERT(a.size() == b.size()); \
50 CPPUNIT_ASSERT(a.hasFastAccess() == b.hasFastAccess()); \
51 COMPARE_VALUES(a.val(), b.val()); \
52 for (int i=0; i<a.size(); i++) { \
53  COMPARE_VALUES(a.dx(i), b.dx(i)); \
54  COMPARE_VALUES(a.fastAccessDx(i), b.fastAccessDx(i)); \
55  } \
56  ;
57 
58 #define BINARY_OP_TEST(TESTNAME,OP) \
59  void TESTNAME () { \
60  c_dfad = a_dfad OP b_dfad; \
61  c_fad = a_fad OP b_fad; \
62  COMPARE_FADS(c_dfad, c_fad); \
63  \
64  double val = urand.number(); \
65  c_dfad = a_dfad OP val; \
66  c_fad = a_fad OP val; \
67  COMPARE_FADS(c_dfad, c_fad); \
68  \
69  c_dfad = val OP b_dfad; \
70  c_fad = val OP b_fad; \
71  COMPARE_FADS(c_dfad, c_fad); \
72  }
73 
74 #define RELOP_TEST(TESTNAME,OP) \
75  void TESTNAME () { \
76  bool r1 = a_dfad OP b_dfad; \
77  bool r2 = a_fad OP b_fad; \
78  CPPUNIT_ASSERT(r1 == r2); \
79  \
80  double val = urand.number(); \
81  r1 = a_dfad OP val; \
82  r2 = a_fad OP val; \
83  CPPUNIT_ASSERT(r1 == r2); \
84  \
85  r1 = val OP b_dfad; \
86  r2 = val OP b_fad; \
87  CPPUNIT_ASSERT(r1 == r2); \
88  }
89 
90 #define BINARY_FUNC_TEST(TESTNAME,FUNC) \
91  void TESTNAME () { \
92  c_dfad = FUNC (a_dfad,b_dfad); \
93  c_fad = FUNC (a_fad,b_fad); \
94  COMPARE_FADS(c_dfad, c_fad); \
95  \
96  double val = urand.number(); \
97  c_dfad = FUNC (a_dfad,val); \
98  c_fad = FUNC (a_fad,val); \
99  COMPARE_FADS(c_dfad, c_fad); \
100  \
101  c_dfad = FUNC (val,b_dfad); \
102  c_fad = FUNC (val,b_fad); \
103  COMPARE_FADS(c_dfad, c_fad); \
104  }
105 
106 #define UNARY_OP_TEST(TESTNAME,OP) \
107  void TESTNAME () { \
108  c_dfad = OP a_dfad; \
109  c_fad = OP a_fad; \
110  COMPARE_FADS(c_dfad, c_fad); \
111  }
112 
113 #define UNARY_FUNC_TEST(TESTNAME,FUNC) \
114  void TESTNAME () { \
115  c_dfad = FUNC (a_dfad); \
116  c_fad = FUNC (a_fad); \
117  COMPARE_FADS(c_dfad, c_fad); \
118  }
119 
120 #define UNARY_ASSIGNOP_TEST(TESTNAME,OP) \
121  void TESTNAME () { \
122  c_dfad OP a_dfad; \
123  c_fad OP a_fad; \
124  COMPARE_FADS(c_dfad, c_fad); \
125  \
126  double val = urand.number(); \
127  c_dfad OP val; \
128  c_fad OP val; \
129  COMPARE_FADS(c_dfad, c_fad); \
130  }
131 
132 // A class for testing each Fad operation
133 template <class FadType, class ScalarType>
134 class FadOpsUnitTest : public CppUnit::TestFixture {
135 
137 
138  CPPUNIT_TEST(testAddition);
139  CPPUNIT_TEST(testSubtraction);
140  CPPUNIT_TEST(testMultiplication);
141  CPPUNIT_TEST(testDivision);
142 
143  CPPUNIT_TEST(testEquals);
144  CPPUNIT_TEST(testNotEquals);
145  CPPUNIT_TEST(testLessThanOrEquals);
146  CPPUNIT_TEST(testGreaterThanOrEquals);
147  CPPUNIT_TEST(testLessThan);
148  CPPUNIT_TEST(testGreaterThan);
149 
150  CPPUNIT_TEST(testPow);
153 
154  CPPUNIT_TEST(testUnaryPlus);
155  CPPUNIT_TEST(testUnaryMinus);
156 
157  CPPUNIT_TEST(testExp);
158  CPPUNIT_TEST(testLog);
159  CPPUNIT_TEST(testLog10);
160  CPPUNIT_TEST(testSqrt);
161  CPPUNIT_TEST(testCos);
162  CPPUNIT_TEST(testSin);
163  CPPUNIT_TEST(testTan);
164  CPPUNIT_TEST(testACos);
165  CPPUNIT_TEST(testASin);
166  CPPUNIT_TEST(testATan);
167  CPPUNIT_TEST(testCosh);
168  CPPUNIT_TEST(testSinh);
169  CPPUNIT_TEST(testTanh);
170  CPPUNIT_TEST(testAbs);
171  CPPUNIT_TEST(testFAbs);
172 
173  CPPUNIT_TEST(testPlusEquals);
174  CPPUNIT_TEST(testMinusEquals);
175  CPPUNIT_TEST(testTimesEquals);
176  CPPUNIT_TEST(testDivideEquals);
177 
179 
184 
186 
188 
189 public:
190 
191  FadOpsUnitTest();
192 
193  FadOpsUnitTest(int numComponents, ScalarType absolute_tolerance,
194  ScalarType relative_tolerance);
195 
196  void setUp();
197 
198  void tearDown();
199 
200  BINARY_OP_TEST(testAddition, +);
201  BINARY_OP_TEST(testSubtraction, -);
202  BINARY_OP_TEST(testMultiplication, *);
203  BINARY_OP_TEST(testDivision, /);
204 
205  RELOP_TEST(testEquals, ==);
206  RELOP_TEST(testNotEquals, !=);
207  RELOP_TEST(testLessThanOrEquals, <=);
208  RELOP_TEST(testGreaterThanOrEquals, >=);
209  RELOP_TEST(testLessThan, <);
210  RELOP_TEST(testGreaterThan, >);
211 
212  BINARY_FUNC_TEST(testPow, pow);
213 
214  UNARY_OP_TEST(testUnaryPlus, +);
215  UNARY_OP_TEST(testUnaryMinus, -);
216 
217  UNARY_FUNC_TEST(testExp, exp);
218  UNARY_FUNC_TEST(testLog, log);
219  UNARY_FUNC_TEST(testLog10, log10);
220  UNARY_FUNC_TEST(testSqrt, sqrt);
221  UNARY_FUNC_TEST(testCos, cos);
222  UNARY_FUNC_TEST(testSin, sin);
223  UNARY_FUNC_TEST(testTan, tan);
224  UNARY_FUNC_TEST(testACos, acos);
225  UNARY_FUNC_TEST(testASin, asin);
226  UNARY_FUNC_TEST(testATan, atan);
227  UNARY_FUNC_TEST(testCosh, cosh);
228  UNARY_FUNC_TEST(testSinh, sinh);
229  UNARY_FUNC_TEST(testTanh, tanh);
230  UNARY_FUNC_TEST(testAbs, abs);
231  UNARY_FUNC_TEST(testFAbs, fabs);
232 
233  UNARY_ASSIGNOP_TEST(testPlusEquals, +=);
234  UNARY_ASSIGNOP_TEST(testMinusEquals, -=);
235  UNARY_ASSIGNOP_TEST(testTimesEquals, *=);
236  UNARY_ASSIGNOP_TEST(testDivideEquals, /=);
237 
238  void testMax();
239  void testMin();
240 
241  template <typename ScalarT>
242  ScalarT composite1(const ScalarT& a, const ScalarT& b) {
243  ScalarT t1 = 3. * a + sin(b) / log(fabs(a - b * 7.));
244  ScalarT t2 = 1.0e3;
245  ScalarT t3 = 5.7e4;
246  ScalarT t4 = 3.2e5;
247  t1 *= cos(a + exp(t1)) / 6. - tan(t1*sqrt(abs(a * log10(abs(b)))));
248  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));
249  t1 /= cosh(b - 0.7) + 7.*sinh(t1 + 0.8)*tanh(9./a) - 9.;
250  t1 += pow(abs(a*4.),b-8.)/cos(a*b*a);
251 
252  return t1;
253 }
254 
255  void testComposite1() {
259  }
260 
261  void testPlusLR() {
262  FadType aa_dfad = a_dfad;
263  FAD::Fad<ScalarType> aa_fad = a_fad;
264  aa_dfad = 1.0;
265  aa_fad = 1.0;
266  aa_dfad = aa_dfad + b_dfad;
267  aa_fad = aa_fad + b_fad;
268  COMPARE_FADS(aa_dfad, aa_fad);
269  }
270 
271  void testMinusLR() {
272  FadType aa_dfad = a_dfad;
273  FAD::Fad<ScalarType> aa_fad = a_fad;
274  aa_dfad = 1.0;
275  aa_fad = 1.0;
276  aa_dfad = aa_dfad - b_dfad;
277  aa_fad = aa_fad - b_fad;
278  COMPARE_FADS(aa_dfad, aa_fad);
279  }
280 
281  void testTimesLR() {
282  FadType aa_dfad = a_dfad;
283  FAD::Fad<ScalarType> aa_fad = a_fad;
284  aa_dfad = 2.0;
285  aa_fad = 2.0;
286  aa_dfad = aa_dfad * b_dfad;
287  aa_fad = aa_fad * b_fad;
288  COMPARE_FADS(aa_dfad, aa_fad);
289  }
290 
291  void testDivideLR() {
292  FadType aa_dfad = a_dfad;
293  FAD::Fad<ScalarType> aa_fad = a_fad;
294  aa_dfad = 2.0;
295  aa_fad = 2.0;
296  aa_dfad = aa_dfad / b_dfad;
297  aa_fad = aa_fad / b_fad;
298  COMPARE_FADS(aa_dfad, aa_fad);
299  }
300 
301  // Check various corner cases for pow()
302  void testPowConstB() {
303  FadType a, b, c, cc;
304 
305  // Constant b
306  a = FadType(n,1.2345);
307  for (int i=0; i<n; ++i)
308  a.fastAccessDx(i) = urand.number();
309  b = 3.456;
310  c = pow(a, b);
311  cc = FadType(n, pow(a.val(),b.val()));
312  for (int i=0; i<n; ++i)
313  cc.fastAccessDx(i) = b.val()*pow(a.val(),b.val()-1)*a.dx(i);
314  COMPARE_FADS(c, cc);
315 
316  // Constant scalar b
317  c = pow(a, b.val());
318  COMPARE_FADS(c, cc);
319 
320  // Constant b == 0
321  b = 0.0;
322  c = pow(a, b);
323  cc.val() = 1.0;
324  for (int i=0; i<n; ++i)
325  cc.fastAccessDx(i) = 0.0;
326  COMPARE_FADS(c, cc);
327 
328  // Constant scalar b == 0
329  c = pow(a, b.val());
330  COMPARE_FADS(c, cc);
331 
332  // a == 0 and constant b
333  a.val() = 0.0;
334  b = 3.456;
335  c = pow(a, b);
336  cc.val() = 0.0;
337  for (int i=0; i<n; ++i)
338  cc.fastAccessDx(i) = 0.0;
339  COMPARE_FADS(c, cc);
340 
341  // a == 0 and constant scalar b
342  c = pow(a, b.val());
343  COMPARE_FADS(c, cc);
344 
345  // a == 0 and b == 0
346  b = 0.0;
347  c = pow(a, b);
348  cc.val() = 1.0;
349  for (int i=0; i<n; ++i)
350  cc.fastAccessDx(i) = 0.0;
351  COMPARE_FADS(c, cc);
352 
353  // a == 0 and scalar b == 0
354  c = pow(a, b.val());
355  COMPARE_FADS(c, cc);
356  }
357 
358 protected:
359 
360  // DFad variables
362 
363  // Fad variables
364  FAD::Fad<ScalarType> a_fad, b_fad, c_fad;
365 
366  // Random number generator
368 
369  // Number of derivative components
370  int n;
371 
372  // Tolerances to which fad objects should be the same
373  ScalarType tol_a, tol_r;
374 
375 }; // class FadOpsUnitTest
376 
377 template <class FadType, class ScalarType>
380  urand(), n(5), tol_a(1.0e-15), tol_r(1.0e-12) {}
381 
382 template <class FadType, class ScalarType>
384 FadOpsUnitTest(int numComponents, ScalarType absolute_tolerance,
385  ScalarType relative_tolerance) :
386  urand(),
387  n(numComponents),
388  tol_a(absolute_tolerance),
389  tol_r(relative_tolerance) {}
390 
391 template <class FadType, class ScalarType>
393  ScalarType val;
394 
395  val = urand.number();
396  a_dfad = FadType(n,val);
397  a_fad = FAD::Fad<ScalarType>(n,val);
398 
399  val = urand.number();
400  b_dfad = FadType(n,val);
401  b_fad = FAD::Fad<ScalarType>(n,val);
402 
403  for (int i=0; i<n; i++) {
404  val = urand.number();
405  a_dfad.fastAccessDx(i) = val;
406  a_fad.fastAccessDx(i) = val;
407 
408  val = urand.number();
409  b_dfad.fastAccessDx(i) = val;
410  b_fad.fastAccessDx(i) = val;
411  }
412 }
413 
414 template <class FadType, class ScalarType>
417 
418 template <class FadType, class ScalarType>
421  ScalarType val;
422 
423  FadType aa_dfad = a_dfad + 1.0;
424  c_dfad = max(aa_dfad, a_dfad);
425  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
426  for (int i=0; i<n; i++) {
427  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
428  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
429  }
430 
431  c_dfad = max(a_dfad, aa_dfad);
432  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
433  for (int i=0; i<n; i++) {
434  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
435  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
436  }
437 
438  c_dfad = max(a_dfad+1.0, a_dfad);
439  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
440  for (int i=0; i<n; i++) {
441  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
442  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
443  }
444 
445  c_dfad = max(a_dfad, a_dfad+1.0);
446  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
447  for (int i=0; i<n; i++) {
448  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
449  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
450  }
451 
452  val = a_dfad.val() + 1;
453  c_dfad = max(a_dfad, val);
454  COMPARE_VALUES(c_dfad.val(), val);
455  for (int i=0; i<n; i++)
456  COMPARE_VALUES(c_dfad.dx(i), 0.0);
457 
458  val = a_dfad.val() - 1;
459  c_dfad = max(a_dfad, val);
460  COMPARE_VALUES(c_dfad.val(), a_dfad.val());
461  for (int i=0; i<n; i++) {
462  COMPARE_VALUES(c_dfad.dx(i), a_dfad.dx(i));
463  COMPARE_VALUES(c_dfad.fastAccessDx(i), a_dfad.fastAccessDx(i));
464  }
465 
466  val = b_dfad.val() + 1;
467  c_dfad = max(val, b_dfad);
468  COMPARE_VALUES(c_dfad.val(), val);
469  for (int i=0; i<n; i++)
470  COMPARE_VALUES(c_dfad.dx(i), 0.0);
471 
472  val = b_dfad.val() - 1;
473  c_dfad = max(val, b_dfad);
474  COMPARE_VALUES(c_dfad.val(), b_dfad.val());
475  for (int i=0; i<n; i++) {
476  COMPARE_VALUES(c_dfad.dx(i), b_dfad.dx(i));
477  COMPARE_VALUES(c_dfad.fastAccessDx(i), b_dfad.fastAccessDx(i));
478  }
479 }
480 
481 template <class FadType, class ScalarType>
484  ScalarType val;
485 
486  FadType aa_dfad = a_dfad - 1.0;
487  c_dfad = min(aa_dfad, a_dfad);
488  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
489  for (int i=0; i<n; i++) {
490  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
491  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
492  }
493 
494  c_dfad = min(a_dfad, aa_dfad);
495  COMPARE_VALUES(c_dfad.val(), aa_dfad.val());
496  for (int i=0; i<n; i++) {
497  COMPARE_VALUES(c_dfad.dx(i), aa_dfad.dx(i));
498  COMPARE_VALUES(c_dfad.fastAccessDx(i), aa_dfad.fastAccessDx(i));
499  }
500 
501  val = a_dfad.val() - 1;
502  c_dfad = min(a_dfad, val);
503  COMPARE_VALUES(c_dfad.val(), val);
504  for (int i=0; i<n; i++)
505  COMPARE_VALUES(c_dfad.dx(i), 0.0);
506 
507  val = a_dfad.val() + 1;
508  c_dfad = min(a_dfad, val);
509  COMPARE_VALUES(c_dfad.val(), a_dfad.val());
510  for (int i=0; i<n; i++) {
511  COMPARE_VALUES(c_dfad.dx(i), a_dfad.dx(i));
512  COMPARE_VALUES(c_dfad.fastAccessDx(i), a_dfad.fastAccessDx(i));
513  }
514 
515  val = b_dfad.val() - 1;
516  c_dfad = min(val, b_dfad);
517  COMPARE_VALUES(c_dfad.val(), val);
518  for (int i=0; i<n; i++)
519  COMPARE_VALUES(c_dfad.dx(i), 0.0);
520 
521  val = b_dfad.val() + 1;
522  c_dfad = min(val, b_dfad);
523  COMPARE_VALUES(c_dfad.val(), b_dfad.val());
524  for (int i=0; i<n; i++) {
525  COMPARE_VALUES(c_dfad.dx(i), b_dfad.dx(i));
526  COMPARE_VALUES(c_dfad.fastAccessDx(i), b_dfad.fastAccessDx(i));
527  }
528 }
529 
530 #undef COMPARE_VALUES
531 #undef COMPARE_FADS
532 
533 #endif // FADUNITTESTS_HPP
RELOP_TEST(testEquals,==)
asin(expr.val())
cosh(expr.val())
abs(expr.val())
UNARY_FUNC_TEST(testExp, exp)
Sacado::Fad::DFad< double > FadType
ScalarType tol_r
atan(expr.val())
ScalarT number()
Get random number.
BINARY_OP_TEST(testAddition,+)
ScalarT composite1(const ScalarT &a, const ScalarT &b)
KOKKOS_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
expr val()
UNARY_ASSIGNOP_TEST(testPlusEquals,+=)
tanh(expr.val())
#define COMPARE_FADS(a, b)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
CPPUNIT_TEST(testAddition)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
sqrt(expr.val())
sinh(expr.val())
tan(expr.val())
FAD::Fad< ScalarType > b_fad
FAD::Fad< ScalarType > a_fad
FAD::Fad< ScalarType > c_fad
sin(expr.val())
log(expr.val())
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
ScalarType tol_a
CPPUNIT_TEST_SUITE(FadOpsUnitTest)
BINARY_FUNC_TEST(testPow, pow)
exp(expr.val())
Sacado::Random< ScalarType > urand
#define COMPARE_VALUES(a, b)
fabs(expr.val())
int n
log10(expr.val())
cos(expr.val())
UNARY_OP_TEST(testUnaryPlus,+)