Sacado Package Browser (Single Doxygen Collection)  Version of the Day
LogicalSparseUnitTests.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 // Sacado includes
31 #include "Sacado_No_Kokkos.hpp"
32 #include "Sacado_Random.hpp"
33 
36 
37 // gtest includes
38 #include <gtest/gtest.h>
39 
40 // A class for testing each DFad operation
42 protected:
43 
44  // DFad variables
46 
47  // Logical sparse variables
49 
50  // Random number generator
52 
53  // Number of derivative components
54  int n;
55 
56  // Tolerances to which fad objects should be the same
57  double tol_a, tol_r;
58 
60  urand(0.0, 1.0), n(5), tol_a(1.0e-15), tol_r(1.0e-14) {}
61 
62  void SetUp() override {
63  double val;
64 
65  val = urand.number();
66  a_dfad = DFadType(n,val);
67  a_ls = LSType(n,val);
68 
69  val = urand.number();
70  b_dfad = DFadType(n,val);
71  b_ls = LSType(n,val);
72 
73  val = urand.number();
74  c_dfad = val;
75  c_ls = val;
76 
77  for (int i=0; i<n; i++) {
78  val = urand.number();
79  a_dfad.fastAccessDx(i) = val;
80  a_ls.fastAccessDx(i) = 1;
81 
82  val = urand.number();
83  b_dfad.fastAccessDx(i) = val;
84  b_ls.fastAccessDx(i) = 1;
85  }
86  }
87 
88  void TearDown() override {}
89 
90  // Assert to Fad objects are the same
91  void compareFads(const DFadType& x_dfad, const LSType& x_ls) {
92  // Compare sizes
93  ASSERT_TRUE(x_dfad.size() == x_ls.size());
94 
95  // Compare hasFastAccess
96  ASSERT_TRUE(x_dfad.hasFastAccess() == x_ls.hasFastAccess());
97 
98  // Compare values
99  compareDoubles(x_dfad.val(), x_ls.val());
100 
101  for (int i=0; i<x_ls.size(); i++) {
102 
103  // Compare dx
104  compareDx(x_dfad.dx(i), x_ls.dx(i));
105 
106  // Compare fastAccessDx
107  compareDx(x_dfad.fastAccessDx(i), x_ls.fastAccessDx(i));
108  }
109  }
110 
111  // Assert two doubles are the same to relative precision
112  void compareDoubles(double a, double b) {
113  ASSERT_TRUE( fabs(a-b) < tol_a + tol_r*fabs(a) );
114  }
115 
116  // Assert two bools are the same
117  void compareBools(bool a, bool b) {
118  ASSERT_TRUE( a == b );
119  }
120 
121  // Assert a double and bool are same (logically)
122  void compareDx(double a, bool b) {
123  ASSERT_TRUE( (a && b) || !(a || b) );
124  }
125 
126  template <typename ScalarT>
127  ScalarT composite1(const ScalarT& a, const ScalarT& b) {
128  ScalarT t1 = 3. * a + sin(b) / log(fabs(a - b * 7.));
129  ScalarT t2 = 1.0e3;
130  ScalarT t3 = 5.7e4;
131  ScalarT t4 = 3.2e5;
132  t1 *= cos(a + exp(t1)) / 6. - tan(t1*sqrt(abs(a * log10(abs(b)))));
133  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));
134  t1 /= cosh(b - 0.7) + 7.*sinh(t1 + 0.8)*tanh(9./a) - 9.;
135  t1 += pow(abs(a*4.),b-8.)/cos(a*b*a);
136 
137  return t1;
138  }
139 
140 }; // class LogicalSparseOpsUnitTest
141 
142 #define BINARY_OP_TEST(TESTNAME,OP) \
143  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
144  c_dfad = a_dfad OP b_dfad; \
145  c_ls = a_ls OP b_ls; \
146  compareFads(c_dfad, c_ls); \
147  \
148  double val = urand.number(); \
149  c_dfad = a_dfad OP val; \
150  c_ls = a_ls OP val; \
151  compareFads(c_dfad, c_ls); \
152  \
153  c_dfad = val OP b_dfad; \
154  c_ls = val OP b_ls; \
155  compareFads(c_dfad, c_ls); \
156  }
157 
158 #define RELOP_TEST(TESTNAME,OP) \
159  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
160  bool r1 = a_dfad OP b_dfad; \
161  bool r2 = a_ls OP b_ls; \
162  ASSERT_TRUE(r1 == r2); \
163  \
164  double val = urand.number(); \
165  r1 = a_dfad OP val; \
166  r2 = a_ls OP val; \
167  ASSERT_TRUE(r1 == r2); \
168  \
169  r1 = val OP b_dfad; \
170  r2 = val OP b_ls; \
171  ASSERT_TRUE(r1 == r2); \
172  }
173 
174 #define BINARY_FUNC_TEST(TESTNAME,FUNC) \
175  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
176  c_dfad = FUNC (a_dfad,b_dfad); \
177  c_ls = FUNC (a_ls,b_ls); \
178  compareFads(c_dfad, c_ls); \
179  \
180  double val = urand.number(); \
181  c_dfad = FUNC (a_dfad,val); \
182  c_ls = FUNC (a_ls,val); \
183  compareFads(c_dfad, c_ls); \
184  \
185  c_dfad = FUNC (val,b_dfad); \
186  c_ls = FUNC (val,b_ls); \
187  compareFads(c_dfad, c_ls); \
188  }
189 
190 #define UNARY_OP_TEST(TESTNAME,OP) \
191  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
192  c_dfad = OP a_dfad; \
193  c_ls = OP a_ls; \
194  compareFads(c_dfad, c_ls); \
195  }
196 
197 #define UNARY_FUNC_TEST(TESTNAME,FUNC) \
198  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
199  c_dfad = FUNC (a_dfad); \
200  c_ls = FUNC (a_ls); \
201  compareFads(c_dfad, c_ls); \
202  }
203 
204 #define UNARY_ASSIGNOP_TEST(TESTNAME,OP) \
205  TEST_F(LogicalSparseOpsUnitTest, TESTNAME) { \
206  c_dfad OP a_dfad; \
207  c_ls OP a_ls; \
208  compareFads(c_dfad, c_ls); \
209  \
210  double val = urand.number(); \
211  c_dfad OP val; \
212  c_ls OP val; \
213  compareFads(c_dfad, c_ls); \
214  }
215 
216 BINARY_OP_TEST(testAddition, +)
217 BINARY_OP_TEST(testSubtraction, -)
218 BINARY_OP_TEST(testMultiplication, *)
219 BINARY_OP_TEST(testDivision, /)
220 
221 RELOP_TEST(testEquals, ==)
222 RELOP_TEST(testNotEquals, !=)
223 RELOP_TEST(testLessThanOrEquals, <=)
224 RELOP_TEST(testGreaterThanOrEquals, >=)
225 RELOP_TEST(testLessThan, <)
226 RELOP_TEST(testGreaterThan, >)
227 
228 BINARY_FUNC_TEST(testPow, pow)
229 
230 UNARY_OP_TEST(testUnaryPlus, +)
231 UNARY_OP_TEST(testUnaryMinus, -)
232 
233 UNARY_FUNC_TEST(testExp, exp)
234 UNARY_FUNC_TEST(testLog, log)
235 UNARY_FUNC_TEST(testLog10, log10)
236 UNARY_FUNC_TEST(testSqrt, sqrt)
237 UNARY_FUNC_TEST(testCos, cos)
238 UNARY_FUNC_TEST(testSin, sin)
239 UNARY_FUNC_TEST(testTan, tan)
240 UNARY_FUNC_TEST(testACos, acos)
241 UNARY_FUNC_TEST(testASin, asin)
242 UNARY_FUNC_TEST(testATan, atan)
243 UNARY_FUNC_TEST(testCosh, cosh)
244 UNARY_FUNC_TEST(testSinh, sinh)
245 UNARY_FUNC_TEST(testTanh, tanh)
246 UNARY_FUNC_TEST(testAbs, abs)
247 UNARY_FUNC_TEST(testFAbs, fabs)
248 
249 UNARY_ASSIGNOP_TEST(testPlusEquals, +=)
250 UNARY_ASSIGNOP_TEST(testMinusEquals, -=)
251 UNARY_ASSIGNOP_TEST(testTimesEquals, *=)
252 UNARY_ASSIGNOP_TEST(testDivideEquals, /=)
253 
255  c_dfad = composite1(a_dfad, b_dfad);
256  c_ls = composite1(a_ls, b_ls);
257  compareFads(c_dfad, c_ls);
258 }
259 
261  DFadType aa_dfad = a_dfad;
262  LSType aa_ls = a_ls;
263  aa_dfad = 1.0;
264  aa_ls = 1.0;
265  aa_dfad = aa_dfad + b_dfad;
266  aa_ls = aa_ls + b_ls;
267  compareFads(aa_dfad, aa_ls);
268 }
269 
271  DFadType aa_dfad = a_dfad;
272  LSType aa_ls = a_ls;
273  aa_dfad = 1.0;
274  aa_ls = 1.0;
275  aa_dfad = aa_dfad - b_dfad;
276  aa_ls = aa_ls - b_ls;
277  compareFads(aa_dfad, aa_ls);
278 }
279 
281  DFadType aa_dfad = a_dfad;
282  LSType aa_ls = a_ls;
283  aa_dfad = 2.0;
284  aa_ls = 2.0;
285  aa_dfad = aa_dfad * b_dfad;
286  aa_ls = aa_ls * b_ls;
287  compareFads(aa_dfad, aa_ls);
288 }
289 
291  DFadType aa_dfad = a_dfad;
292  LSType aa_ls = a_ls;
293  aa_dfad = 2.0;
294  aa_ls = 2.0;
295  aa_dfad = aa_dfad / b_dfad;
296  aa_ls = aa_ls / b_ls;
297  compareFads(aa_dfad, aa_ls);
298 }
299 
301  double val;
302 
303  // LFAd, LFad
304  LSType aa_ls = a_ls + 1.0;
305  c_ls = max(aa_ls, a_ls);
306  compareDoubles(c_ls.val(), aa_ls.val());
307  for (int i=0; i<n; i++) {
308  compareBools(c_ls.dx(i), aa_ls.dx(i));
309  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
310  }
311  c_ls = max(a_ls, aa_ls);
312  compareDoubles(c_ls.val(), aa_ls.val());
313  for (int i=0; i<n; i++) {
314  compareBools(c_ls.dx(i), aa_ls.dx(i));
315  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
316  }
317 
318  // Expr, LFad
319  c_ls = max(a_ls+1.0, a_ls);
320  compareDoubles(c_ls.val(), aa_ls.val());
321  for (int i=0; i<n; i++) {
322  compareBools(c_ls.dx(i), aa_ls.dx(i));
323  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
324  }
325  c_ls = max(a_ls, a_ls+1.0);
326  compareDoubles(c_ls.val(), aa_ls.val());
327  for (int i=0; i<n; i++) {
328  compareBools(c_ls.dx(i), aa_ls.dx(i));
329  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
330  }
331 
332  // Expr, Expr (same)
333  c_ls = max(a_ls+1.0, a_ls+1.0);
334  compareDoubles(c_ls.val(), aa_ls.val());
335  for (int i=0; i<n; i++) {
336  compareBools(c_ls.dx(i), aa_ls.dx(i));
337  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
338  }
339 
340  // Expr, Expr (different)
341  c_ls = max(a_ls+1.0, a_ls-1.0);
342  compareDoubles(c_ls.val(), aa_ls.val());
343  for (int i=0; i<n; i++) {
344  compareBools(c_ls.dx(i), aa_ls.dx(i));
345  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
346  }
347  c_ls = max(a_ls-1.0, a_ls+1.0);
348  compareDoubles(c_ls.val(), aa_ls.val());
349  for (int i=0; i<n; i++) {
350  compareBools(c_ls.dx(i), aa_ls.dx(i));
351  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
352  }
353 
354  // LFad, const
355  val = a_ls.val() + 1;
356  c_ls = max(a_ls, val);
357  compareDoubles(c_ls.val(), val);
358  for (int i=0; i<n; i++)
359  compareBools(c_ls.dx(i), 0);
360  val = a_ls.val() - 1;
361  c_ls = max(a_ls, val);
362  compareDoubles(c_ls.val(), a_ls.val());
363  for (int i=0; i<n; i++) {
364  compareBools(c_ls.dx(i), a_ls.dx(i));
365  compareBools(c_ls.fastAccessDx(i), a_ls.fastAccessDx(i));
366  }
367  val = b_ls.val() + 1;
368  c_ls = max(val, b_ls);
369  compareDoubles(c_ls.val(), val);
370  for (int i=0; i<n; i++)
371  compareBools(c_ls.dx(i), 0);
372  val = b_ls.val() - 1;
373  c_ls = max(val, b_ls);
374  compareDoubles(c_ls.val(), b_ls.val());
375  for (int i=0; i<n; i++) {
376  compareBools(c_ls.dx(i), b_ls.dx(i));
377  compareBools(c_ls.fastAccessDx(i), b_ls.fastAccessDx(i));
378  }
379 
380  // Expr, const
381  val = a_ls.val();
382  c_ls = max(a_ls+1.0, val);
383  compareDoubles(c_ls.val(), aa_ls.val());
384  for (int i=0; i<n; i++) {
385  compareBools(c_ls.dx(i), aa_ls.dx(i));
386  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
387  }
388  c_ls = max(val, a_ls+1.0);
389  compareDoubles(c_ls.val(), aa_ls.val());
390  for (int i=0; i<n; i++) {
391  compareBools(c_ls.dx(i), aa_ls.dx(i));
392  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
393  }
394 }
395 
397  double val;
398 
399  // LFad, LFad
400  LSType aa_ls = a_ls - 1.0;
401  c_ls = min(aa_ls, a_ls);
402  compareDoubles(c_ls.val(), aa_ls.val());
403  for (int i=0; i<n; i++) {
404  compareBools(c_ls.dx(i), aa_ls.dx(i));
405  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
406  }
407  c_ls = min(a_ls, aa_ls);
408  compareDoubles(c_ls.val(), aa_ls.val());
409  for (int i=0; i<n; i++) {
410  compareBools(c_ls.dx(i), aa_ls.dx(i));
411  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
412  }
413 
414  // Expr, LFad
415  c_ls = min(a_ls-1.0, a_ls);
416  compareDoubles(c_ls.val(), aa_ls.val());
417  for (int i=0; i<n; i++) {
418  compareBools(c_ls.dx(i), aa_ls.dx(i));
419  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
420  }
421  c_ls = min(a_ls, a_ls-1.0);
422  compareDoubles(c_ls.val(), aa_ls.val());
423  for (int i=0; i<n; i++) {
424  compareBools(c_ls.dx(i), aa_ls.dx(i));
425  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
426  }
427 
428  // Expr, Expr (same)
429  c_ls = min(a_ls-1.0, a_ls-1.0);
430  compareDoubles(c_ls.val(), aa_ls.val());
431  for (int i=0; i<n; i++) {
432  compareBools(c_ls.dx(i), aa_ls.dx(i));
433  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
434  }
435 
436  // Expr, Expr (different)
437  c_ls = min(a_ls+1.0, a_ls-1.0);
438  compareDoubles(c_ls.val(), aa_ls.val());
439  for (int i=0; i<n; i++) {
440  compareBools(c_ls.dx(i), aa_ls.dx(i));
441  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
442  }
443  c_ls = min(a_ls-1.0, a_ls+1.0);
444  compareDoubles(c_ls.val(), aa_ls.val());
445  for (int i=0; i<n; i++) {
446  compareBools(c_ls.dx(i), aa_ls.dx(i));
447  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
448  }
449 
450  // LFad, const
451  val = a_ls.val() - 1;
452  c_ls = min(a_ls, val);
453  compareDoubles(c_ls.val(), val);
454  for (int i=0; i<n; i++)
455  compareBools(c_ls.dx(i), 0);
456  val = a_ls.val() + 1;
457  c_ls = min(a_ls, val);
458  compareDoubles(c_ls.val(), a_ls.val());
459  for (int i=0; i<n; i++) {
460  compareBools(c_ls.dx(i), a_ls.dx(i));
461  compareBools(c_ls.fastAccessDx(i), a_ls.fastAccessDx(i));
462  }
463  val = b_ls.val() - 1;
464  c_ls = min(val, b_ls);
465  compareDoubles(c_ls.val(), val);
466  for (int i=0; i<n; i++)
467  compareBools(c_ls.dx(i), 0);
468  val = b_ls.val() + 1;
469  c_ls = min(val, b_ls);
470  compareDoubles(c_ls.val(), b_ls.val());
471  for (int i=0; i<n; i++) {
472  compareBools(c_ls.dx(i), b_ls.dx(i));
473  compareBools(c_ls.fastAccessDx(i), b_ls.fastAccessDx(i));
474  }
475 
476  // Expr, const
477  val = a_ls.val();
478  c_ls = min(a_ls-1.0, val);
479  compareDoubles(c_ls.val(), aa_ls.val());
480  for (int i=0; i<n; i++) {
481  compareBools(c_ls.dx(i), aa_ls.dx(i));
482  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
483  }
484  c_ls = min(val, a_ls-1.0);
485  compareDoubles(c_ls.val(), aa_ls.val());
486  for (int i=0; i<n; i++) {
487  compareBools(c_ls.dx(i), aa_ls.dx(i));
488  compareBools(c_ls.fastAccessDx(i), aa_ls.fastAccessDx(i));
489  }
490 }
void compareDoubles(double a, double b)
void compareDx(double a, bool b)
asin(expr.val())
cosh(expr.val())
#define UNARY_OP_TEST(TESTNAME, OP)
abs(expr.val())
#define BINARY_FUNC_TEST(TESTNAME, FUNC)
Sacado::LFad::LogicalSparse< double, bool > LSType
atan(expr.val())
#define UNARY_FUNC_TEST(TESTNAME, FUNC)
ScalarT number()
Get random number.
expr val()
ScalarT composite1(const ScalarT &a, const ScalarT &b)
tanh(expr.val())
#define ASSERT_TRUE(condition)
Definition: gtest.h:1985
#define RELOP_TEST(TESTNAME, OP)
SimpleFad< ValueT > min(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
#define BINARY_OP_TEST(TESTNAME, OP)
TEST_F(LogicalSparseOpsUnitTest, testComposite1)
sqrt(expr.val())
sinh(expr.val())
tan(expr.val())
Sacado::Fad::DFad< double > DFadType
sin(expr.val())
log(expr.val())
acos(expr.val())
SimpleFad< ValueT > max(const SimpleFad< ValueT > &a, const SimpleFad< ValueT > &b)
SACADO_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)
#define UNARY_ASSIGNOP_TEST(TESTNAME, OP)
exp(expr.val())
Sacado::Random< double > urand
fabs(expr.val())
void compareFads(const DFadType &x_dfad, const LSType &x_ls)
log10(expr.val())
cos(expr.val())