Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
42protected:
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();
67 a_ls = LSType(n,val);
68
69 val = urand.number();
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
216BINARY_OP_TEST(testAddition, +)
217BINARY_OP_TEST(testSubtraction, -)
218BINARY_OP_TEST(testMultiplication, *)
219BINARY_OP_TEST(testDivision, /)
220
221RELOP_TEST(testEquals, ==)
222RELOP_TEST(testNotEquals, !=)
223RELOP_TEST(testLessThanOrEquals, <=)
224RELOP_TEST(testGreaterThanOrEquals, >=)
225RELOP_TEST(testLessThan, <)
226RELOP_TEST(testGreaterThan, >)
227
228BINARY_FUNC_TEST(testPow, pow)
229
230UNARY_OP_TEST(testUnaryPlus, +)
231UNARY_OP_TEST(testUnaryMinus, -)
232
233UNARY_FUNC_TEST(testExp, exp)
234UNARY_FUNC_TEST(testLog, log)
235UNARY_FUNC_TEST(testLog10, log10)
236UNARY_FUNC_TEST(testSqrt, sqrt)
237UNARY_FUNC_TEST(testCos, cos)
238UNARY_FUNC_TEST(testSin, sin)
239UNARY_FUNC_TEST(testTan, tan)
240UNARY_FUNC_TEST(testACos, acos)
241UNARY_FUNC_TEST(testASin, asin)
242UNARY_FUNC_TEST(testATan, atan)
243UNARY_FUNC_TEST(testCosh, cosh)
244UNARY_FUNC_TEST(testSinh, sinh)
245UNARY_FUNC_TEST(testTanh, tanh)
246UNARY_FUNC_TEST(testAbs, abs)
247UNARY_FUNC_TEST(testFAbs, fabs)
248
249UNARY_ASSIGNOP_TEST(testPlusEquals, +=)
250UNARY_ASSIGNOP_TEST(testMinusEquals, -=)
251UNARY_ASSIGNOP_TEST(testTimesEquals, *=)
252UNARY_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}
#define UNARY_OP_TEST(TESTNAME, OP)
#define BINARY_OP_TEST(TESTNAME, OP)
Sacado::LFad::LogicalSparse< double, bool > LSType
#define UNARY_ASSIGNOP_TEST(TESTNAME, OP)
#define BINARY_FUNC_TEST(TESTNAME, FUNC)
Sacado::Fad::DFad< double > DFadType
#define RELOP_TEST(TESTNAME, OP)
#define UNARY_FUNC_TEST(TESTNAME, FUNC)
fabs(expr.val())
log(expr.val())
tan(expr.val())
abs(expr.val())
cos(expr.val())
cosh(expr.val())
acos(expr.val())
sin(expr.val())
sinh(expr.val())
log10(expr.val())
exp(expr.val())
atan(expr.val())
expr val()
sqrt(expr.val())
tanh(expr.val())
asin(expr.val())
void compareFads(const DFadType &x_dfad, const LSType &x_ls)
Sacado::Random< double > urand
ScalarT composite1(const ScalarT &a, const ScalarT &b)
void compareDoubles(double a, double b)
void compareDx(double a, bool b)
User inteface class for computing the logical sparsity pattern of a derivative via forward-mode AD.
A random number generator that generates random numbers uniformly distributed in the interval (a,...
ScalarT number()
Get random number.
#define TEST_F(test_fixture, test_name)
Definition: gtest.h:2379
#define ASSERT_TRUE(condition)
Definition: gtest.h:1985