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