27#include <boost/pool/pool_alloc.hpp>
32using std::logic_error;
40#ifdef USE_ADTL_REFCOUNTING
52 ADOLC_API friend void setNumDir(
const size_t p);
56 refcounter() { ++refcnt; }
57 ~refcounter() { --refcnt; }
58 ADOLC_API inline static size_t getNumLiveVar() {
return refcnt; }
81 inline adouble(
const double v,
const double *adv);
208 inline bool operator>(
const double)
const;
212 inline bool operator<(
const double)
const;
217 inline void setValue(
const double v);
223 inline explicit operator double const &()
const;
224 inline explicit operator double &&();
225 inline explicit operator double();
234 ADOLC_API static boost::pool<boost::default_user_allocator_new_delete>
238#ifdef USE_ADTL_REFCOUNTING
241 ADOLC_API inline static size_t numDir = 1;
255#ifdef USE_ADTL_REFCOUNTING
256 if (refcounter::refcnt > 0) {
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",
267 fprintf(
DIAG_OUT,
"ADOL-C Error: Traceless: p < 1 not possible\n");
272 if (adouble::advalpool != NULL) {
273 delete adouble::advalpool;
274 adouble::advalpool = NULL;
277 new boost::pool<boost::default_user_allocator_new_delete>(
278 (adouble::numDir + 1) *
sizeof(
double));
282ADOLC_API inline size_t getNumDir() {
return adouble::numDir; }
285 return ADOLC_MATH_NSP::numeric_limits<double>::quiet_NaN();
289 return ADOLC_MATH_NSP::numeric_limits<double>::infinity();
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]
300 adval =
reinterpret_cast<double *
>(advalpool->malloc());
302 adval =
new double[adouble::numDir + 1];
309 adval =
reinterpret_cast<double *
>(advalpool->malloc());
311 adval =
new double[adouble::numDir + 1];
320 adval =
reinterpret_cast<double *
>(advalpool->malloc());
322 adval =
new double[adouble::numDir + 1];
331 adval =
reinterpret_cast<double *
>(advalpool->malloc());
333 adval =
new double[adouble::numDir + 1];
343 advalpool->free(adval);
369 tmp.ADVAL_I =
ADVAL_I + a.ADVAL_I;
374 adouble tmp(v + a.PRIMAL_VALUE, a.adval + 1);
387 tmp.ADVAL_I =
ADVAL_I - a.ADVAL_I;
393 tmp.PRIMAL_VALUE = v - a.PRIMAL_VALUE;
395 tmp.ADVAL_I = -a.ADVAL_I;
418 tmp.ADVAL_I = v * a.ADVAL_I;
435 (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
441 tmp.PRIMAL_VALUE = v / a.PRIMAL_VALUE;
443 tmp.ADVAL_I = (-v * a.ADVAL_I) / (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
478 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::tan(a.PRIMAL_VALUE);
479 tmp2 = ADOLC_MATH_NSP::cos(a.PRIMAL_VALUE);
482 tmp.ADVAL_I = a.ADVAL_I / tmp2;
488 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::exp(a.PRIMAL_VALUE);
490 tmp.ADVAL_I = tmp.PRIMAL_VALUE * a.ADVAL_I;
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();
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();
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();
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;
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;
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;
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;
576 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::atan(a.PRIMAL_VALUE);
577 double tmp2 = 1 + a.PRIMAL_VALUE * a.PRIMAL_VALUE;
581 tmp.ADVAL_I = a.ADVAL_I * tmp2;
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);
595 (a.ADVAL_I * b.PRIMAL_VALUE - a.PRIMAL_VALUE * b.ADVAL_I) / tmp3 * tmp4;
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;
611 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::pow(a.PRIMAL_VALUE, b.PRIMAL_VALUE);
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;
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;
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;
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;
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;
658 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::tanh(a.PRIMAL_VALUE);
659 double tmp2 = ADOLC_MATH_NSP::cosh(a.PRIMAL_VALUE);
662 tmp.ADVAL_I = a.ADVAL_I / tmp2;
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;
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;
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;
695 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::fabs(a.PRIMAL_VALUE);
697 if (a.PRIMAL_VALUE > 0)
699 if (a.PRIMAL_VALUE < 0)
703 tmp.ADVAL_I = a.ADVAL_I * as;
710 tmp.ADVAL_I = a.ADVAL_I * as;
717 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::ceil(a.PRIMAL_VALUE);
725 tmp.PRIMAL_VALUE = ADOLC_MATH_NSP::floor(a.PRIMAL_VALUE);
733 double tmp2 = a.PRIMAL_VALUE - b.PRIMAL_VALUE;
735 tmp.PRIMAL_VALUE = b.PRIMAL_VALUE;
737 tmp.ADVAL_I = b.ADVAL_I;
739 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
742 tmp.ADVAL_I = a.ADVAL_I;
745 if (a.ADVAL_I < b.ADVAL_I)
746 tmp.ADVAL_I = b.ADVAL_I;
748 tmp.ADVAL_I = a.ADVAL_I;
757 double tmp2 = v - a.PRIMAL_VALUE;
759 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
761 tmp.ADVAL_I = a.ADVAL_I;
763 tmp.PRIMAL_VALUE = v;
770 tmp.ADVAL_I = a.ADVAL_I;
781 double tmp2 = a.PRIMAL_VALUE - v;
783 tmp.PRIMAL_VALUE = v;
787 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
790 tmp.ADVAL_I = a.ADVAL_I;
794 tmp.ADVAL_I = a.ADVAL_I;
805 double tmp2 = a.PRIMAL_VALUE - b.PRIMAL_VALUE;
807 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
809 tmp.ADVAL_I = a.ADVAL_I;
811 tmp.PRIMAL_VALUE = b.PRIMAL_VALUE;
814 tmp.ADVAL_I = b.ADVAL_I;
817 if (a.ADVAL_I < b.ADVAL_I)
818 tmp.ADVAL_I = a.ADVAL_I;
820 tmp.ADVAL_I = b.ADVAL_I;
829 double tmp2 = v - a.PRIMAL_VALUE;
831 tmp.PRIMAL_VALUE = v;
835 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
838 tmp.ADVAL_I = a.ADVAL_I;
842 tmp.ADVAL_I = a.ADVAL_I;
853 double tmp2 = a.PRIMAL_VALUE - v;
855 tmp.PRIMAL_VALUE = a.PRIMAL_VALUE;
857 tmp.ADVAL_I = a.ADVAL_I;
859 tmp.PRIMAL_VALUE = v;
866 tmp.ADVAL_I = a.ADVAL_I;
881 return a * ADOLC_MATH_NSP::pow(2., v);
890 return ADOLC_MATH_NSP::frexp(a.PRIMAL_VALUE, v);
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;
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;
999 (a.PRIMAL_VALUE * a.PRIMAL_VALUE);
1017 return v != a.PRIMAL_VALUE;
1029 return v == a.PRIMAL_VALUE;
1041 return v <= a.PRIMAL_VALUE;
1053 return v >= a.PRIMAL_VALUE;
1065 return v > a.PRIMAL_VALUE;
1077 return v < a.PRIMAL_VALUE;
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");
1104 return adval[p + 1];
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");
#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
ADOLC_API double makeInf()
Definition adtl.h:288
ADOLC_API double makeNaN()
Definition adtl.h:284
#define DIAG_OUT
Definition usrparms.h:52