Sacado Package Browser (Single Doxygen Collection)  Version of the Day
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())
log10(expr.val())
cos(expr.val())
UNARY_OP_TEST(testUnaryPlus,+)