Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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)
#define TEST_F(test_fixture, test_name)
Definition: gtest.h:2379
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)
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())
int n
void compareFads(const DFadType &x_dfad, const LSType &x_ls)
log10(expr.val())
cos(expr.val())