1 #define BOOST_TEST_DYN_LINK
2 #include <boost/test/unit_test.hpp>
3
4 namespace tt = boost::test_tools;
5
6 #include <adolc/adtl.h>
7 typedef adtl::adouble adouble;
8
9 #include "const.h"
10
11 BOOST_AUTO_TEST_SUITE( traceless_scalar )
12
13
14 /***********************************/
15 /* Tests for traceless scalar mode */
16 /* Author: Philipp Schuette */
17 /***********************************/
18
19
20 /* Naming convention for test cases: Operatorname_Operator_Primal for primal
21 * function value. Operatorname_Operator_Derivative(_WrtX) for function
22 * derivative (or partial derivative wrt variable X).
23 */
24
BOOST_AUTO_TEST_CASE(ExpOperatorPrimal)25 BOOST_AUTO_TEST_CASE(ExpOperatorPrimal)
26 {
27 double a = 2.;
28 adouble ad = a;
29
30 a = std::exp(a);
31 ad = adtl::exp(ad);
32
33 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
34 }
35
BOOST_AUTO_TEST_CASE(ExpOperatorDerivative)36 BOOST_AUTO_TEST_CASE(ExpOperatorDerivative)
37 {
38 double a = 2.;
39 adouble ad = a;
40
41 /* Derivative value is exp(a)*adot. */
42 double aDerivative = std::exp(a);
43
44 /* Fast syntax for setting the 0th derivate direction; in scalar mode this
45 * is the only one required. Default derivative value is 0.0.
46 */
47 ad.setADValue(0, 1.);
48 ad = adtl::exp(ad);
49
50 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
51 }
52
BOOST_AUTO_TEST_CASE(MultOperatorPrimal)53 BOOST_AUTO_TEST_CASE(MultOperatorPrimal)
54 {
55 double a = 2., b = 3.5;
56 adouble ad = a, bd = b;
57
58 double c = a * b;
59 adouble cd = ad * bd;
60
61 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
62 }
63
64 /* First case with multiple active input variables. All partial
65 * derivatives are tested.
66 */
67
BOOST_AUTO_TEST_CASE(MultOperatorDerivativeWrtA)68 BOOST_AUTO_TEST_CASE(MultOperatorDerivativeWrtA)
69 {
70 double a = 2., b = 3.5;
71 adouble ad = a, bd = b;
72
73 double cDerivative = 3.5;
74
75 ad.setADValue(0, 1.);
76 adouble cd = ad * bd;
77
78 /* The expected derivative value is cdot = a*bdot + adot*b = b, because
79 * adot = 1., bdot = 0. (by default).
80 */
81 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
82 }
83
BOOST_AUTO_TEST_CASE(MultOperatorDerivativeWrtB)84 BOOST_AUTO_TEST_CASE(MultOperatorDerivativeWrtB)
85 {
86 double a = 2., b = 3.5;
87 adouble ad = a, bd = b;
88
89 double cDerivative = 2.;
90
91 bd.setADValue(0,1.);
92 adouble cd = ad * bd;
93
94 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
95 }
96
BOOST_AUTO_TEST_CASE(AddOperatorPrimal)97 BOOST_AUTO_TEST_CASE(AddOperatorPrimal)
98 {
99 double a = 2.5, b = 3.;
100 adouble ad = a, bd = b;
101
102 double c = a + b;
103 adouble cd = ad + bd;
104
105 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
106 }
107
BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtA)108 BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtA)
109 {
110 double a = 2.5, b = 3.;
111 adouble ad = a, bd = b;
112
113 /* Expected derivate value is cdot = 1.*adot + 1.*bdot. */
114 double cDerivative = 1.;
115
116 ad.setADValue(0, 1.);
117 adouble cd = ad + bd;
118
119 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
120 }
121
BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtB)122 BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtB)
123 {
124 double a = 2.5, b = 3.;
125 adouble ad = a, bd = b;
126
127 double cDerivative = 1.;
128
129 bd.setADValue(0, 1.);
130 adouble cd = ad + bd;
131
132 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
133 }
134
BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtAB)135 BOOST_AUTO_TEST_CASE(AddOperatorDerivativeWrtAB)
136 {
137 double a = 2.5, b = 3.;
138 adouble ad = a, bd = b;
139
140 /* For diversity, check derivative calculation with adot = 4., bdot = 5.5. */
141 double cDerivative = 1. * 4. + 1. * 5.5;
142
143 ad.setADValue(0, 4.);
144 bd.setADValue(0, 5.5);
145 adouble cd = ad + bd;
146
147 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
148 }
149
BOOST_AUTO_TEST_CASE(SubOperatorPrimal)150 BOOST_AUTO_TEST_CASE(SubOperatorPrimal)
151 {
152 double a = 1.5, b = 3.2;
153 adouble ad = a, bd = b;
154
155 double c = a - b;
156 adouble cd = ad - bd;
157
158 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
159 }
160
BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtA)161 BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtA)
162 {
163 double a = 1.5, b = 3.2;
164 adouble ad = a, bd = b;
165
166 /* Derivate value is cdot = 1.*adot - 1.*bdot. */
167 double cDerivative = 1.;
168
169 ad.setADValue(0, 1.);
170 adouble cd = ad - bd;
171
172 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
173 }
174
BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtB)175 BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtB)
176 {
177 double a = 1.5, b = 3.2;
178 adouble ad = a, bd = b;
179
180 double cDerivative = -1.;
181
182 bd.setADValue(0, 1.);
183 adouble cd = ad - bd;
184
185 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
186 }
187
BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtAB)188 BOOST_AUTO_TEST_CASE(SubOperatorDerivateWrtAB)
189 {
190 double a = 1.5, b = 3.2;
191 adouble ad = a, bd = b;
192
193 double cDerivative = 1. * 7.3 - 1. * 1.1;
194
195 ad.setADValue(0, 7.3);
196 bd.setADValue(0, 1.1);
197 adouble cd = ad - bd;
198
199 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
200 }
201
BOOST_AUTO_TEST_CASE(DivOperatorPrimal)202 BOOST_AUTO_TEST_CASE(DivOperatorPrimal)
203 {
204 double a = 0.5, b = 4.5;
205 adouble ad = a, bd = b;
206
207 double c = a / b;
208 adouble cd = ad / bd;
209
210 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
211 }
212
BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtA)213 BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtA)
214 {
215 double a = 0.5, b = 4.5;
216 adouble ad = a, bd = b;
217
218 /* Derivative value cdot = (adot/b) - (c/b)*bdot. */
219 double cDerivative = 1. / b;
220
221 ad.setADValue(0, 1.);
222 adouble cd = ad / bd;
223
224 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
225 }
226
BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtB)227 BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtB)
228 {
229 double a = 0.5, b = 4.5;
230 adouble ad = a, bd = b;
231
232 double c = a / b;
233 double cDerivative = -(c / b);
234
235 bd.setADValue(0, 1.);
236 adouble cd = ad / bd;
237
238 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
239 }
240
BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtAB)241 BOOST_AUTO_TEST_CASE(DivOperatorDerivativeWrtAB)
242 {
243 double a = 0.5, b = 4.5;
244 adouble ad = a, bd = b;
245
246 double c = a / b;
247 double cDerivative = (2. / b) - (c / b) * 3.;
248
249 ad.setADValue(0, 2.);
250 bd.setADValue(0, 3.);
251 adouble cd = ad / bd;
252
253 BOOST_TEST(cd.getADValue(0) == cDerivative, tt::tolerance(tol));
254 }
255
BOOST_AUTO_TEST_CASE(TanOperatorPrimal)256 BOOST_AUTO_TEST_CASE(TanOperatorPrimal)
257 {
258 double a = 0.7;
259 adouble ad = a;
260
261 a = std::tan(a);
262 ad = adtl::tan(ad);
263
264 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
265 }
266
BOOST_AUTO_TEST_CASE(TanOperatorDerivative)267 BOOST_AUTO_TEST_CASE(TanOperatorDerivative)
268 {
269 double a = 0.7;
270 adouble ad = a;
271
272 a = std::tan(a);
273 /* Derivative value: tan = sin/cos --> tan_prime = 1./(cos*cos) = 1 + tan*tan. */
274 double aDerivative = (1. + a*a);
275
276 ad.setADValue(0, 1.);
277 ad = adtl::tan(ad);
278
279 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
280 }
281
BOOST_AUTO_TEST_CASE(SinOperatorPrimal)282 BOOST_AUTO_TEST_CASE(SinOperatorPrimal)
283 {
284 double a = 1.2;
285 adouble ad = a;
286
287 a = std::sin(a);
288 ad = adtl::sin(ad);
289
290 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
291 }
292
BOOST_AUTO_TEST_CASE(SinOperatorDerivative)293 BOOST_AUTO_TEST_CASE(SinOperatorDerivative)
294 {
295 double a = 1.2;
296 adouble ad = a;
297
298 /* Derivative of sin is cos. */
299 double aDerivative = std::cos(a);
300
301 ad.setADValue(0, 1.);
302 ad = adtl::sin(ad);
303
304 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
305 }
306
BOOST_AUTO_TEST_CASE(CosOperatorPrimal)307 BOOST_AUTO_TEST_CASE(CosOperatorPrimal)
308 {
309 double a = 1.2;
310 adouble ad = a;
311
312 a = std::cos(a);
313 ad = adtl::cos(ad);
314
315 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
316 }
317
BOOST_AUTO_TEST_CASE(CosOperatorDerivative)318 BOOST_AUTO_TEST_CASE(CosOperatorDerivative)
319 {
320 double a = 1.2;
321 adouble ad = a;
322
323 /* Derivative of cos is -sin. */
324 double aDerivative = -1. * std::sin(a);
325
326 ad.setADValue(0, 1.);
327 ad = adtl::cos(ad);
328
329 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
330 }
331
BOOST_AUTO_TEST_CASE(SqrtOperatorPrimal)332 BOOST_AUTO_TEST_CASE(SqrtOperatorPrimal)
333 {
334 double a = 2.2;
335 adouble ad = a;
336
337 a = std::sqrt(a);
338 ad = adtl::sqrt(ad);
339
340 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
341 }
342
BOOST_AUTO_TEST_CASE(SqrtOperatorDerivative)343 BOOST_AUTO_TEST_CASE(SqrtOperatorDerivative)
344 {
345 double a = 2.2;
346 adouble ad = a;
347
348 a = std::sqrt(a);
349 /* Derivative value is 1./(2*sqrt). */
350 double aDerivative = 1. / (2 * a);
351
352 ad.setADValue(0, 1.);
353 ad = adtl::sqrt(ad);
354
355 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
356 }
357
BOOST_AUTO_TEST_CASE(LogOperatorPrimal)358 BOOST_AUTO_TEST_CASE(LogOperatorPrimal)
359 {
360 double a = 4.9;
361 adouble ad = a;
362
363 a = std::log(a);
364 ad = adtl::log(ad);
365
366 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
367 }
368
BOOST_AUTO_TEST_CASE(LogOperatorDerivative)369 BOOST_AUTO_TEST_CASE(LogOperatorDerivative)
370 {
371 double a = 4.9;
372 adouble ad = a;
373
374 /* Derivative value is 1./a. */
375 double aDerivative = 1. / a;
376
377 ad.setADValue(0, 1.);
378 ad = adtl::log(ad);
379
380 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
381 }
382
BOOST_AUTO_TEST_CASE(SinhOperatorPrimal)383 BOOST_AUTO_TEST_CASE(SinhOperatorPrimal)
384 {
385 double a = 4.;
386 adouble ad = a;
387
388 a = std::sinh(a);
389 ad = adtl::sinh(ad);
390
391 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
392 }
393
BOOST_AUTO_TEST_CASE(SinhOperatorDerivative)394 BOOST_AUTO_TEST_CASE(SinhOperatorDerivative)
395 {
396 double a = 4.;
397 adouble ad = a;
398
399 /* Derivative of sinh is cosh. */
400 double aDerivative = std::cosh(a);
401
402 ad.setADValue(0, 1.);
403 ad = adtl::sinh(ad);
404
405 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
406 }
407
BOOST_AUTO_TEST_CASE(CoshOperatorPrimal)408 BOOST_AUTO_TEST_CASE(CoshOperatorPrimal)
409 {
410 double a = 4.;
411 adouble ad = a;
412
413 a = std::cosh(a);
414 ad = adtl::cosh(ad);
415
416 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
417 }
418
BOOST_AUTO_TEST_CASE(CoshOperatorDerivative)419 BOOST_AUTO_TEST_CASE(CoshOperatorDerivative)
420 {
421 double a = 4.;
422 adouble ad = a;
423
424 /* Derivative of cosh is sinh. */
425 double aDerivative = std::sinh(a);
426
427 ad.setADValue(0, 1.);
428 ad = adtl::cosh(ad);
429
430 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
431 }
432
BOOST_AUTO_TEST_CASE(TanhOperatorPrimal)433 BOOST_AUTO_TEST_CASE(TanhOperatorPrimal)
434 {
435 double a = 4.;
436 adouble ad = a;
437
438 a = std::tanh(a);
439 ad = adtl::tanh(ad);
440
441 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
442 }
443
BOOST_AUTO_TEST_CASE(TanhOperatorDerivative)444 BOOST_AUTO_TEST_CASE(TanhOperatorDerivative)
445 {
446 double a = 4.;
447 adouble ad = a;
448
449 a = std::tanh(a);
450 /* Derivative value 1./(cosh*cosh) = 1 - tanh*tanh. */
451 double aDerivative = 1 - a*a;
452
453 ad.setADValue(0, 1.);
454 ad = adtl::tanh(ad);
455
456 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
457 }
458
BOOST_AUTO_TEST_CASE(AsinOperatorPrimal)459 BOOST_AUTO_TEST_CASE(AsinOperatorPrimal)
460 {
461 double a = 0.9;
462 adouble ad = a;
463
464 a = std::asin(a);
465 ad = adtl::asin(ad);
466
467 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
468 }
469
BOOST_AUTO_TEST_CASE(AsinOperatorDerivative)470 BOOST_AUTO_TEST_CASE(AsinOperatorDerivative)
471 {
472 double a = 0.9;
473 adouble ad = a;
474
475 /* Derivative value 1. / sqrt(1. - a*a). */
476 double aDerivative = 1. / (std::sqrt(1. - a*a));
477
478 ad.setADValue(0, 1.);
479 ad = adtl::asin(ad);
480
481 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
482 }
483
BOOST_AUTO_TEST_CASE(AcosOperatorPrimal)484 BOOST_AUTO_TEST_CASE(AcosOperatorPrimal)
485 {
486 double a = 0.8;
487 adouble ad = a;
488
489 a = std::acos(a);
490 ad = adtl::acos(ad);
491
492 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
493 }
494
BOOST_AUTO_TEST_CASE(AcosOperatorDerivative)495 BOOST_AUTO_TEST_CASE(AcosOperatorDerivative)
496 {
497 double a = 0.8;
498 adouble ad = a;
499
500 /* Derivative value -1. / sqrt(1. - a*a). */
501 double aDerivative = -1. / (std::sqrt(1. - a*a));
502
503 ad.setADValue(0, 1.);
504 ad = adtl::acos(ad);
505
506 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
507 }
508
BOOST_AUTO_TEST_CASE(AtanOperatorPrimal)509 BOOST_AUTO_TEST_CASE(AtanOperatorPrimal)
510 {
511 double a = 9.8;
512 adouble ad = a;
513
514 a = std::atan(a);
515 ad = adtl::atan(ad);
516
517 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
518 }
519
BOOST_AUTO_TEST_CASE(AtanOperatorDerivative)520 BOOST_AUTO_TEST_CASE(AtanOperatorDerivative)
521 {
522 double a = 9.8;
523 adouble ad = a;
524
525 /* Derivative value 1./(1. + a*a). */
526 double aDerivative = 1. / (1. + a*a);
527
528 ad.setADValue(0, 1.);
529 ad = adtl::atan(ad);
530
531 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
532 }
533
BOOST_AUTO_TEST_CASE(Log10OperatorPrimal)534 BOOST_AUTO_TEST_CASE(Log10OperatorPrimal)
535 {
536 double a = 12.3;
537 adouble ad = a;
538
539 a = std::log10(a);
540 ad = adtl::log10(ad);
541
542 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
543 }
544
BOOST_AUTO_TEST_CASE(Log10OperatorDerivative)545 BOOST_AUTO_TEST_CASE(Log10OperatorDerivative)
546 {
547 double a = 12.3;
548 adouble ad = a;
549
550 /* Derivative value 1. / (log(10)*a), because log10(a) = log(a)/log(10). */
551 double aDerivative = 1. / (a * std::log(10));
552
553 ad.setADValue(0, 1.);
554 ad = adtl::log10(ad);
555
556 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
557 }
558
559 #if defined(ATRIG_ERF)
BOOST_AUTO_TEST_CASE(AsinhOperatorPrimal)560 BOOST_AUTO_TEST_CASE(AsinhOperatorPrimal)
561 {
562 double a = 0.6;
563 adouble ad = a;
564
565 a = std::asinh(a);
566 ad = adtl::asinh(ad);
567
568 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
569 }
570
BOOST_AUTO_TEST_CASE(AsinhOperatorDerivative)571 BOOST_AUTO_TEST_CASE(AsinhOperatorDerivative)
572 {
573 double a = 0.6;
574 adouble ad = a;
575
576 double aDerivative = 1. / (std::sqrt(a*a + 1.));
577
578 ad.setADValue(0, 1.);
579 ad = adtl::asinh(ad);
580
581 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
582 }
583
BOOST_AUTO_TEST_CASE(AcoshOperatorPrimal)584 BOOST_AUTO_TEST_CASE(AcoshOperatorPrimal)
585 {
586 double a = 1.7;
587 adouble ad = a;
588
589 a = std::acosh(a);
590 ad = adtl::acosh(ad);
591
592 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
593 }
594
BOOST_AUTO_TEST_CASE(AcoshOperatorDerivative)595 BOOST_AUTO_TEST_CASE(AcoshOperatorDerivative)
596 {
597 double a = 1.7;
598 adouble ad = a;
599
600 double aDerivative = 1. / (std::sqrt(a*a - 1.));
601
602 ad.setADValue(0, 1.);
603 ad = adtl::acosh(ad);
604
605 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
606 }
607
BOOST_AUTO_TEST_CASE(AtanhOperatorPrimal)608 BOOST_AUTO_TEST_CASE(AtanhOperatorPrimal)
609 {
610 double a = 0.6;
611 adouble ad = a;
612
613 a = std::atanh(a);
614 ad = adtl::atanh(ad);
615
616 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
617 }
618
BOOST_AUTO_TEST_CASE(AtanhOperatorDerivative)619 BOOST_AUTO_TEST_CASE(AtanhOperatorDerivative)
620 {
621 double a = 0.6;
622 adouble ad = a;
623
624 double aDerivative = 1. / (1. - a*a);
625
626 ad.setADValue(0, 1.);
627 ad = adtl::atanh(ad);
628
629 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
630 }
631 #endif
632
BOOST_AUTO_TEST_CASE(InclOperatorPrimal)633 BOOST_AUTO_TEST_CASE(InclOperatorPrimal)
634 {
635 double a = 5.;
636 adouble ad = a;
637
638 ++a;
639 ++ad;
640
641 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
642 }
643
BOOST_AUTO_TEST_CASE(InclOperatorDerivative)644 BOOST_AUTO_TEST_CASE(InclOperatorDerivative)
645 {
646 double a = 5.;
647 adouble ad = a;
648
649 double aDerivative = 1.;
650
651 ad.setADValue(0, 1.);
652 ++ad;
653
654 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
655 }
656
BOOST_AUTO_TEST_CASE(DeclOperatorPrimal)657 BOOST_AUTO_TEST_CASE(DeclOperatorPrimal)
658 {
659 double a = 5.;
660 adouble ad = a;
661
662 --a;
663 --ad;
664
665 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
666 }
667
BOOST_AUTO_TEST_CASE(DeclOperatorDerivative)668 BOOST_AUTO_TEST_CASE(DeclOperatorDerivative)
669 {
670 double a = 5.;
671 adouble ad = a;
672
673 double aDerivative = 1.;
674
675 ad.setADValue(0, 1.);
676 --ad;
677
678 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
679 }
680
BOOST_AUTO_TEST_CASE(SignPlusOperatorPrimal)681 BOOST_AUTO_TEST_CASE(SignPlusOperatorPrimal)
682 {
683 double a = 1.5;
684 adouble ad = a;
685
686 a = +a;
687 ad = +ad;
688
689 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
690 }
691
BOOST_AUTO_TEST_CASE(SignPlusOperatorDerivative)692 BOOST_AUTO_TEST_CASE(SignPlusOperatorDerivative)
693 {
694 double a = 1.5;
695 adouble ad = a;
696
697 double aDerivative = 1.;
698
699 ad.setADValue(0, 1.);
700 ad = +ad;
701
702 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
703 }
704
BOOST_AUTO_TEST_CASE(SignMinusOperatorPrimal)705 BOOST_AUTO_TEST_CASE(SignMinusOperatorPrimal)
706 {
707 double a = 1.5;
708 adouble ad = a;
709
710 a = -a;
711 ad = -ad;
712
713 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
714 }
715
BOOST_AUTO_TEST_CASE(SignMinusOperatorDerivative)716 BOOST_AUTO_TEST_CASE(SignMinusOperatorDerivative)
717 {
718 double a = 1.5;
719 adouble ad = a;
720
721 double aDerivative = -1.;
722
723 ad.setADValue(0, 1.);
724 ad = -ad;
725
726 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
727 }
728
729 /* The atan2 operator is defined as atan2(a, b) = atan(a/b). */
BOOST_AUTO_TEST_CASE(Atan2OperatorPrimal)730 BOOST_AUTO_TEST_CASE(Atan2OperatorPrimal)
731 {
732 double a = 12.3, b = 2.1;
733 adouble ad = a, bd = b;
734
735 double c = std::atan2(a, b);
736 adouble cd = adtl::atan2(ad, bd);
737
738 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
739 }
740
BOOST_AUTO_TEST_CASE(Atan2OperatorDerivativeWrtA)741 BOOST_AUTO_TEST_CASE(Atan2OperatorDerivativeWrtA)
742 {
743 double a = 12.3, b = 2.1;
744 adouble ad = a, bd = b;
745
746 /* Partial derivative wrt a of atan2(a, b) is b/(a*a + b*b). */
747 double c = b / (a*a + b*b);
748
749 ad.setADValue(0, 1.);
750 adouble cd = adtl::atan2(ad, bd);
751
752 BOOST_TEST(cd.getADValue(0) == c, tt::tolerance(tol));
753 }
754
BOOST_AUTO_TEST_CASE(Atan2OperatorDerivativeWrtB)755 BOOST_AUTO_TEST_CASE(Atan2OperatorDerivativeWrtB)
756 {
757 double a = 12.3, b = 2.1;
758 adouble ad = a, bd = b;
759
760 /* Partial derivative wrt b of atan2(a, b) is -a/(a*a + b*b). */
761 double c = -a / (a*a + b*b);
762
763 bd.setADValue(0, 1.);
764 adouble cd = adtl::atan2(ad, bd);
765
766 BOOST_TEST(cd.getADValue(0) == c, tt::tolerance(tol));
767 }
768
769 /* For the pow operator (pow(x, n) = x^n), ADOL-C provides three different options with
770 * the following signatures:
771 *
772 * (1) adouble pow(adouble, double) --> can be differentiated wrt the base adouble
773 * (2) adouble pow(adouble, adouble) --> can be differentiated wrt both base and exponent
774 * (3) adouble pow(double, adouble) --> can be differentiated wrt the exponent adouble
775 *
776 * tests for these three are implemented separately for both primal and derivative value.
777 */
778
BOOST_AUTO_TEST_CASE(PowOperatorPrimal_1)779 BOOST_AUTO_TEST_CASE(PowOperatorPrimal_1)
780 {
781 double a = 2.3;
782 adouble ad = a;
783
784 /* Common exponent for both std:: and adtl:: */
785 double e = 3.5;
786
787 a = std::pow(a, e);
788 ad = adtl::pow(ad, e);
789
790 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
791 }
792
BOOST_AUTO_TEST_CASE(PowOperatorDerivative_1)793 BOOST_AUTO_TEST_CASE(PowOperatorDerivative_1)
794 {
795 double a = 2.3;
796 adouble ad = a;
797
798 /* Common exponent for both std:: and adtl:: */
799 double e = 3.5;
800
801 double aDerivative = e * std::pow(a, e - 1.);
802
803 ad.setADValue(0, 1.);
804 ad = adtl::pow(ad, e);
805
806 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
807 }
808
BOOST_AUTO_TEST_CASE(PowOperatorPrimal_2)809 BOOST_AUTO_TEST_CASE(PowOperatorPrimal_2)
810 {
811 double a = 2.3, e = 3.5;
812 adouble ad = a, ed = e;
813
814 a = std::pow(a, e);
815 ad = adtl::pow(ad, ed);
816
817 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
818 }
819
BOOST_AUTO_TEST_CASE(PowOperatorDerivative_2_WrtA)820 BOOST_AUTO_TEST_CASE(PowOperatorDerivative_2_WrtA)
821 {
822 double a = 2.3, e = 3.5;
823 adouble ad = a, ed = e;
824
825 double aDerivative = e * std::pow(a, e - 1.);
826
827 ad.setADValue(0, 1.);
828 ad = adtl::pow(ad, ed);
829
830 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
831 }
832
BOOST_AUTO_TEST_CASE(PowOperatorDerivative_2_WrtB)833 BOOST_AUTO_TEST_CASE(PowOperatorDerivative_2_WrtB)
834 {
835 double a = 2.3, e = 3.5;
836 adouble ad = a, ed = e;
837
838 /* For derivative calculation use pow(a, e) = exp(e*log(a)). */
839 double eDerivative = std::log(a) * std::pow(a, e);
840
841 ed.setADValue(0, 1.);
842 ed = adtl::pow(ad, ed);
843
844 BOOST_TEST(ed.getADValue(0) == eDerivative, tt::tolerance(tol));
845 }
846
BOOST_AUTO_TEST_CASE(PowOperatorPrimal_3)847 BOOST_AUTO_TEST_CASE(PowOperatorPrimal_3)
848 {
849 double e = 3.5;
850 adouble ed = e;
851
852 /* Common base for both std:: and adtl:: */
853 double a = 2.3;
854
855 e = std::pow(a, e);
856 ed = adtl::pow(a, ed);
857
858 BOOST_TEST(ed.getValue() == e, tt::tolerance(tol));
859 }
860
BOOST_AUTO_TEST_CASE(PowOperatorDerivative_3)861 BOOST_AUTO_TEST_CASE(PowOperatorDerivative_3)
862 {
863 double e = 3.5;
864 adouble ed = e;
865
866 /* Common base for both std:: and adtl:: */
867 double a = 2.3;
868
869 double eDerivative = std::log(a) * std::pow(a, e);
870
871 ed.setADValue(0, 1.);
872 ed = adtl::pow(a, ed);
873
874 BOOST_TEST(ed.getADValue(0) == eDerivative, tt::tolerance(tol));
875 }
876
877 /* Only the primitive value of frexp has to be tested, as this function
878 * is not differentiable.
879 */
BOOST_AUTO_TEST_CASE(FrexpOperatorPrimal_Derivative)880 BOOST_AUTO_TEST_CASE(FrexpOperatorPrimal_Derivative)
881 {
882 double a = 4.348;
883 adouble ad = a;
884
885 int m = 1;
886 int *n;
887 n = &m;
888
889 double aValue = std::frexp(a, n);
890
891 ad.setADValue(0, 1.);
892 ad = adtl::frexp(ad, n);
893
894 BOOST_TEST(ad.getValue() == aValue, tt::tolerance(tol));
895 /* ADValue is 0., because the output of frexp() is double, not adouble. */
896 BOOST_TEST(ad.getADValue(0) == 0., tt::tolerance(tol));
897 }
898
BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_1)899 BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_1)
900 {
901 double a = 4., b = 3.;
902 adouble ad = a, bd = b;
903
904 a = a * std::pow(2., b);
905 ad = adtl::ldexp(ad, bd);
906
907 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
908 }
909
BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_1_WrtA)910 BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_1_WrtA)
911 {
912 double a = 4., b = 3.;
913 adouble ad = a, bd = b;
914
915 double aDerivative = std::pow(2., b);
916
917 ad.setADValue(0, 1.);
918 ad = adtl::ldexp(ad, bd);
919
920 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
921 }
922
BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_1_WrtB)923 BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_1_WrtB)
924 {
925 double a = 4., b = 3.;
926 adouble ad = a, bd = b;
927
928 double bDerivative = a * std::log(2.) * std::pow(2., b);
929
930 bd.setADValue(0, 1.);
931 bd = adtl::ldexp(ad, bd);
932
933 BOOST_TEST(bd.getADValue(0) == bDerivative, tt::tolerance(tol));
934 }
935
BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_2)936 BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_2)
937 {
938 double a = 4., b = 3.;
939 adouble ad = a;
940
941 a = a * std::pow(2., b);
942 ad = adtl::ldexp(ad, b);
943
944 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
945 }
946
BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_2)947 BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_2)
948 {
949 double a = 4., b = 3.;
950 adouble ad = a;
951
952 double aDerivative = std::pow(2., b);
953
954 ad.setADValue(0, 1.);
955 ad = adtl::ldexp(ad, b);
956
957 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
958 }
959
BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_3)960 BOOST_AUTO_TEST_CASE(LdexpOperatorPrimal_3)
961 {
962 double a = 4., b = 3.;
963 adouble bd = b;
964
965 b = a * std::pow(2., b);
966 bd = adtl::ldexp(a, bd);
967
968 BOOST_TEST(bd.getValue() == b, tt::tolerance(tol));
969 }
970
BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_3)971 BOOST_AUTO_TEST_CASE(LdexpOperatorDerivative_3)
972 {
973 double a = 4., b = 3.;
974 adouble bd = b;
975
976 double bDerivative = a * std::log(2.) * std::pow(2., b);
977
978 bd.setADValue(0, 1.);
979 bd = adtl::ldexp(a, bd);
980
981 BOOST_TEST(bd.getADValue(0) == bDerivative, tt::tolerance(tol));
982 }
983
984 /* For the absolute value operator, the following test cases are implemented:
985 *
986 * (1) Primal value is tested on positive, negative and zero;
987 * (2) Derivative value is tested on positive value, negative value;
988 * (3) Derivative value is tested on zero in positive direction, negative direction.
989 */
990
BOOST_AUTO_TEST_CASE(FabsOperatorPrimal)991 BOOST_AUTO_TEST_CASE(FabsOperatorPrimal)
992 {
993 double a = 1.4, b = -5.;
994 adouble ad = a, bd = b;
995
996 a = std::fabs(a);
997 b = std::fabs(b);
998 ad = adtl::fabs(ad);
999 bd = adtl::fabs(bd);
1000
1001 adouble cd = 0;
1002 cd = adtl::fabs(cd);
1003
1004 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1005 BOOST_TEST(bd.getValue() == b, tt::tolerance(tol));
1006 BOOST_TEST(cd.getValue() == 0, tt::tolerance(tol));
1007 }
1008
BOOST_AUTO_TEST_CASE(FabsOperatorDerivativeAtNonZero)1009 BOOST_AUTO_TEST_CASE(FabsOperatorDerivativeAtNonZero)
1010 {
1011 double a = 1.4, b = -5.;
1012 adouble ad = a, bd = b;
1013
1014 double aDerivative = 1.;
1015
1016 ad.setADValue(0, 1.);
1017 ad = adtl::fabs(ad);
1018
1019 double bDerivative = -1.;
1020
1021 bd.setADValue(0, 1.);
1022 bd = adtl::fabs(bd);
1023
1024 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
1025 BOOST_TEST(bd.getADValue(0) == bDerivative, tt::tolerance(tol));
1026 }
1027
BOOST_AUTO_TEST_CASE(FabsOperatorDerivativeAtZero)1028 BOOST_AUTO_TEST_CASE(FabsOperatorDerivativeAtZero)
1029 {
1030 adouble ad = 0;
1031 adouble bd = 0;
1032
1033 ad.setADValue(0, 2.5);
1034 bd.setADValue(0, -3.5);
1035
1036 double posDerivative = 2.5; /* ADValue * (+1.) */
1037 double negDerivative = 3.5; /* ADValue * (-1.) */
1038
1039 ad = adtl::fabs(ad);
1040 bd = adtl::fabs(bd);
1041
1042 BOOST_TEST(ad.getADValue(0) == posDerivative, tt::tolerance(tol));
1043 BOOST_TEST(bd.getADValue(0) == negDerivative, tt::tolerance(tol));
1044 }
1045
1046 /* The ceil operator is implemented as to 'destroy' any derivative calculations: Its
1047 * derivative is set to 0 regardless of Value/ADValue.
1048 */
BOOST_AUTO_TEST_CASE(CeilOperatorPrimal)1049 BOOST_AUTO_TEST_CASE(CeilOperatorPrimal)
1050 {
1051 double a = 3.573;
1052 adouble ad = a;
1053
1054 a = std::ceil(a);
1055 ad = adtl::ceil(ad);
1056
1057 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1058 }
1059
BOOST_AUTO_TEST_CASE(CeilOperatorDerivative)1060 BOOST_AUTO_TEST_CASE(CeilOperatorDerivative)
1061 {
1062 double a = 3.573;
1063 adouble ad = a;
1064
1065 double aDerivative = 0.0;
1066
1067 /* Slight variation in derivative direction value. */
1068 ad.setADValue(0, 1.1);
1069 ad = adtl::ceil(ad);
1070
1071 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
1072 }
1073
1074 /* To the floor operator comments similar to those regarding ceil apply. */
BOOST_AUTO_TEST_CASE(FloorOperatorPrimal)1075 BOOST_AUTO_TEST_CASE(FloorOperatorPrimal)
1076 {
1077 double a = 4.483;
1078 adouble ad = a;
1079
1080 a = std::floor(a);
1081 ad = adtl::floor(ad);
1082
1083 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1084 }
1085
BOOST_AUTO_TEST_CASE(FloorOperatorDerivative)1086 BOOST_AUTO_TEST_CASE(FloorOperatorDerivative)
1087 {
1088 double a = 4.483;
1089 adouble ad = a;
1090
1091 double aDerivative = 0.0;
1092
1093 ad.setADValue(0, -1.7);
1094 ad = adtl::ceil(ad);
1095
1096 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
1097 }
1098
1099 /* For the fmax and fmin operators, ADOL-C provides three different options with the
1100 * following signatures:
1101 *
1102 * (1) adouble fmax(adouble, adouble) --> can be differentiated wrt both variables
1103 * (2) adouble fmax(double, adouble) --> can be differentiated wrt the second variable
1104 * (3) adouble fmax(adouble, double) --> can be differentiated wrt the first variable
1105 *
1106 * tests for these three are implemented separately for both primal and
1107 * derivative value.
1108 */
1109
BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_1)1110 BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_1)
1111 {
1112 double a = 4., b = 3.2;
1113 adouble ad = a, bd = b;
1114
1115 double c = std::fmax(a, b);
1116 adouble cd = adtl::fmax(ad, bd);
1117
1118 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1119 }
1120
1121 /* If a > b, then the derivative is calculated as fmax(a, b) = a; similarly
1122 * for b > a. If a = b, then the greater derivative direction is adopted as
1123 * the derivative value. Thus, the cases a > b and a = b are tested.
1124 */
1125
BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_1)1126 BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_1)
1127 {
1128 /* First partial derivative, a > b. */
1129 double a1 = 4., b1 = 3.2;
1130 adouble a1d = a1, b1d = b1;
1131
1132 double derivative1 = 1.;
1133
1134 a1d.setADValue(0, 1.);
1135 adouble c1d = adtl::fmax(a1d, b1d);
1136
1137 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1138
1139 /* Second partial derivative, a > b. */
1140 double a2 = 4., b2 = 3.2;
1141 adouble a2d = a2, b2d = b2;
1142
1143 double derivative2 = 0.;
1144
1145 b2d.setADValue(0, 1.);
1146 adouble c2d = adtl::fmax(a2d, b2d);
1147
1148 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1149
1150 /* Derivative for a = b, with a.ADVal < b.ADVal. */
1151 double a3 = 2.5, b3 = 2.5;
1152 adouble a3d = a3, b3d = b3;
1153
1154 double derivative3 = 3.7;
1155
1156 a3d.setADValue(0, 1.3);
1157 b3d.setADValue(0, 3.7);
1158 adouble c3d = adtl::fmax(a3d, b3d);
1159
1160 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1161 }
1162
BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_2)1163 BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_2)
1164 {
1165 double a = 4., b = 3.2;
1166 adouble bd = b;
1167
1168 double c = std::fmax(a, b);
1169 adouble cd = adtl::fmax(a, bd);
1170
1171 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1172 }
1173
1174 /* If a < b, then fmax(double a, adouble b) behaves like case (1);
1175 * if a > b, then the derivative is set to 0.0 (a is not active!).
1176 * If a = b, fmax carries through a positive derivative value of b and
1177 * introduces 0.0 as derivative value for negative b.ADVal.
1178 */
1179
BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_2)1180 BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_2)
1181 {
1182 /* Case a > b. */
1183 double a1 = 4., b1 = 3.2;
1184 adouble b1d = b1;
1185
1186 double derivative1 = 0.;
1187
1188 b1d.setADValue(0, 1.);
1189 adouble c1d = adtl::fmax(a1, b1d);
1190
1191 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1192
1193 /* Case a < b. */
1194 double a2 = 4., b2 = 5.2;
1195 adouble b2d = b2;
1196
1197 double derivative2 = 1.;
1198
1199 b2d.setADValue(0, 1.);
1200 adouble c2d = adtl::fmax(a2, b2d);
1201
1202 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1203
1204 /* Case a = b. */
1205 double a3 = 4.5, b3 = 4.5;
1206 adouble b3d = b3;
1207
1208 double derivative3 = 0.;
1209
1210 b3d.setADValue(0, -7.3);
1211 adouble c3d = adtl::fmax(a3, b3d);
1212
1213 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1214 }
1215
BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_3)1216 BOOST_AUTO_TEST_CASE(FmaxOperatorPrimal_3)
1217 {
1218 double a = 4., b = 3.2;
1219 adouble ad = a;
1220
1221 double c = std::fmax(a, b);
1222 adouble cd = adtl::fmax(ad, b);
1223
1224 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1225 }
1226
1227 /* Signature fmax(adouble, double) works basically the same as
1228 * signature fmax(double, adouble).
1229 */
1230
BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_3)1231 BOOST_AUTO_TEST_CASE(FmaxOperatorDerivative_3)
1232 {
1233 /* Case a > b. */
1234 double a1 = 4., b1 = 3.2;
1235 adouble a1d = a1;
1236
1237 double derivative1 = 1.;
1238
1239 a1d.setADValue(0, 1.);
1240 adouble c1d = adtl::fmax(a1d, b1);
1241
1242 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1243
1244 /* Case a < b. */
1245 double a2 = 4., b2 = 5.2;
1246 adouble a2d = a2;
1247
1248 double derivative2 = 0.;
1249
1250 a2d.setADValue(0, 1.);
1251 adouble c2d = adtl::fmax(a2d, b2);
1252
1253 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1254
1255 /* Case a = b. */
1256 double a3 = 4.5, b3 = 4.5;
1257 adouble a3d = a3;
1258
1259 double derivative3 = 7.3;
1260
1261 a3d.setADValue(0, 7.3);
1262 adouble c3d = adtl::fmax(a3d, b3);
1263
1264 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1265 }
1266
1267 /* The procedure for fmin() is completely analogous to that for fmax(). */
1268
BOOST_AUTO_TEST_CASE(FminOperatorPrimal_1)1269 BOOST_AUTO_TEST_CASE(FminOperatorPrimal_1)
1270 {
1271 double a = 4., b = 3.2;
1272 adouble ad = a, bd = b;
1273
1274 double c = std::fmin(a, b);
1275 adouble cd = adtl::fmin(ad, bd);
1276
1277 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1278 }
1279
BOOST_AUTO_TEST_CASE(FminOperatorDerivative_1)1280 BOOST_AUTO_TEST_CASE(FminOperatorDerivative_1)
1281 {
1282 /* First partial derivative, a > b. */
1283 double a1 = 4., b1 = 3.2;
1284 adouble a1d = a1, b1d = b1;
1285
1286 double derivative1 = 0.;
1287
1288 a1d.setADValue(0, 1.);
1289 adouble c1d = adtl::fmin(a1d, b1d);
1290
1291 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1292
1293 /* Second partial derivative, a > b. */
1294 double a2 = 4., b2 = 3.2;
1295 adouble a2d = a2, b2d = b2;
1296
1297 double derivative2 = 1.;
1298
1299 b2d.setADValue(0, 1.);
1300 adouble c2d = adtl::fmin(a2d, b2d);
1301
1302 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1303
1304 /* Derivative for a = b, with a.ADVal < b.ADVal. */
1305 double a3 = 2.5, b3 = 2.5;
1306 adouble a3d = a3, b3d = b3;
1307
1308 double derivative3 = 1.3;
1309
1310 a3d.setADValue(0, 1.3);
1311 b3d.setADValue(0, 3.7);
1312 adouble c3d = adtl::fmin(a3d, b3d);
1313
1314 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1315 }
1316
BOOST_AUTO_TEST_CASE(FminOperatorPrimal_2)1317 BOOST_AUTO_TEST_CASE(FminOperatorPrimal_2)
1318 {
1319 double a = 4., b = 3.2;
1320 adouble bd = b;
1321
1322 double c = std::fmin(a, b);
1323 adouble cd = adtl::fmin(a, bd);
1324
1325 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1326 }
1327
BOOST_AUTO_TEST_CASE(FminOperatorDerivative_2)1328 BOOST_AUTO_TEST_CASE(FminOperatorDerivative_2)
1329 {
1330 /* Case a > b. */
1331 double a1 = 4., b1 = 3.2;
1332 adouble b1d = b1;
1333
1334 double derivative1 = 1.;
1335
1336 b1d.setADValue(0, 1.);
1337 adouble c1d = adtl::fmin(a1, b1d);
1338
1339 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1340
1341 /* Case a < b. */
1342 double a2 = 4., b2 = 5.2;
1343 adouble b2d = b2;
1344
1345 double derivative2 = 0.;
1346
1347 b2d.setADValue(0, 1.);
1348 adouble c2d = adtl::fmin(a2, b2d);
1349
1350 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1351
1352 /* Case a = b. */
1353 double a3 = 4.5, b3 = 4.5;
1354 adouble b3d = b3;
1355
1356 double derivative3 = -7.3;
1357
1358 b3d.setADValue(0, -7.3);
1359 adouble c3d = adtl::fmin(a3, b3d);
1360
1361 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1362 }
1363
BOOST_AUTO_TEST_CASE(FminOperatorPrimal_3)1364 BOOST_AUTO_TEST_CASE(FminOperatorPrimal_3)
1365 {
1366 double a = 4., b = 3.2;
1367 adouble ad = a;
1368
1369 double c = std::fmin(a, b);
1370 adouble cd = adtl::fmin(ad, b);
1371
1372 BOOST_TEST(cd.getValue() == c, tt::tolerance(tol));
1373 }
1374
BOOST_AUTO_TEST_CASE(FminOperatorDerivative_3)1375 BOOST_AUTO_TEST_CASE(FminOperatorDerivative_3)
1376 {
1377 /* Case a > b. */
1378 double a1 = 4., b1 = 3.2;
1379 adouble a1d = a1;
1380
1381 double derivative1 = 0.;
1382
1383 a1d.setADValue(0, 1.);
1384 adouble c1d = adtl::fmin(a1d, b1);
1385
1386 BOOST_TEST(c1d.getADValue(0) == derivative1, tt::tolerance(tol));
1387
1388 /* Case a < b. */
1389 double a2 = 4., b2 = 5.2;
1390 adouble a2d = a2;
1391
1392 double derivative2 = 1.;
1393
1394 a2d.setADValue(0, 1.);
1395 adouble c2d = adtl::fmin(a2d, b2);
1396
1397 BOOST_TEST(c2d.getADValue(0) == derivative2, tt::tolerance(tol));
1398
1399 /* Case a = b. */
1400 double a3 = 4.5, b3 = 4.5;
1401 adouble a3d = a3;
1402
1403 double derivative3 = 0.;
1404
1405 a3d.setADValue(0, 7.3);
1406 adouble c3d = adtl::fmin(a3d, b3);
1407
1408 BOOST_TEST(c3d.getADValue(0) == derivative3, tt::tolerance(tol));
1409 }
1410
1411 /* The constant ATRIG_ERF activates/deactives the implementations for asinh,
1412 * acosh, atanh, erf. It is defined/undefined in
1413 * adol-c/ADOL-C/include/adolc/internal in the header file adolc_settings.h.
1414 */
1415 #if defined(ATRIG_ERF)
1416 /* The error function erf(a) is defined as
1417 * 2. / sqrt(pi) * int_{0, a} (exp(- t^2))dt.
1418 */
BOOST_AUTO_TEST_CASE(ErfOperatorPrimal)1419 BOOST_AUTO_TEST_CASE(ErfOperatorPrimal)
1420 {
1421 double a = 7.1;
1422 adouble ad = a;
1423
1424 a = std::erf(a);
1425 ad = adtl::erf(ad);
1426
1427 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1428 }
1429
BOOST_AUTO_TEST_CASE(ErfOperatorDerivative)1430 BOOST_AUTO_TEST_CASE(ErfOperatorDerivative)
1431 {
1432 double a = 7.1;
1433 adouble ad = a;
1434
1435 /* The inverse cosine is used for pi so that no additional math library
1436 * import is necessary, see also the implementation in adtl.h.
1437 */
1438 double aDerivative = 2. / std::sqrt(std::acos(-1.)) * std::exp(-a * a);
1439
1440 ad.setADValue(0, 1.);
1441 ad = adtl::erf(ad);
1442
1443 BOOST_TEST(ad.getADValue(0) == aDerivative, tt::tolerance(tol));
1444 }
1445 #endif
1446
1447 /* Test the primitive non-temporary operations =, +=, -=, *=, /=. */
1448
BOOST_AUTO_TEST_CASE(EqOperatorPrimal_Derivative)1449 BOOST_AUTO_TEST_CASE(EqOperatorPrimal_Derivative)
1450 {
1451 double a = 10.01;
1452 adouble ad = a;
1453
1454 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1455 BOOST_TEST(ad.getADValue(0) == 0.0, tt::tolerance(tol));
1456
1457 ad.setValue(5.147);
1458 ad.setADValue(0, 9.919);
1459
1460 BOOST_TEST(ad.getValue() == 5.147, tt::tolerance(tol));
1461 BOOST_TEST(ad.getADValue(0) == 9.919, tt::tolerance(tol));
1462
1463 adouble bd = ad;
1464
1465 BOOST_TEST(ad.getValue() == bd.getValue(), tt::tolerance(tol));
1466 BOOST_TEST(ad.getADValue(0) == bd.getADValue(0), tt::tolerance(tol));
1467 }
1468
BOOST_AUTO_TEST_CASE(EqPlusOperatorPrimal_Derivative)1469 BOOST_AUTO_TEST_CASE(EqPlusOperatorPrimal_Derivative)
1470 {
1471 double a = 5.132;
1472 adouble ad = a;
1473
1474 a += 5.2;
1475 ad.setADValue(0, 2.1);
1476 ad += 5.2;
1477
1478 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1479 BOOST_TEST(ad.getADValue(0) == 2.1, tt::tolerance(tol));
1480
1481 adouble bd;
1482 bd.setValue(1.1);
1483 bd.setADValue(0, 11.1);
1484
1485 ad += bd;
1486 double Value = (5.132 + 5.2 + 1.1);
1487 double ADValue = (2.1 + 11.1);
1488 BOOST_TEST(ad.getValue() == Value, tt::tolerance(tol));
1489 BOOST_TEST(ad.getADValue(0) == ADValue, tt::tolerance(tol));
1490 }
1491
BOOST_AUTO_TEST_CASE(EqMinusOperatorPrimal_Derivative)1492 BOOST_AUTO_TEST_CASE(EqMinusOperatorPrimal_Derivative)
1493 {
1494 double a = 5.132;
1495 adouble ad = a;
1496
1497 a -= 5.2;
1498 ad.setADValue(0, 2.1);
1499 ad -= 5.2;
1500
1501 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1502 BOOST_TEST(ad.getADValue(0) == 2.1, tt::tolerance(tol));
1503
1504 adouble bd;
1505 bd.setValue(1.1);
1506 bd.setADValue(0, 11.1);
1507
1508 ad -= bd;
1509 double Value = (5.132 - 5.2 - 1.1);
1510 double ADValue = (2.1 - 11.1);
1511 BOOST_TEST(ad.getValue() == Value, tt::tolerance(tol));
1512 BOOST_TEST(ad.getADValue(0) == ADValue, tt::tolerance(tol));
1513 }
1514
BOOST_AUTO_TEST_CASE(EqTimesOperatorPrimal_Derivative)1515 BOOST_AUTO_TEST_CASE(EqTimesOperatorPrimal_Derivative)
1516 {
1517 double a = 5.132;
1518 adouble ad = a;
1519
1520 a *= 5.2;
1521 ad.setADValue(0, 2.1);
1522 ad *= 5.2;
1523
1524 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1525 BOOST_TEST(ad.getADValue(0) == (2.1 * 5.2), tt::tolerance(tol));
1526
1527 adouble bd;
1528 bd.setValue(1.1);
1529 bd.setADValue(0, 11.1);
1530
1531 ad *= bd;
1532 double Value = (5.132 * 5.2 * 1.1);
1533 double ADValue = (2.1*5.2*1.1) + (5.132*5.2*11.1);
1534 BOOST_TEST(ad.getValue() == Value, tt::tolerance(tol));
1535 BOOST_TEST(ad.getADValue(0) == ADValue, tt::tolerance(tol));
1536 }
1537
BOOST_AUTO_TEST_CASE(EqDivOperatorPrimal_Derivative)1538 BOOST_AUTO_TEST_CASE(EqDivOperatorPrimal_Derivative)
1539 {
1540 double a = 5.132;
1541 adouble ad = a;
1542
1543 a /= 5.2;
1544 ad.setADValue(0, 2.1);
1545 ad /= 5.2;
1546
1547 BOOST_TEST(ad.getValue() == a, tt::tolerance(tol));
1548 BOOST_TEST(ad.getADValue(0) == (2.1 / 5.2), tt::tolerance(tol));
1549
1550 adouble bd;
1551 bd.setValue(1.1);
1552 bd.setADValue(0, 11.1);
1553
1554 ad /= bd;
1555 double Value = ((5.132 / 5.2) / 1.1);
1556 double ADValue = (2.1/5.2)/1.1 - (5.132/5.2)*11.1/(1.1*1.1);
1557 BOOST_TEST(ad.getValue() == Value, tt::tolerance(tol));
1558 BOOST_TEST(ad.getADValue(0) == ADValue, tt::tolerance(tol));
1559 }
1560
BOOST_AUTO_TEST_CASE(NotOperatorPrimal)1561 BOOST_AUTO_TEST_CASE(NotOperatorPrimal)
1562 {
1563 double a = 1.0;
1564 adouble ad = a;
1565
1566 BOOST_TEST(!a == 0.0, tt::tolerance(tol));
1567 }
1568
BOOST_AUTO_TEST_CASE(CompNeqOperatorPrimal)1569 BOOST_AUTO_TEST_CASE(CompNeqOperatorPrimal)
1570 {
1571 double a = 1.5, b = 0.5;
1572 adouble ad = a, bd = b;
1573
1574 int n = (ad != bd);
1575 int m = (a != b);
1576
1577 BOOST_TEST(n == m, tt::tolerance(tol));
1578
1579 int k = (ad != a);
1580 int l = (a != a);
1581
1582 BOOST_TEST(k == l, tt::tolerance(tol));
1583 }
1584
BOOST_AUTO_TEST_CASE(CompEqOperatorPrimal)1585 BOOST_AUTO_TEST_CASE(CompEqOperatorPrimal)
1586 {
1587 double a = 0.5, b = 1.5;
1588 adouble ad = a, bd = b;
1589
1590 int n = (ad == bd);
1591 int m = (a == b);
1592
1593 BOOST_TEST(n == m, tt::tolerance(tol));
1594
1595 int k = (ad == a);
1596 int l = (a == a);
1597
1598 BOOST_TEST(k == l, tt::tolerance(tol));
1599 }
1600
BOOST_AUTO_TEST_CASE(CompLeqOperatorPrimal)1601 BOOST_AUTO_TEST_CASE(CompLeqOperatorPrimal)
1602 {
1603 double a = 1.0, b = 0.99;
1604 adouble ad = a, bd = b;
1605
1606 int n = (ad <= bd);
1607 int m = (a <= b);
1608
1609 BOOST_TEST(n == m, tt::tolerance(tol));
1610
1611 int k = (ad <= a);
1612 int l = (a <= a);
1613
1614 BOOST_TEST(k == l, tt::tolerance(tol));
1615 }
1616
BOOST_AUTO_TEST_CASE(CompGeqOperatorPrimal)1617 BOOST_AUTO_TEST_CASE(CompGeqOperatorPrimal)
1618 {
1619 double a = 1.2, b = 2.5;
1620 adouble ad = a, bd = b;
1621
1622 int n = (ad >= bd);
1623 int m = (a >= b);
1624
1625 BOOST_TEST(n == m, tt::tolerance(tol));
1626
1627 int k = (ad >= a);
1628 int l = (a >= a);
1629
1630 BOOST_TEST(k == l, tt::tolerance(tol));
1631 }
1632
BOOST_AUTO_TEST_CASE(CompLeOperatorPrimal)1633 BOOST_AUTO_TEST_CASE(CompLeOperatorPrimal)
1634 {
1635 double a = 1.1, b = 1.1;
1636 adouble ad = a, bd = b;
1637
1638 int n = (ad < bd);
1639 int m = (a < b);
1640
1641 BOOST_TEST(n == m, tt::tolerance(tol));
1642
1643 int k = (ad < a);
1644 int l = (a < a);
1645
1646 BOOST_TEST(k == l, tt::tolerance(tol));
1647 }
1648
BOOST_AUTO_TEST_CASE(CompGeOperatorPrimal)1649 BOOST_AUTO_TEST_CASE(CompGeOperatorPrimal)
1650 {
1651 double a = 1.7, b = 7.5;
1652 adouble ad = a, bd = b;
1653
1654 int n = (ad > bd);
1655 int m = (a > b);
1656
1657 BOOST_TEST(n == m, tt::tolerance(tol));
1658
1659 int k = (ad > a);
1660 int l = (a > a);
1661
1662 BOOST_TEST(k == l, tt::tolerance(tol));
1663 }
1664
BOOST_AUTO_TEST_CASE(CondassignOperatorPrimal)1665 BOOST_AUTO_TEST_CASE(CondassignOperatorPrimal)
1666 {
1667 adouble cond = 1., arg1 = 3.5, arg2 = 5.3;
1668 adouble p;
1669
1670 arg1.setADValue(0, 3.5);
1671 arg2.setADValue(0, 5.3);
1672
1673 condassign(p, cond, arg1, arg2);
1674
1675 BOOST_TEST(p.getValue() == arg1.getValue(), tt::tolerance(tol));
1676 BOOST_TEST(p.getADValue(0) == arg1.getADValue(0), tt::tolerance(tol));
1677 }
1678
BOOST_AUTO_TEST_CASE(CondeqassignOperatorPrimal)1679 BOOST_AUTO_TEST_CASE(CondeqassignOperatorPrimal)
1680 {
1681 adouble cond = 0., arg1 = 3.5, arg2 = 5.3;
1682 adouble p;
1683
1684 arg1.setADValue(0, 3.5);
1685 arg2.setADValue(0, 5.3);
1686
1687 condeqassign(p, cond, arg1, arg2);
1688
1689 BOOST_TEST(p.getValue() == arg1.getValue(), tt::tolerance(tol));
1690 BOOST_TEST(p.getADValue(0) == arg1.getADValue(0), tt::tolerance(tol));
1691 }
1692
1693
1694 BOOST_AUTO_TEST_SUITE_END()
1695
1696
1697
1698
1699