ADOL-C: Automatic Differentiation in C/C++ 2.7.3
Loading...
Searching...
No Matches
adtl.h
Go to the documentation of this file.
1/*----------------------------------------------------------------------------
2 ADOL-C -- Automatic Differentiation by Overloading in C++
3 File: adouble.cpp
4 Revision: $Id$
5 Contents: adtl.h contains that declaratins of procedures used to
6 define various traceless adouble operations.
7
8 Copyright (c) Andrea Walther, Andreas Griewank, Andreas Kowarz,
9 Hristo Mitev, Sebastian Schlenkrich, Jean Utke, Olaf Vogel,
10 Benjamin Letschert, Kshitij Kulshreshtha
11
12 This file is part of ADOL-C. This software is provided as open source.
13 Any use, reproduction, or distribution of the software constitutes
14 recipient's acceptance of the terms of the accompanying license file.
15
16----------------------------------------------------------------------------*/
17#ifndef ADOLC_ADTL_H
18#define ADOLC_ADTL_H
19
20#include <adolc/adolcexport.h>
22#include <list>
23#include <ostream>
24#include <stdexcept>
25
26#if USE_BOOST_POOL
27#include <boost/pool/pool_alloc.hpp>
28#endif
29
30using std::istream;
31using std::list;
32using std::logic_error;
33using std::ostream;
34
35namespace adtl {
36
37ADOLC_API double makeNaN();
38ADOLC_API double makeInf();
39
40#ifdef USE_ADTL_REFCOUNTING
41class adouble;
42
49class refcounter {
50private:
51 static size_t refcnt;
52 ADOLC_API friend void setNumDir(const size_t p);
53 ADOLC_API friend class adouble;
54
55public:
56 refcounter() { ++refcnt; }
57 ~refcounter() { --refcnt; }
58 ADOLC_API inline static size_t getNumLiveVar() { return refcnt; }
59};
60#endif
61
62// class func_ad {
63// public:
64// virtual int operator() (int n, adouble *x, int m, adouble *y) = 0;
65// };
66
77class adouble {
78public:
79 inline adouble();
80 inline adouble(const double v);
81 inline adouble(const double v, const double *adv);
82 inline adouble(const adouble &a);
83 inline ~adouble();
84
85 // sign
86 inline adouble operator-() const;
87 inline adouble operator+() const;
88
89 // addition
90 inline adouble operator+(const double v) const;
91 inline adouble operator+(const adouble &a) const;
92 ADOLC_API inline friend adouble operator+(const double v, const adouble &a);
93
94 // subtraction
95 inline adouble operator-(const double v) const;
96 inline adouble operator-(const adouble &a) const;
97 ADOLC_API inline friend adouble operator-(const double v, const adouble &a);
98
99 // multiplication
100 inline adouble operator*(const double v) const;
101 inline adouble operator*(const adouble &a) const;
102 ADOLC_API inline friend adouble operator*(const double v, const adouble &a);
103
104 // division
105 inline adouble operator/(const double v) const;
106 inline adouble operator/(const adouble &a) const;
107 ADOLC_API inline friend adouble operator/(const double v, const adouble &a);
108
109 // inc/dec
110 inline adouble operator++();
111 inline adouble operator++(int);
112 inline adouble operator--();
113 inline adouble operator--(int);
114
115 // functions
116 ADOLC_API inline friend adouble tan(const adouble &a);
117 ADOLC_API inline friend adouble exp(const adouble &a);
118 ADOLC_API inline friend adouble log(const adouble &a);
119 ADOLC_API inline friend adouble sqrt(const adouble &a);
120 ADOLC_API inline friend adouble cbrt(const adouble &a);
121 ADOLC_API inline friend adouble sin(const adouble &a);
122 ADOLC_API inline friend adouble cos(const adouble &a);
123 ADOLC_API inline friend adouble asin(const adouble &a);
124 ADOLC_API inline friend adouble acos(const adouble &a);
125 ADOLC_API inline friend adouble atan(const adouble &a);
126
127 ADOLC_API inline friend adouble atan2(const adouble &a, const adouble &b);
128 ADOLC_API inline friend adouble pow(const adouble &a, double v);
129 ADOLC_API inline friend adouble pow(const adouble &a, const adouble &b);
130 ADOLC_API inline friend adouble pow(double v, const adouble &a);
131 ADOLC_API inline friend adouble log10(const adouble &a);
132
133 ADOLC_API inline friend adouble sinh(const adouble &a);
134 ADOLC_API inline friend adouble cosh(const adouble &a);
135 ADOLC_API inline friend adouble tanh(const adouble &a);
136 ADOLC_API inline friend adouble asinh(const adouble &a);
137 ADOLC_API inline friend adouble acosh(const adouble &a);
138 ADOLC_API inline friend adouble atanh(const adouble &a);
139 ADOLC_API inline friend adouble fabs(const adouble &a);
140 ADOLC_API inline friend adouble ceil(const adouble &a);
141 ADOLC_API inline friend adouble floor(const adouble &a);
142 ADOLC_API inline friend adouble fmax(const adouble &a, const adouble &b);
143 ADOLC_API inline friend adouble fmax(double v, const adouble &a);
144 ADOLC_API inline friend adouble fmax(const adouble &a, double v);
145 ADOLC_API inline friend adouble fmin(const adouble &a, const adouble &b);
146 ADOLC_API inline friend adouble fmin(double v, const adouble &a);
147 ADOLC_API inline friend adouble fmin(const adouble &a, double v);
148 ADOLC_API inline friend adouble ldexp(const adouble &a, const adouble &b);
149 ADOLC_API inline friend adouble ldexp(const adouble &a, const double v);
150 ADOLC_API inline friend adouble ldexp(const double v, const adouble &a);
151 ADOLC_API inline friend double frexp(const adouble &a, int *v);
152 ADOLC_API inline friend adouble erf(const adouble &a);
153 ADOLC_API inline friend adouble erfc(const adouble &a);
154
155 ADOLC_API inline friend void condassign(adouble &res, const adouble &cond,
156 const adouble &arg1,
157 const adouble &arg2);
158 ADOLC_API inline friend void condassign(adouble &res, const adouble &cond,
159 const adouble &arg);
160 ADOLC_API inline friend void condeqassign(adouble &res, const adouble &cond,
161 const adouble &arg1,
162 const adouble &arg2);
163 ADOLC_API inline friend void condeqassign(adouble &res, const adouble &cond,
164 const adouble &arg);
165
166 /******************* nontemporary results ***************************/
167 // assignment
168 inline adouble &operator=(const double v);
169 inline adouble &operator=(const adouble &a);
170
171 // addition
172 inline adouble &operator+=(const double v);
173 inline adouble &operator+=(const adouble &a);
174
175 // subtraction
176 inline adouble &operator-=(const double v);
177 inline adouble &operator-=(const adouble &a);
178
179 // multiplication
180 inline adouble &operator*=(const double v);
181 inline adouble &operator*=(const adouble &a);
182
183 // division
184 inline adouble &operator/=(const double v);
185 inline adouble &operator/=(const adouble &a);
186
187 // not
188 inline bool operator!() const;
189
190 // comparison
191 inline bool operator!=(const adouble &) const;
192 inline bool operator!=(const double) const;
193 ADOLC_API inline friend bool operator!=(const double, const adouble &);
194
195 inline bool operator==(const adouble &) const;
196 inline bool operator==(const double) const;
197 ADOLC_API inline friend bool operator==(const double, const adouble &);
198
199 inline bool operator<=(const adouble &) const;
200 inline bool operator<=(const double) const;
201 ADOLC_API inline friend bool operator<=(const double, const adouble &);
202
203 inline bool operator>=(const adouble &) const;
204 inline bool operator>=(const double) const;
205 ADOLC_API inline friend bool operator>=(const double, const adouble &);
206
207 inline bool operator>(const adouble &) const;
208 inline bool operator>(const double) const;
209 ADOLC_API inline friend bool operator>(const double, const adouble &);
210
211 inline bool operator<(const adouble &) const;
212 inline bool operator<(const double) const;
213 ADOLC_API inline friend bool operator<(const double, const adouble &);
214
215 /******************* getter / setter ********************************/
216 inline double getValue() const;
217 inline void setValue(const double v);
218 inline double *getADValue() const;
219 inline void setADValue(const double *v);
220
221 inline double getADValue(size_t p) const;
222 inline void setADValue(size_t p, double v);
223 inline explicit operator double const &() const;
224 inline explicit operator double &&();
225 inline explicit operator double();
226
227public:
228 /******************* i/o operations *********************************/
229 friend ostream &operator<<(ostream &, const adouble &);
230 friend istream &operator>>(istream &, adouble &);
231
232private:
233#if USE_BOOST_POOL
234 ADOLC_API static boost::pool<boost::default_user_allocator_new_delete>
235 *advalpool;
236#endif
237 double *adval;
238#ifdef USE_ADTL_REFCOUNTING
239 refcounter __rcnt;
240#endif
241 ADOLC_API inline static size_t numDir = 1;
242 ADOLC_API inline friend void setNumDir(const size_t p);
243 ADOLC_API inline friend size_t getNumDir();
244};
245
246} // namespace adtl
247
248#include <cmath>
249#include <iostream>
250#include <limits>
251
252namespace adtl {
253
254ADOLC_API inline void setNumDir(const size_t p) {
255#ifdef USE_ADTL_REFCOUNTING
256 if (refcounter::refcnt > 0) {
257 fprintf(DIAG_OUT,
258 "ADOL-C Warning: Traceless: Setting numDir will not change the "
259 "number of\n directional derivative in existing adoubles and may "
260 "lead to erroneous results\n or memory corruption\n Number of "
261 "currently existing adoubles = %zu\n",
262 refcounter::refcnt);
263 }
264#endif
265
266 if (p < 1) {
267 fprintf(DIAG_OUT, "ADOL-C Error: Traceless: p < 1 not possible\n");
268 abort();
269 }
270 adouble::numDir = p;
271#if USE_BOOST_POOL
272 if (adouble::advalpool != NULL) {
273 delete adouble::advalpool;
274 adouble::advalpool = NULL;
275 }
276 adouble::advalpool =
277 new boost::pool<boost::default_user_allocator_new_delete>(
278 (adouble::numDir + 1) * sizeof(double));
279#endif
280}
281
282ADOLC_API inline size_t getNumDir() { return adouble::numDir; }
283
284ADOLC_API inline double makeNaN() {
285 return ADOLC_MATH_NSP::numeric_limits<double>::quiet_NaN();
286}
287
288ADOLC_API inline double makeInf() {
289 return ADOLC_MATH_NSP::numeric_limits<double>::infinity();
290}
291
292#define FOR_I_EQ_0_LTEQ_NUMDIR for (size_t _i = 0; _i <= adouble::numDir; ++_i)
293#define FOR_I_EQ_1_LTEQ_NUMDIR for (size_t _i = 1; _i <= adouble::numDir; ++_i)
294#define ADVAL_I adval[_i]
295#define PRIMAL_VALUE adval[0]
296
297/******************************* ctors ************************************/
298inline adouble::adouble() : adval(NULL) {
299#if USE_BOOST_POOL
300 adval = reinterpret_cast<double *>(advalpool->malloc());
301#else
302 adval = new double[adouble::numDir + 1];
303#endif
304 PRIMAL_VALUE = 0.;
305}
306
307inline adouble::adouble(const double v) : adval(NULL) {
308#if USE_BOOST_POOL
309 adval = reinterpret_cast<double *>(advalpool->malloc());
310#else
311 adval = new double[adouble::numDir + 1];
312#endif
313 PRIMAL_VALUE = v;
315 ADVAL_I = 0.0;
316}
317
318inline adouble::adouble(const double v, const double *adv) : adval(NULL) {
319#if USE_BOOST_POOL
320 adval = reinterpret_cast<double *>(advalpool->malloc());
321#else
322 adval = new double[adouble::numDir + 1];
323#endif
324 PRIMAL_VALUE = v;
326 ADVAL_I = adv[_i - 1];
327}
328
329inline adouble::adouble(const adouble &a) : adval(NULL) {
330#if USE_BOOST_POOL
331 adval = reinterpret_cast<double *>(advalpool->malloc());
332#else
333 adval = new double[adouble::numDir + 1];
334#endif
336 ADVAL_I = a.ADVAL_I;
337}
338
339/******************************* dtors ************************************/
341 if (adval != NULL)
342#if USE_BOOST_POOL
343 advalpool->free(adval);
344#else
345 delete[] adval;
346#endif
347}
348
349/************************* temporary results ******************************/
350// sign
352 adouble tmp;
354 tmp.ADVAL_I = -ADVAL_I;
355 return tmp;
356}
357
358inline adouble adouble::operator+() const { return *this; }
359
360// addition
361inline adouble adouble::operator+(const double v) const {
362 adouble tmp(PRIMAL_VALUE + v, adval + 1);
363 return tmp;
364}
365
366inline adouble adouble::operator+(const adouble &a) const {
367 adouble tmp;
369 tmp.ADVAL_I = ADVAL_I + a.ADVAL_I;
370 return tmp;
371}
372
373ADOLC_API inline adouble operator+(const double v, const adouble &a) {
374 adouble tmp(v + a.PRIMAL_VALUE, a.adval + 1);
375 return tmp;
376}
377
378// subtraction
379inline adouble adouble::operator-(const double v) const {
380 adouble tmp(PRIMAL_VALUE - v, adval + 1);
381 return tmp;
382}
383
384inline adouble adouble::operator-(const adouble &a) const {
385 adouble tmp;
387 tmp.ADVAL_I = ADVAL_I - a.ADVAL_I;
388 return tmp;
389}
390
391ADOLC_API inline adouble operator-(const double v, const adouble &a) {
392 adouble tmp;
393 tmp.PRIMAL_VALUE = v - a.PRIMAL_VALUE;
395 tmp.ADVAL_I = -a.ADVAL_I;
396 return tmp;
397}
398
399// multiplication
400inline adouble adouble::operator*(const double v) const {
401 adouble tmp;
403 tmp.ADVAL_I = ADVAL_I * v;
404 return tmp;
405}
406
407inline adouble adouble::operator*(const adouble &a) const {
408 adouble tmp;
409 tmp.PRIMAL_VALUE = PRIMAL_VALUE * a.PRIMAL_VALUE;
411 tmp.ADVAL_I = ADVAL_I * a.PRIMAL_VALUE + PRIMAL_VALUE * a.ADVAL_I;
412 return tmp;
413}
414
415ADOLC_API inline adouble operator*(const double v, const adouble &a) {
416 adouble tmp;
418 tmp.ADVAL_I = v * a.ADVAL_I;
419 return tmp;
420}
421
422// division
423inline adouble adouble::operator/(const double v) const {
424 adouble tmp;
426 tmp.ADVAL_I = ADVAL_I / v;
427 return tmp;
428}
429
430inline adouble adouble::operator/(const adouble &a) const {
431 adouble tmp;
432 tmp.PRIMAL_VALUE = PRIMAL_VALUE / a.PRIMAL_VALUE;
434 tmp.ADVAL_I = (ADVAL_I * a.PRIMAL_VALUE - PRIMAL_VALUE * a.ADVAL_I) /
435 (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
436 return tmp;
437}
438
439ADOLC_API inline adouble operator/(const double v, const adouble &a) {
440 adouble tmp;
441 tmp.PRIMAL_VALUE = v / a.PRIMAL_VALUE;
443 tmp.ADVAL_I = (-v * a.ADVAL_I) / (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
444 return tmp;
445}
446
447// inc/dec
449 ++PRIMAL_VALUE;
450 return *this;
451}
452
454 adouble tmp;
455 tmp.PRIMAL_VALUE = PRIMAL_VALUE++;
457 tmp.ADVAL_I = ADVAL_I;
458 return tmp;
459}
460
462 --PRIMAL_VALUE;
463 return *this;
464}
465
467 adouble tmp;
468 tmp.PRIMAL_VALUE = PRIMAL_VALUE--;
470 tmp.ADVAL_I = ADVAL_I;
471 return tmp;
472}
473
474// functions
475ADOLC_API inline adouble tan(const adouble &a) {
476 adouble tmp;
477 double tmp2;
478 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::tan(a.PRIMAL_VALUE);
479 tmp2 = ADOLC_MATH_NSP::cos(a.PRIMAL_VALUE);
480 tmp2 *= tmp2;
482 tmp.ADVAL_I = a.ADVAL_I / tmp2;
483 return tmp;
484}
485
486ADOLC_API inline adouble exp(const adouble &a) {
487 adouble tmp;
488 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::exp(a.PRIMAL_VALUE);
490 tmp.ADVAL_I = tmp.PRIMAL_VALUE * a.ADVAL_I;
491 return tmp;
492}
493
494ADOLC_API inline adouble log(const adouble &a) {
495 adouble tmp;
496 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::log(a.PRIMAL_VALUE);
498 if (a.PRIMAL_VALUE > 0)
499 tmp.ADVAL_I = a.ADVAL_I / a.PRIMAL_VALUE;
500 else if (a.PRIMAL_VALUE == 0 && a.ADVAL_I != 0.0) {
501 int sign = (a.ADVAL_I < 0) ? -1 : 1;
502 tmp.ADVAL_I = sign * makeInf();
503 } else
504 tmp.ADVAL_I = makeNaN();
505 return tmp;
506}
507
508ADOLC_API inline adouble sqrt(const adouble &a) {
509 adouble tmp;
510 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::sqrt(a.PRIMAL_VALUE);
512 if (a.PRIMAL_VALUE > 0)
513 tmp.ADVAL_I = a.ADVAL_I / (tmp.PRIMAL_VALUE * 2);
514 else if (a.PRIMAL_VALUE == 0.0 && a.ADVAL_I != 0.0) {
515 int sign = (a.ADVAL_I < 0) ? -1 : 1;
516 tmp.ADVAL_I = sign * makeInf();
517 } else
518 tmp.ADVAL_I = makeNaN();
519 return tmp;
520}
521
522ADOLC_API inline adouble cbrt(const adouble &a) {
523 adouble tmp;
524 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::cbrt(a.PRIMAL_VALUE);
526 if (a.PRIMAL_VALUE != 0.0)
527 tmp.ADVAL_I = a.ADVAL_I / (tmp.PRIMAL_VALUE * tmp.PRIMAL_VALUE * 3);
528 else if (a.PRIMAL_VALUE == 0.0 && a.ADVAL_I != 0.0) {
529 int sign = (a.ADVAL_I < 0) ? -1 : 1;
530 tmp.ADVAL_I = sign * makeInf();
531 } else
532 tmp.ADVAL_I = makeNaN();
533 return tmp;
534}
535
536ADOLC_API inline adouble sin(const adouble &a) {
537 adouble tmp;
538 double tmp2;
539 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::sin(a.PRIMAL_VALUE);
540 tmp2 = ADOLC_MATH_NSP::cos(a.PRIMAL_VALUE);
542 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
543 return tmp;
544}
545
546ADOLC_API inline adouble cos(const adouble &a) {
547 adouble tmp;
548 double tmp2;
549 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::cos(a.PRIMAL_VALUE);
550 tmp2 = -ADOLC_MATH_NSP::sin(a.PRIMAL_VALUE);
552 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
553 return tmp;
554}
555
556ADOLC_API inline adouble asin(const adouble &a) {
557 adouble tmp;
558 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::asin(a.PRIMAL_VALUE);
559 double tmp2 = ADOLC_MATH_NSP::sqrt(1 - a.PRIMAL_VALUE * a.PRIMAL_VALUE);
561 tmp.ADVAL_I = a.ADVAL_I / tmp2;
562 return tmp;
563}
564
565ADOLC_API inline adouble acos(const adouble &a) {
566 adouble tmp;
567 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::acos(a.PRIMAL_VALUE);
568 double tmp2 = -ADOLC_MATH_NSP::sqrt(1 - a.PRIMAL_VALUE * a.PRIMAL_VALUE);
570 tmp.ADVAL_I = a.ADVAL_I / tmp2;
571 return tmp;
572}
573
574ADOLC_API inline adouble atan(const adouble &a) {
575 adouble tmp;
576 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::atan(a.PRIMAL_VALUE);
577 double tmp2 = 1 + a.PRIMAL_VALUE * a.PRIMAL_VALUE;
578 tmp2 = 1 / tmp2;
579 if (tmp2 != 0)
581 tmp.ADVAL_I = a.ADVAL_I * tmp2;
582 else FOR_I_EQ_1_LTEQ_NUMDIR tmp.ADVAL_I = 0.0;
583 return tmp;
584}
585
586ADOLC_API inline adouble atan2(const adouble &a, const adouble &b) {
587 adouble tmp;
588 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::atan2(a.PRIMAL_VALUE, b.PRIMAL_VALUE);
589 double tmp2 = a.PRIMAL_VALUE * a.PRIMAL_VALUE;
590 double tmp3 = b.PRIMAL_VALUE * b.PRIMAL_VALUE;
591 double tmp4 = tmp3 / (tmp2 + tmp3);
592 if (tmp4 != 0)
594 tmp.ADVAL_I =
595 (a.ADVAL_I * b.PRIMAL_VALUE - a.PRIMAL_VALUE * b.ADVAL_I) / tmp3 * tmp4;
596 else FOR_I_EQ_1_LTEQ_NUMDIR tmp.ADVAL_I = 0.0;
597 return tmp;
598}
599
600ADOLC_API inline adouble pow(const adouble &a, double v) {
601 adouble tmp;
602 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::pow(a.PRIMAL_VALUE, v);
603 double tmp2 = v * ADOLC_MATH_NSP::pow(a.PRIMAL_VALUE, v - 1);
605 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
606 return tmp;
607}
608
609ADOLC_API inline adouble pow(const adouble &a, const adouble &b) {
610 adouble tmp;
611 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::pow(a.PRIMAL_VALUE, b.PRIMAL_VALUE);
612 double tmp2 =
613 b.PRIMAL_VALUE * ADOLC_MATH_NSP::pow(a.PRIMAL_VALUE, b.PRIMAL_VALUE - 1);
614 double tmp3 = ADOLC_MATH_NSP::log(a.PRIMAL_VALUE) * tmp.PRIMAL_VALUE;
616 tmp.ADVAL_I = tmp2 * a.ADVAL_I + tmp3 * b.ADVAL_I;
617 return tmp;
618}
619
620ADOLC_API inline adouble pow(double v, const adouble &a) {
621 adouble tmp;
622 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::pow(v, a.PRIMAL_VALUE);
623 double tmp2 = tmp.PRIMAL_VALUE * ADOLC_MATH_NSP::log(v);
625 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
626 return tmp;
627}
628
629ADOLC_API inline adouble log10(const adouble &a) {
630 adouble tmp;
631 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::log10(a.PRIMAL_VALUE);
632 double tmp2 = ADOLC_MATH_NSP::log((double)10) * a.PRIMAL_VALUE;
634 tmp.ADVAL_I = a.ADVAL_I / tmp2;
635 return tmp;
636}
637
638ADOLC_API inline adouble sinh(const adouble &a) {
639 adouble tmp;
640 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::sinh(a.PRIMAL_VALUE);
641 double tmp2 = ADOLC_MATH_NSP::cosh(a.PRIMAL_VALUE);
643 tmp.ADVAL_I = a.ADVAL_I * tmp2;
644 return tmp;
645}
646
647ADOLC_API inline adouble cosh(const adouble &a) {
648 adouble tmp;
649 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::cosh(a.PRIMAL_VALUE);
650 double tmp2 = ADOLC_MATH_NSP::sinh(a.PRIMAL_VALUE);
652 tmp.ADVAL_I = a.ADVAL_I * tmp2;
653 return tmp;
654}
655
656ADOLC_API inline adouble tanh(const adouble &a) {
657 adouble tmp;
658 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::tanh(a.PRIMAL_VALUE);
659 double tmp2 = ADOLC_MATH_NSP::cosh(a.PRIMAL_VALUE);
660 tmp2 *= tmp2;
662 tmp.ADVAL_I = a.ADVAL_I / tmp2;
663 return tmp;
664}
665
666ADOLC_API inline adouble asinh(const adouble &a) {
667 adouble tmp;
668 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP_ERF::asinh(a.PRIMAL_VALUE);
669 double tmp2 = ADOLC_MATH_NSP::sqrt(a.PRIMAL_VALUE * a.PRIMAL_VALUE + 1);
671 tmp.ADVAL_I = a.ADVAL_I / tmp2;
672 return tmp;
673}
674
675ADOLC_API inline adouble acosh(const adouble &a) {
676 adouble tmp;
677 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP_ERF::acosh(a.PRIMAL_VALUE);
678 double tmp2 = ADOLC_MATH_NSP::sqrt(a.PRIMAL_VALUE * a.PRIMAL_VALUE - 1);
680 tmp.ADVAL_I = a.ADVAL_I / tmp2;
681 return tmp;
682}
683
684ADOLC_API inline adouble atanh(const adouble &a) {
685 adouble tmp;
686 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP_ERF::atanh(a.PRIMAL_VALUE);
687 double tmp2 = 1 - a.PRIMAL_VALUE * a.PRIMAL_VALUE;
689 tmp.ADVAL_I = a.ADVAL_I / tmp2;
690 return tmp;
691}
692
693ADOLC_API inline adouble fabs(const adouble &a) {
694 adouble tmp;
695 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::fabs(a.PRIMAL_VALUE);
696 int as = 0;
697 if (a.PRIMAL_VALUE > 0)
698 as = 1;
699 if (a.PRIMAL_VALUE < 0)
700 as = -1;
701 if (as != 0)
703 tmp.ADVAL_I = a.ADVAL_I * as;
705 as = 0;
706 if (a.ADVAL_I > 0)
707 as = 1;
708 if (a.ADVAL_I < 0)
709 as = -1;
710 tmp.ADVAL_I = a.ADVAL_I * as;
711 }
712 return tmp;
713}
714
715ADOLC_API inline adouble ceil(const adouble &a) {
716 adouble tmp;
717 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::ceil(a.PRIMAL_VALUE);
719 tmp.ADVAL_I = 0.0;
720 return tmp;
721}
722
723ADOLC_API inline adouble floor(const adouble &a) {
724 adouble tmp;
725 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::floor(a.PRIMAL_VALUE);
727 tmp.ADVAL_I = 0.0;
728 return tmp;
729}
730
731ADOLC_API inline adouble fmax(const adouble &a, const adouble &b) {
732 adouble tmp;
733 double tmp2 = a.PRIMAL_VALUE - b.PRIMAL_VALUE;
734 if (tmp2 < 0) {
735 tmp.PRIMAL_VALUE = b.PRIMAL_VALUE;
737 tmp.ADVAL_I = b.ADVAL_I;
738 } else {
739 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
740 if (tmp2 > 0) {
742 tmp.ADVAL_I = a.ADVAL_I;
743 } else {
745 if (a.ADVAL_I < b.ADVAL_I)
746 tmp.ADVAL_I = b.ADVAL_I;
747 else
748 tmp.ADVAL_I = a.ADVAL_I;
749 }
750 }
751 }
752 return tmp;
753}
754
755ADOLC_API inline adouble fmax(double v, const adouble &a) {
756 adouble tmp;
757 double tmp2 = v - a.PRIMAL_VALUE;
758 if (tmp2 < 0) {
759 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
761 tmp.ADVAL_I = a.ADVAL_I;
762 } else {
763 tmp.PRIMAL_VALUE = v;
764 if (tmp2 > 0) {
766 tmp.ADVAL_I = 0.0;
767 } else {
769 if (a.ADVAL_I > 0)
770 tmp.ADVAL_I = a.ADVAL_I;
771 else
772 tmp.ADVAL_I = 0.0;
773 }
774 }
775 }
776 return tmp;
777}
778
779ADOLC_API inline adouble fmax(const adouble &a, double v) {
780 adouble tmp;
781 double tmp2 = a.PRIMAL_VALUE - v;
782 if (tmp2 < 0) {
783 tmp.PRIMAL_VALUE = v;
785 tmp.ADVAL_I = 0.0;
786 } else {
787 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
788 if (tmp2 > 0) {
790 tmp.ADVAL_I = a.ADVAL_I;
791 } else {
793 if (a.ADVAL_I > 0)
794 tmp.ADVAL_I = a.ADVAL_I;
795 else
796 tmp.ADVAL_I = 0.0;
797 }
798 }
799 }
800 return tmp;
801}
802
803ADOLC_API inline adouble fmin(const adouble &a, const adouble &b) {
804 adouble tmp;
805 double tmp2 = a.PRIMAL_VALUE - b.PRIMAL_VALUE;
806 if (tmp2 < 0) {
807 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
809 tmp.ADVAL_I = a.ADVAL_I;
810 } else {
811 tmp.PRIMAL_VALUE = b.PRIMAL_VALUE;
812 if (tmp2 > 0) {
814 tmp.ADVAL_I = b.ADVAL_I;
815 } else {
817 if (a.ADVAL_I < b.ADVAL_I)
818 tmp.ADVAL_I = a.ADVAL_I;
819 else
820 tmp.ADVAL_I = b.ADVAL_I;
821 }
822 }
823 }
824 return tmp;
825}
826
827ADOLC_API inline adouble fmin(double v, const adouble &a) {
828 adouble tmp;
829 double tmp2 = v - a.PRIMAL_VALUE;
830 if (tmp2 < 0) {
831 tmp.PRIMAL_VALUE = v;
833 tmp.ADVAL_I = 0.0;
834 } else {
835 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
836 if (tmp2 > 0) {
838 tmp.ADVAL_I = a.ADVAL_I;
839 } else {
841 if (a.ADVAL_I < 0)
842 tmp.ADVAL_I = a.ADVAL_I;
843 else
844 tmp.ADVAL_I = 0.0;
845 }
846 }
847 }
848 return tmp;
849}
850
851ADOLC_API inline adouble fmin(const adouble &a, double v) {
852 adouble tmp;
853 double tmp2 = a.PRIMAL_VALUE - v;
854 if (tmp2 < 0) {
855 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
857 tmp.ADVAL_I = a.ADVAL_I;
858 } else {
859 tmp.PRIMAL_VALUE = v;
860 if (tmp2 > 0) {
862 tmp.ADVAL_I = 0.0;
863 } else {
865 if (a.ADVAL_I < 0)
866 tmp.ADVAL_I = a.ADVAL_I;
867 else
868 tmp.ADVAL_I = 0.0;
869 }
870 }
871 }
872 return tmp;
873}
874
875ADOLC_API inline adouble ldexp(const adouble &a, const adouble &b) {
876 adouble tmp = a * pow(2., b);
877 return tmp;
878}
879
880ADOLC_API inline adouble ldexp(const adouble &a, const double v) {
881 return a * ADOLC_MATH_NSP::pow(2., v);
882}
883
884ADOLC_API inline adouble ldexp(const double v, const adouble &a) {
885 adouble tmp = v * pow(2., a);
886 return tmp;
887}
888
889ADOLC_API inline double frexp(const adouble &a, int *v) {
890 return ADOLC_MATH_NSP::frexp(a.PRIMAL_VALUE, v);
891}
892
893ADOLC_API inline adouble erf(const adouble &a) {
894 adouble tmp;
895 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP_ERF::erf(a.PRIMAL_VALUE);
896 double tmp2 = 2.0 / ADOLC_MATH_NSP_ERF::sqrt(ADOLC_MATH_NSP::acos(-1.0)) *
897 ADOLC_MATH_NSP_ERF::exp(-a.PRIMAL_VALUE * a.PRIMAL_VALUE);
899 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
900 return tmp;
901}
902
903ADOLC_API inline adouble erfc(const adouble &a) {
904 adouble tmp;
905 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP_ERF::erfc(a.PRIMAL_VALUE);
906 double tmp2 = -2.0 / ADOLC_MATH_NSP_ERF::sqrt(ADOLC_MATH_NSP::acos(-1.0)) *
907 ADOLC_MATH_NSP_ERF::exp(-a.PRIMAL_VALUE * a.PRIMAL_VALUE);
909 tmp.ADVAL_I = tmp2 * a.ADVAL_I;
910 return tmp;
911}
912
913ADOLC_API inline void condassign(adouble &res, const adouble &cond,
914 const adouble &arg1, const adouble &arg2) {
915 if (cond.getValue() > 0)
916 res = arg1;
917 else
918 res = arg2;
919}
920
921ADOLC_API inline void condassign(adouble &res, const adouble &cond,
922 const adouble &arg) {
923 if (cond.getValue() > 0)
924 res = arg;
925}
926
927ADOLC_API inline void condeqassign(adouble &res, const adouble &cond,
928 const adouble &arg1, const adouble &arg2) {
929 if (cond.getValue() >= 0)
930 res = arg1;
931 else
932 res = arg2;
933}
934
935ADOLC_API inline void condeqassign(adouble &res, const adouble &cond,
936 const adouble &arg) {
937 if (cond.getValue() >= 0)
938 res = arg;
939}
940
941/******************* nontemporary results *********************************/
942inline adouble &adouble::operator=(const double v) {
943 PRIMAL_VALUE = v;
945 ADVAL_I = 0.0;
946 return *this;
947}
948
951 ADVAL_I = a.ADVAL_I;
952 return *this;
953}
954
955inline adouble &adouble::operator+=(const double v) {
956 PRIMAL_VALUE += v;
957 return *this;
958}
959
962 ADVAL_I += a.ADVAL_I;
963 return *this;
964}
965
966inline adouble &adouble::operator-=(const double v) {
967 PRIMAL_VALUE -= v;
968 return *this;
969}
970
973 ADVAL_I -= a.ADVAL_I;
974 return *this;
975}
976
977inline adouble &adouble::operator*=(const double v) {
979 ADVAL_I *= v;
980 return *this;
981}
982
985 ADVAL_I = ADVAL_I * a.PRIMAL_VALUE + PRIMAL_VALUE * a.ADVAL_I;
986 PRIMAL_VALUE *= a.PRIMAL_VALUE;
987 return *this;
988}
989
990inline adouble &adouble::operator/=(const double v) {
992 ADVAL_I /= v;
993 return *this;
994}
995
998 ADVAL_I = (ADVAL_I * a.PRIMAL_VALUE - PRIMAL_VALUE * a.ADVAL_I) /
999 (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
1000 PRIMAL_VALUE = PRIMAL_VALUE / a.PRIMAL_VALUE;
1001 return *this;
1002}
1003
1004// not
1005inline bool adouble::operator!() const { return PRIMAL_VALUE == 0.0; }
1006
1007// comparison
1008inline bool adouble::operator!=(const adouble &a) const {
1009 return PRIMAL_VALUE != a.PRIMAL_VALUE;
1010}
1011
1012inline bool adouble::operator!=(const double v) const {
1013 return PRIMAL_VALUE != v;
1014}
1015
1016ADOLC_API inline bool operator!=(const double v, const adouble &a) {
1017 return v != a.PRIMAL_VALUE;
1018}
1019
1020inline bool adouble::operator==(const adouble &a) const {
1021 return PRIMAL_VALUE == a.PRIMAL_VALUE;
1022}
1023
1024inline bool adouble::operator==(const double v) const {
1025 return PRIMAL_VALUE == v;
1026}
1027
1028ADOLC_API inline bool operator==(const double v, const adouble &a) {
1029 return v == a.PRIMAL_VALUE;
1030}
1031
1032inline bool adouble::operator<=(const adouble &a) const {
1033 return PRIMAL_VALUE <= a.PRIMAL_VALUE;
1034}
1035
1036inline bool adouble::operator<=(const double v) const {
1037 return PRIMAL_VALUE <= v;
1038}
1039
1040ADOLC_API inline bool operator<=(const double v, const adouble &a) {
1041 return v <= a.PRIMAL_VALUE;
1042}
1043
1044inline bool adouble::operator>=(const adouble &a) const {
1045 return PRIMAL_VALUE >= a.PRIMAL_VALUE;
1046}
1047
1048inline bool adouble::operator>=(const double v) const {
1049 return PRIMAL_VALUE >= v;
1050}
1051
1052ADOLC_API inline bool operator>=(const double v, const adouble &a) {
1053 return v >= a.PRIMAL_VALUE;
1054}
1055
1056inline bool adouble::operator>(const adouble &a) const {
1057 return PRIMAL_VALUE > a.PRIMAL_VALUE;
1058}
1059
1060inline bool adouble::operator>(const double v) const {
1061 return PRIMAL_VALUE > v;
1062}
1063
1064ADOLC_API inline bool operator>(const double v, const adouble &a) {
1065 return v > a.PRIMAL_VALUE;
1066}
1067
1068inline bool adouble::operator<(const adouble &a) const {
1069 return PRIMAL_VALUE < a.PRIMAL_VALUE;
1070}
1071
1072inline bool adouble::operator<(const double v) const {
1073 return PRIMAL_VALUE < v;
1074}
1075
1076ADOLC_API inline bool operator<(const double v, const adouble &a) {
1077 return v < a.PRIMAL_VALUE;
1078}
1079
1080/******************* getter / setter **************************************/
1081inline adouble::operator double const &() const { return PRIMAL_VALUE; }
1082
1083inline adouble::operator double &&() { return (double &&)PRIMAL_VALUE; }
1084
1085inline adouble::operator double() { return PRIMAL_VALUE; }
1086
1087inline double adouble::getValue() const { return PRIMAL_VALUE; }
1088
1089inline void adouble::setValue(const double v) { PRIMAL_VALUE = v; }
1090
1091inline double *adouble::getADValue() const { return (adval + 1); }
1092
1093inline void adouble::setADValue(const double *const v) {
1095 ADVAL_I = v[_i - 1];
1096}
1097
1098inline double adouble::getADValue(size_t p) const {
1099 if (p >= adouble::numDir) {
1100 fprintf(DIAG_OUT, "Derivative array accessed out of bounds"
1101 " while \"getADValue(...)\"!!!\n");
1102 throw logic_error("incorrect function call, errorcode=-1");
1103 }
1104 return adval[p + 1];
1105}
1106
1107inline void adouble::setADValue(size_t p, double v) {
1108 if (p >= adouble::numDir) {
1109 fprintf(DIAG_OUT, "Derivative array accessed out of bounds"
1110 " while \"setADValue(...)\"!!!\n");
1111 throw logic_error("incorrect function call, errorcode=-1");
1112 }
1113 adval[p + 1] = v;
1114}
1115
1116} // namespace adtl
1117#endif
#define ADOLC_API
Definition adolcexport.h:16
#define ADVAL_I
Definition adoublecuda.h:51
ADOLC_API void condeqassign(adouble &res, const adouble &cond, const adouble &arg1, const adouble &arg2)
ADOLC_API void condassign(adouble &res, const adouble &cond, const adouble &arg1, const adouble &arg2)
ADOLC_API adouble cbrt(const adouble &a)
#define PRIMAL_VALUE
Definition adtl.h:295
#define FOR_I_EQ_1_LTEQ_NUMDIR
Definition adtl.h:293
#define FOR_I_EQ_0_LTEQ_NUMDIR
Definition adtl.h:292
Active scalar for tapeless first-order forward differentiation.
Definition adtl.h:77
ADOLC_API friend adouble erf(const adouble &a)
Definition adtl.h:893
ADOLC_API friend void setNumDir(const size_t p)
Definition adtl.h:254
ADOLC_API friend adouble floor(const adouble &a)
Definition adtl.h:723
bool operator!() const
Definition adtl.h:1005
ADOLC_API friend adouble atanh(const adouble &a)
Definition adtl.h:684
ADOLC_API friend adouble sin(const adouble &a)
Definition adtl.h:536
ADOLC_API friend adouble pow(const adouble &a, double v)
Definition adtl.h:600
~adouble()
Definition adtl.h:340
ADOLC_API friend adouble log10(const adouble &a)
Definition adtl.h:629
ADOLC_API friend bool operator!=(const double, const adouble &)
Definition adtl.h:1016
adouble operator-() const
Definition adtl.h:351
ADOLC_API friend adouble operator*(const double v, const adouble &a)
Definition adtl.h:415
adouble operator++()
Definition adtl.h:448
ADOLC_API friend adouble cos(const adouble &a)
Definition adtl.h:546
ADOLC_API friend bool operator<(const double, const adouble &)
Definition adtl.h:1076
ADOLC_API friend adouble cbrt(const adouble &a)
Definition adtl.h:522
ADOLC_API friend adouble erfc(const adouble &a)
Definition adtl.h:903
adouble & operator-=(const double v)
Definition adtl.h:966
ADOLC_API friend double frexp(const adouble &a, int *v)
Definition adtl.h:889
ADOLC_API friend bool operator>=(const double, const adouble &)
Definition adtl.h:1052
void setValue(const double v)
Definition adtl.h:1089
adouble & operator=(const double v)
Definition adtl.h:942
ADOLC_API friend void condeqassign(adouble &res, const adouble &cond, const adouble &arg1, const adouble &arg2)
Definition adtl.h:927
ADOLC_API friend size_t getNumDir()
Definition adtl.h:282
ADOLC_API friend bool operator==(const double, const adouble &)
Definition adtl.h:1028
adouble & operator/=(const double v)
Definition adtl.h:990
ADOLC_API friend adouble exp(const adouble &a)
Definition adtl.h:486
friend ostream & operator<<(ostream &, const adouble &)
ADOLC_API friend adouble tanh(const adouble &a)
Definition adtl.h:656
ADOLC_API friend adouble operator/(const double v, const adouble &a)
Definition adtl.h:439
ADOLC_API friend adouble asin(const adouble &a)
Definition adtl.h:556
double getValue() const
Definition adtl.h:1087
double * getADValue() const
Definition adtl.h:1091
ADOLC_API friend adouble acos(const adouble &a)
Definition adtl.h:565
ADOLC_API friend void condassign(adouble &res, const adouble &cond, const adouble &arg1, const adouble &arg2)
Definition adtl.h:913
adouble & operator*=(const double v)
Definition adtl.h:977
adouble()
Definition adtl.h:298
void setADValue(const double *v)
Definition adtl.h:1093
ADOLC_API friend adouble fabs(const adouble &a)
Definition adtl.h:693
adouble operator--()
Definition adtl.h:461
ADOLC_API friend adouble cosh(const adouble &a)
Definition adtl.h:647
ADOLC_API friend adouble fmin(const adouble &a, const adouble &b)
Definition adtl.h:803
ADOLC_API friend bool operator>(const double, const adouble &)
Definition adtl.h:1064
ADOLC_API friend adouble log(const adouble &a)
Definition adtl.h:494
ADOLC_API friend adouble atan2(const adouble &a, const adouble &b)
Definition adtl.h:586
adouble operator+() const
Definition adtl.h:358
ADOLC_API friend adouble tan(const adouble &a)
Definition adtl.h:475
ADOLC_API friend adouble sinh(const adouble &a)
Definition adtl.h:638
ADOLC_API friend adouble fmax(const adouble &a, const adouble &b)
Definition adtl.h:731
ADOLC_API friend adouble atan(const adouble &a)
Definition adtl.h:574
ADOLC_API friend adouble sqrt(const adouble &a)
Definition adtl.h:508
adouble & operator+=(const double v)
Definition adtl.h:955
friend istream & operator>>(istream &, adouble &)
ADOLC_API friend adouble asinh(const adouble &a)
Definition adtl.h:666
ADOLC_API friend bool operator<=(const double, const adouble &)
Definition adtl.h:1040
ADOLC_API friend adouble ceil(const adouble &a)
Definition adtl.h:715
ADOLC_API friend adouble acosh(const adouble &a)
Definition adtl.h:675
ADOLC_API friend adouble ldexp(const adouble &a, const adouble &b)
Definition adtl.h:875
Definition adtl.h:35
ADOLC_API double makeInf()
Definition adtl.h:288
ADOLC_API double makeNaN()
Definition adtl.h:284
#define DIAG_OUT
Definition usrparms.h:52