22 #if defined(RAD_DEBUG_BLOCKKEEP) && !defined(HAVE_SACADO_UNINIT)
23 #undef RAD_DEBUG_BLOCKKEEP
34 #undef RAD_ALLOW_WANTDERIV
35 #ifndef RAD_DISALLOW_WANTDERIV
36 #define RAD_ALLOW_WANTDERIV
42 #define RAD_REINIT_0(x)
43 #define RAD_REINIT_1(x)
44 #define RAD_REINIT_2(x)
47 #if RAD_REINIT == 1 //{{
49 #define RAD_REINIT_1(x) x
50 #ifdef RAD_ALLOW_WANTDERIV
51 #define ADvar ADvar_1n
52 #define IndepADvar IndepADvar_1n
55 #define IndepADvar IndepADvar_1
56 #endif //RAD_ALLOW_WANTDERIV
57 #elif RAD_REINIT == 2 //}{
59 #define RAD_REINIT_2(x) x
61 #define RAD_cvchk(x) if (x.gen != x.IndepADvar_root.gen) { x.cv = new ADvari<Double>(x.Val);\
62 x.gen = x.IndepADvar_root.gen; }
63 #ifdef RAD_ALLOW_WANTDERIV
64 #define IndepADvar IndepADvar_2n
65 #define ADvar ADvar_2n
67 #define IndepADvar IndepADvar_2
69 #endif //RAD_ALLOW_WANTDERIV
70 #elif RAD_REINIT != 0 //}{
71 Botch! Expected
"RAD_REINIT" to be 0, 1, or 2.
74 #undef RAD_ALLOW_WANTDERIV
76 #define RAD_REINIT_0(x) x
79 #ifdef RAD_ALLOW_WANTDERIV
80 #define Allow_noderiv(x) x
82 #define Allow_noderiv(x)
87 #undef RAD_AUTO_AD_Const
88 #undef RAD_DEBUG_BLOCKKEEP
94 #ifdef RAD_Const_WARN // ==> RAD_AUTO_AD_Const and RAD_DEBUG
95 #ifndef RAD_AUTO_AD_Const
96 #define RAD_AUTO_AD_Const
103 #endif // RAD_Const_WARN
110 #ifndef RAD_AUTO_AD_Const
111 #ifdef RAD_DEBUG_BLOCKKEEP
119 #ifdef RAD_AUTO_AD_Const
120 #undef RAD_DEBUG_BLOCKKEEP
122 #ifdef RAD_DEBUG_BLOCKKEEP
123 #if !(RAD_DEBUG_BLOCKKEEP > 0)
124 #undef RAD_DEBUG_BLOCKKEEP
126 extern "C" void _uninit_f2c(
void *
x,
int type,
long len);
128 template <
typename T>
129 struct UninitType {};
132 struct UninitType<float> {
133 static const int utype = 4;
137 struct UninitType<double> {
138 static const int utype = 5;
141 template <
typename T>
142 struct UninitType< std::complex<T> > {
143 static const int utype = UninitType<T>::utype + 2;
152 template<
typename T>
class
185 #define Dtype typename DoubleAvoid<Double>::dtype
186 #define Ltype typename DoubleAvoid<Double>::ltype
187 #define Itype typename DoubleAvoid<Double>::itype
188 #define Ttype typename DoubleAvoid<Double>::ttype
193 template<
typename Double>
class ADvar;
200 template<
typename Double>
class Derp;
202 template<
typename Double>
struct
207 char memblk[1000*
sizeof(double)];
210 template<
typename Double>
class
217 ADMemblock *Busy, *First, *
Free;
222 ADMemblock *DBusy, *DFree;
223 size_t DMleft, nderps;
225 #ifdef RAD_DEBUG_BLOCKKEEP
227 ADMemblock *rad_Oldcurmb;
229 void *new_ADmemblock(
size_t);
234 void *Memalloc(
size_t len);
235 static void Gradcomp(
int wantgrad);
237 static void aval_reset();
238 static void free_all();
239 static void re_init();
240 static void zero_out();
241 static void Weighted_Gradcomp(
size_t, ADVar**,
Double*);
242 static void Outvar_Gradcomp(ADVar&);
244 DErp *new_Derp(
const Double *,
const ADVari*,
const ADVari*);
250 template<
typename Double>
class
260 template<
typename Double>
class
267 inline void *
operator new(size_t,
Derp *
x) {
return x; }
268 inline void operator delete(
void*,
Derp *) {}
277 Derp(
const ADVari *);
279 Derp(
const Double *,
const ADVari *,
const ADVari *);
280 inline void *
operator new(
size_t len) {
return (
Derp*)ADVari::adc.Memalloc(len); }
284 #if RAD_REINIT > 0 //{
285 template<
typename Double> Derp<Double>*
286 ADcontext<Double>::new_Derp(
const Double *
a,
const ADvari<Double> *b,
const ADvari<Double> *
c)
291 if (this->DMleft == 0) {
298 this->DMleft = nderps;
300 rv = &((DErp*)DBusy->
memblk)[--this->DMleft];
308 #define Ai const Base< ADvari<Double> >&
309 #define AI const Base< IndepADvar<Double> >&
310 #define T template<typename Double>
337 #define F ADvari<Double>&
385 template<
typename Double>ADvari<Double>&
ADf1(
Double f,
Double g,
const IndepADvar<Double> &x);
387 const IndepADvar<Double> &x,
const IndepADvar<Double> &
y);
388 template<
typename Double>ADvari<Double>&
ADfn(
Double f,
int n,
389 const IndepADvar<Double> *x,
const Double *g);
391 template<
typename Double> IndepADvar<Double>&
ADvar_operatoreq(IndepADvar<Double>*,
392 const ADvari<Double>&);
393 template<
typename Double> ADvar<Double>&
ADvar_operatoreq(ADvar<Double>*,
const ADvari<Double>&);
394 template<
typename Double>
void AD_Const(
const IndepADvar<Double>&);
395 template<
typename Double>
void AD_Const1(
Double*,
const IndepADvar<Double>&);
396 template<
typename Double> ADvari<Double>&
ADf1(
Double,
Double,
const ADvari<Double>&);
398 const ADvari<Double>&,
const ADvari<Double>&);
400 const IndepADvar<Double>&,
const ADvari<Double>&);
402 const ADvari<Double>&,
const IndepADvar<Double>&);
403 template<
typename Double>
Double val(
const ADvari<Double>&);
405 template<
typename Double>
class
406 ADvari :
public Base< ADvari<Double> > {
411 #ifdef RAD_AUTO_AD_Const
413 #ifdef RAD_Const_WARN
414 mutable const IndepADVar *padv;
417 mutable const IndepADVar *padv;
418 #endif //RAD_Const_WARN
421 static ADvari *First_ADvari, **Last_ADvari;
423 inline void ADvari_padv(
const IndepADVar *v) {
425 Last_ADvari = &this->Next;
428 #endif //RAD_AUTO_AD_Const
432 static int gcgen_cur, last_opno, zap_gcgen, zap_gcgen1, zap_opno;
433 static FILE *debug_file;
438 void *
operator new(
size_t len) {
441 rv->gcgen = gcgen_cur;
442 rv->opno = ++last_opno;
443 if (last_opno == zap_opno && gcgen_cur == zap_gcgen)
444 printf(
"Got to opno %d\n", last_opno);
450 void operator delete(
void*) {}
451 #ifdef RAD_ALLOW_WANTDERIV
452 inline ADvari(
Double t): Val(t), aval(0.), wantderiv(1) {}
453 inline ADvari(): Val(0.), aval(0.), wantderiv(1) {}
454 inline void no_deriv() { wantderiv = 0; }
459 #ifdef RAD_AUTO_AD_Const
472 #define Ai const Base< ADvari >&
474 #define T1(r,f) F r f <>(Ai);
524 friend ADvari& ADfn<>(
Double f,
int n,
const IndepADVar *
x,
const Double *g);
526 inline operator Double() {
return this->Val; }
527 inline operator Double()
const {
return this->Val; }
532 template<
typename Double>
class
539 #ifdef RAD_ALLOW_WANTDERIV
540 if (!ADVari::adc.new_Derp(a1,
this,c1))
543 ADVari::adc.new_Derp(a1,
this,c1);
546 #else // RAD_REINIT == 0
550 ADVari(val1), d(a1,this,c1) {}
551 #ifdef RAD_AUTO_AD_Const
552 typedef typename ADVari::IndepADVar IndepADVar;
554 ADvar1(
const IndepADVar*,
const IndepADVar&);
555 ADvar1(
const IndepADVar*,
const ADVari&);
557 ADVari(val1), d(a1,this,c1) {
559 this->ADvari_padv(v);
562 #endif // RAD_REININT > 0
566 template<
typename Double>
class
567 ConstADvari:
public ADvari<Double> {
581 inline void *
operator new(
size_t len) {
return ADVari::adc.Memalloc(len); }
582 inline ConstADvari(
Double t): ADVari(t) {}
584 static void aval_reset(
void);
587 template<
typename Double>
class
593 #elif RAD_REINIT == 2
594 typedef unsigned long ADGenType;
595 mutable ADGenType gen;
601 template<
typename Double>
class
611 IndepADvar_root.ADvprev = (this->ADvprev = IndepADvar_root.ADvprev)->ADvnext =
this;
612 this->ADvnext = &IndepADvar_root;
623 (this->ADvnext->ADvprev = this->ADvprev)->ADvnext = this->ADvnext;
636 #if RAD_REINIT > 0 //{
637 template<
typename Double> IndepADvar_base0<Double>
638 IndepADvar_base<Double>::IndepADvar_root(0.);
640 template<
typename Double>
void
641 IndepADvar_base<Double>::Move_to_end() {
642 if (
this != IndepADvar_root.ADvprev) {
643 (this->ADvnext->ADvprev = this->ADvprev)->ADvnext = this->ADvnext;
644 IndepADvar_root.ADvprev = (this->ADvprev = IndepADvar_root.ADvprev)->ADvnext =
this;
645 this->ADvnext = &IndepADvar_root;
648 #elif RAD_REINIT == 2
649 template<
typename Double>
typename IndepADvar_base0<Double>::ADGenType
650 IndepADvar_base<Double>::gen0(1);
654 template<
typename Double>
class
655 IndepADvar:
protected IndepADvar_base<Double>,
public Base< IndepADvar<Double> > {
657 static void AD_Const(
const IndepADvar&);
663 #ifdef RAD_AUTO_AD_Const
668 #elif defined(RAD_EQ_ALIAS)
673 #endif //RAD_AUTO_AD_Const
690 #ifdef RAD_ALLOW_WANTDERIV
691 inline int Wantderiv() {
return this->wantderiv; }
700 #ifdef RAD_AUTO_AD_Const
702 inline IndepADvar() { cv = 0; }
703 inline ~IndepADvar() {
717 #ifdef RAD_Const_WARN
718 inline operator ADVari&()
const {
719 ADVari *tcv = this->cv;
724 inline operator ADVari*()
const {
725 ADVari *tcv = this->cv;
730 #else //RAD_Const_WARN
731 inline operator ADVari&()
const {
RAD_cvchk((*
this))
return *this->cv; }
732 inline operator ADVari*()
const {
RAD_cvchk((*
this))
return this->cv; }
733 #endif //RAD_Const_WARN
748 friend void AD_Const1<>(
Double*,
const IndepADvar&);
750 friend ADVari& ADf1<>(
Double,
Double,
const IndepADvar&);
769 #define Ai const Base< ADVari >&
770 #define AI const Base< IndepADvar >&
778 #define T1(f) friend ADVari& f<> (AI);
780 #define F friend ADVari&
830 template<
typename Double>
class
831 ADvar:
public IndepADvar<Double> {
841 #if RAD_REINIT == 0 //{
843 if (ConstADVari::cadc.fpval_implies_const)
844 x =
new ConstADVari(d);
846 #ifdef RAD_AUTO_AD_Const //{
847 x =
new ADVari((IndepADVar*)
this, d);
848 x->ADvari_padv(
this);
855 ADVari *x =
new ADVari(d);
871 #ifdef RAD_AUTO_AD_Const
872 inline ADvar(IndepADVar &x) {
873 this->cv = x.cv ?
new ADVar1(
this, x) : 0;
876 inline ADvar(ADVari &x) { this->cv = &
x; x.ADvari_padv(
this); }
877 inline ADvar& operator=(IndepADVar &x) {
880 this->cv =
new ADVar1(
this,x);
883 inline ADvar& operator=(ADVari &x) {
886 this->cv =
new ADVar1(
this, x);
890 friend ADvar& ADvar_operatoreq<>(ADvar*, const ADVari&);
893 inline ADvar(
const IndepADVar &x) {
895 this->cv = (ADVari*)x.cv;
897 inline ADvar(const ADVari &x) { this->cv = (ADVari*)&x; }
898 inline ADvar& operator=(IndepADVar &x) {
900 this->cv = (ADVari*)x.cv; return *this;
902 inline ADvar& operator=(const ADVari &x) { this->cv = (ADVari*)&x;
return *
this; }
904 ADvar(const IndepADVar &x) {
908 this->cv =
new ADVar1(x.cv->Val, &this->cv->adc.One, x.cv);
918 this->cv =
new ADVar1(x.
cv->Val, &this->cv->adc.One, (ADVari*)x.
cv);
926 this->cv =
new ADVar1(x.
Val, &this->cv->adc.One, &x);
932 ADvar& operator=(Double);
933 ADvar& operator+=(
const ADVari&);
934 ADvar& operator+=(Double);
935 ADvar& operator-=(
const ADVari&);
936 ADvar& operator-=(Double);
937 ADvar& operator*=(
const ADVari&);
938 ADvar& operator*=(Double);
939 ADvar& operator/=(
const ADVari&);
940 ADvar& operator/=(Double);
943 {
return ConstADVari::cadc.fpval_implies_const; }
945 { ConstADVari::cadc.fpval_implies_const = newval; }
947 bool oldval = ConstADVari::cadc.fpval_implies_const;
948 ConstADVari::cadc.fpval_implies_const = newval;
952 inline static bool get_fpval_implies_const(
void) {
return true; }
953 inline static void set_fpval_implies_const(
bool newval) {}
954 inline static bool setget_fpval_implies_const(
bool newval) {
return newval; }
960 static inline void aval_reset() { ConstADVari::aval_reset(); }
968 template<
typename Double>
972 template<
typename Double>
975 template<
typename Double>
976 inline void AD_Const(
const IndepADvar<Double>&v) {}
977 #endif //RAD_REINIT == 0
979 template<
typename Double>
class
980 ConstADvar:
public ADvar<Double> {
997 void ConstADvar_ctr(Double);
1007 #ifdef RAD_NO_CONST_UPDATE
1013 this->cv =
new ADVari(d);
1022 this->cv =
new ADVar1(
this,d);
1031 #ifdef RAD_ALLOW_WANTDERIV
1032 template<
typename Double>
class
1036 typedef ADvar<Double>
ADVar;
1037 typedef IndepADvar<Double> IndepADVar;
1038 typedef typename IndepADVar::ADVari ADVari;
1039 typedef ADvar1<Double> ADVar1;
1041 void ADvar_ndctr(Double d) {
1042 ADVari *x =
new ADVari(d);
1053 inline ADvar_nd(Double d): ADVar((
void*)0,0) { ADvar_ndctr(d); }
1057 this->cv =
new ADVar1(x.cv->Val, &this->cv->adc.One, x.cv);
1064 this->cv =
new ADVar1(x.Val, &this->cv->adc.One, &x);
1070 #define ADvar_nd ADvar
1071 #endif //RAD_ALLOW_WANTDERIV
1073 template<
typename Double>
class
1074 ADvar1s:
public ADvar1<Double> {
1078 #if RAD_REINIT > 0 //{{
1079 inline ADvar1s(Double val1, Double a1,
const ADVari *c1): ADVar1(val1,&a1,c1) {}
1082 ADvar1s(Double val1, Double a1,
const ADVari *c1): ADVar1(val1,&a,c1), a(a1) {}
1083 #ifdef RAD_AUTO_AD_Const
1085 ADvar1s(Double val1, Double a1,
const ADVari *c1,
const ADVar *v):
1086 ADVar1(val1,&a,c1,v), a(a1) {}
1088 #endif // }} RAD_REINIT > 0
1091 template<
typename Double>
class
1092 ADvar2:
public ADvari<Double> {
1097 #if RAD_REINIT > 0 //{{
1098 ADvar2(Double val1,
const ADVari *Lcv,
const Double *Lc,
1099 const ADVari *Rcv,
const Double *Rc): ADVari(val1) {
1100 #ifdef RAD_ALLOW_WANTDERIV
1102 Ld = ADVari::adc.new_Derp(Lc,
this, Lcv);
1103 Rd = ADVari::adc.new_Derp(Rc,
this, Rcv);
1107 ADVari::adc.new_Derp(Lc, this, Lcv);
1108 ADVari::adc.new_Derp(Rc,
this, Rcv);
1109 #endif //RAD_ALLOW_WANTDERIV
1111 #else //}{ RAD_REINIT == 0
1113 ADvar2(Double val1,
const ADVari *Lcv,
const Double *Lc,
1114 const ADVari *Rcv,
const Double *Rc):
1116 dR.
next = DErp::LastDerp;
1118 DErp::LastDerp = &dL;
1125 #ifdef RAD_AUTO_AD_Const
1127 ADvar2(Double val1,
const ADVari *Lcv,
const Double *Lc,
1128 const ADVari *Rcv,
const Double *Rc, ADVar *v):
1130 dR.
next = DErp::LastDerp;
1132 DErp::LastDerp = &dL;
1139 this->ADvari_padv(v);
1142 #endif // }} RAD_REINIT
1145 template<
typename Double>
class
1146 ADvar2q:
public ADvar2<Double> {
1151 #if RAD_REINIT > 0 //{{
1152 inline ADvar2q(Double val1, Double Lp, Double Rp,
const ADVari *Lcv,
const ADVari *Rcv):
1154 #ifdef RAD_ALLOW_WANTDERIV
1156 Ld = ADVari::adc.new_Derp(&Lp,
this, Lcv);
1157 Rd = ADVari::adc.new_Derp(&Rp,
this, Rcv);
1161 ADVari::adc.new_Derp(&Lp, this, Lcv);
1162 ADVari::adc.new_Derp(&Rp,
this, Rcv);
1163 #endif //RAD_ALLOW_WANTDERIV
1165 #else //}{ RADINIT == 0
1167 ADvar2q(Double val1, Double Lp, Double Rp,
const ADVari *Lcv,
const ADVari *Rcv):
1168 ADVar2(val1), a(Lp), b(Rp) {
1169 this->dR.next = DErp::LastDerp;
1170 this->dL.next = &this->dR;
1171 DErp::LastDerp = &this->dL;
1176 this->dL.b = this->dR.b =
this;
1178 #ifdef RAD_AUTO_AD_Const
1180 ADvar2q(Double val1, Double Lp, Double Rp,
const ADVari *Lcv,
1181 const ADVari *Rcv,
const ADVar *v):
1182 ADVar2(val1), a(Lp), b(Rp) {
1183 this->dR.next = DErp::LastDerp;
1184 this->dL.next = &this->dR;
1185 DErp::LastDerp = &this->dL;
1190 this->dL.b = this->dR.b =
this;
1192 this->ADvari_padv(v);
1195 #endif //}} RAD_REINIT > 0
1198 template<
typename Double>
class
1199 ADvarn:
public ADvari<Double> {
1204 #if RAD_REINIT > 0 // {{
1205 ADvarn(Double val1,
int n1,
const IndepADVar *x,
const Double *g): ADVari(val1) {
1206 #ifdef RAD_ALLOW_WANTDERIV
1208 for(i = nd = 0; i < n1; i++)
1209 if (ADVari::adc.new_Derp(g+i,
this, x[i].cv))
1214 for(
int i = 0; i < n1; i++)
1215 ADVari::adc.new_Derp(g+i,
this, x[i].cv);
1216 #endif // RAD_ALLOW_WANTDERIV
1222 ADvarn(Double val1,
int n1,
const IndepADVar *x,
const Double *g):
1223 ADVari(val1), n(n1) {
1228 a1 = a = (Double*)ADVari::adc.Memalloc(n*
sizeof(*a));
1229 d1 = Da = (DErp*)ADVari::adc.Memalloc(n*
sizeof(DErp));
1230 dlast = DErp::LastDerp;
1231 for(i = 0; i < n1; i++, d1++) {
1239 DErp::LastDerp = dlast;
1241 #endif //}} RAD_REINIT > 0
1244 template<
typename Double>
1249 template<
typename Double>
1255 template<
typename Double>
1256 inline int operator<(const Base< ADvari<Double> > &LL, Double
R) {
1260 template<
typename Double>
1261 inline int operator<(Double L, const Base< ADvari<Double> > &RR) {
1266 template<
typename Double>
1272 template<
typename Double>
1273 inline int operator<=(const Base< ADvari<Double> > &LL, Double
R) {
1277 template<
typename Double>
1278 inline int operator<=(Double L, const Base< ADvari<Double> > &RR) {
1283 template<
typename Double>
1289 template<
typename Double>
1294 template<
typename Double>
1300 template<
typename Double>
1306 template<
typename Double>
1311 template<
typename Double>
1317 template<
typename Double>
1323 template<
typename Double>
1328 template<
typename Double>
1334 template<
typename Double>
1340 template<
typename Double>
1345 template<
typename Double>
1351 template<
typename Double>
1354 return Mbase + (Mleft -= len);
1355 return new_ADmemblock(len);
1357 #if RAD_REINIT > 0 //{{
1359 template<
typename Double>
1362 template<
typename Double>
1366 template<
typename Double>
1368 a(*a1), b(b1), c(c1) {}
1369 #else //}{ RAD_REINIT == 0
1371 template<
typename Double>
1377 template<
typename Double>
1384 template<
typename Double>
1389 #endif //}} RAD_REINIT
1403 #ifdef RAD_AUTO_AD_Const
1409 #ifndef RAD_DEBUG_gcgen1
1410 #define RAD_DEBUG_gcgen1 -1
1422 First =
new ADMemblock;
1426 Mbase = (
char*)First->
memblk;
1427 Mleft =
sizeof(First->
memblk);
1428 rad_need_reinit = 0;
1429 #ifdef RAD_DEBUG_BLOCKKEEP
1430 rad_busy_blocks = 0;
1435 DBusy =
new ADMemblock;
1438 DMleft = nderps =
sizeof(DBusy->
memblk)/
sizeof(DErp);
1445 ADMemblock *mb, *mb1;
1447 for(mb = ADVari::adc.Busy; mb; mb = mb1) {
1451 for(mb = ADVari::adc.Free; mb; mb = mb1) {
1455 for(mb = ConstADVari::cadc.Busy; mb; mb = mb1) {
1459 ConstADVari::cadc.Busy = ADVari::adc.Busy = ADVari::adc.Free = 0;
1460 ConstADVari::cadc.Mleft = ADVari::adc.Mleft = 0;
1461 ConstADVari::cadc.Mbase = ADVari::adc.Mbase = 0;
1463 for(mb = ADVari::adc.DBusy; mb; mb = mb1) {
1467 for(mb = ADVari::adc.DFree; mb; mb = mb1) {
1471 ADVari::adc.DBusy = ADVari::adc.DFree = 0;
1472 ADVari::adc.DMleft = 0;
1473 ConstADVari::cadc.Mbase = ADVari::adc.Mbase = 0;
1475 ConstADVari::lastcad = 0;
1476 Derp<Double>::LastDerp = 0;
1484 if (ConstADVari::cadc.Busy || ADVari::adc.Busy || ADVari::adc.Free
1486 || ADVari::adc.DBusy || ADVari::adc.DFree
1489 ADVari::adc.do_init();
1490 ConstADVari::cadc.do_init();
1493 template<
typename Double>
void*
1496 ADMemblock *mb, *mb0, *mb1, *mbf, *
x;
1497 #ifdef RAD_AUTO_AD_Const
1500 #ifdef RAD_Const_WARN
1512 if ((rad_need_reinit & 1) &&
this == &ADVari::adc) {
1513 rad_need_reinit &= ~1;
1515 #ifdef RAD_DEBUG_BLOCKKEEP
1516 Mleft = rad_mleft_save;
1517 if (Mleft <
sizeof(First->
memblk))
1518 _uninit_f2c(Mbase + Mleft,
1519 UninitType<Double>::utype,
1520 (
sizeof(First->
memblk) - Mleft)
1522 if ((mb = Busy->
next)) {
1524 for(;; mb = mb->
next) {
1526 UninitType<Double>::utype,
1533 rad_Oldcurmb = Busy;
1534 if (rad_busy_blocks >= RAD_DEBUG_BLOCKKEEP) {
1535 rad_busy_blocks = 0;
1539 for(mb = Busy; mb != mb0; mb = mb1) {
1546 Mbase = (
char*)First->
memblk;
1547 Mleft =
sizeof(First->
memblk);
1554 for(mb = Busy; mb != mb0; mb = mb1) {
1561 Mbase = (
char*)First->
memblk;
1562 Mleft =
sizeof(First->
memblk);
1564 #ifdef RAD_AUTO_AD_Const // {
1565 *ADVari::Last_ADvari = 0;
1566 ADVari::Last_ADvari = &ADVari::First_ADvari;
1567 a = ADVari::First_ADvari;
1572 #ifdef RAD_Const_WARN
1573 if ((i = a->opno) > 0)
1576 v->
cv = cv =
new ADVari(v, a->
Val);
1580 v->
cv =
new ADVari(v, a->
Val);
1586 #endif // } RAD_AUTO_AD_Const
1587 #if RAD_REINIT > 0 //{
1589 while((mb1 = mb->
next)) {
1600 while((vb = vb->ADvnext) != vb0)
1601 if ((tcv = ((IADv*)vb)->cv))
1602 ((IADv*)vb)->cv =
new ADVari(tcv->
Val);
1603 #elif RAD_REINIT == 2
1608 return Mbase + (Mleft -= len);
1615 #ifdef RAD_DEBUG_BLOCKKEEP
1620 return (Mbase = (
char*)x->
memblk) +
1621 (Mleft =
sizeof(First->
memblk) - len);
1624 template<
typename Double>
void
1627 #if RAD_REINIT > 0 //{{
1631 if (ADVari::adc.rad_need_reinit && wantgrad) {
1632 mb = ADVari::adc.DBusy;
1633 d = ((DErp*)mb->
memblk) + ADVari::adc.DMleft;
1634 de = ((DErp*)mb->
memblk) + ADVari::adc.nderps;
1641 de = d + ADVari::adc.nderps;
1644 #else //}{ RAD_REINIT == 0
1647 if (ADVari::adc.rad_need_reinit && wantgrad) {
1648 for(d = DErp::LastDerp; d; d = d->
next)
1651 #endif //}} RAD_REINIT
1653 if (!(ADVari::adc.rad_need_reinit & 1)) {
1654 ADVari::adc.rad_need_reinit = 1;
1655 ADVari::adc.rad_mleft_save = ADVari::adc.Mleft;
1656 ADVari::adc.Mleft = 0;
1660 if (ADVari::gcgen_cur == ADVari::zap_gcgen1 && wantgrad) {
1662 if (!(fname = getenv(
"RAD_DEBUG_FILE")))
1663 fname =
"rad_debug.out";
1667 ADVari::debug_file = fopen(fname,
"w");
1668 ADVari::zap_gcgen1 = -1;
1671 #if RAD_REINIT > 0 //{{
1672 if (ADVari::adc.DMleft < ADVari::adc.nderps && wantgrad) {
1673 mb = ADVari::adc.DBusy;
1674 d = ((DErp*)mb->
memblk) + ADVari::adc.DMleft;
1675 de = ((DErp*)mb->
memblk) + ADVari::adc.nderps;
1679 if (ADVari::debug_file) {
1680 for(; d < de; d++) {
1681 fprintf(ADVari::debug_file,
"%d\t%d\t%g + %g * %g",
1684 fprintf(ADVari::debug_file,
" = %g\n", d->
c->
aval);
1694 de = d + ADVari::adc.nderps;
1697 #else //}{ RAD_REINIT == 0
1698 if ((d = DErp::LastDerp) && wantgrad) {
1701 if (ADVari::debug_file)
1703 fprintf(ADVari::debug_file,
"%d\t%d\t%g + %g * %g",
1706 fprintf(ADVari::debug_file,
" = %g\n", d->
c->
aval);
1707 }
while((d = d->
next));
1711 while((d = d->
next));
1714 if (ADVari::debug_file) {
1715 fclose(ADVari::debug_file);
1716 ADVari::debug_file = 0;
1719 #endif // }} RAD_REINIT
1721 if (ADVari::debug_file)
1722 fflush(ADVari::debug_file);
1723 ADVari::gcgen_cur++;
1724 ADVari::last_opno = 0;
1728 template<
typename Double>
void
1732 #if RAD_REINIT > 0 //{{
1736 if (ADVari::adc.rad_need_reinit) {
1737 mb = ADVari::adc.DBusy;
1738 d = ((DErp*)mb->
memblk) + ADVari::adc.DMleft;
1739 de = ((DErp*)mb->
memblk) + ADVari::adc.nderps;
1746 de = d + ADVari::adc.nderps;
1749 #else //}{ RAD_REINIT == 0
1752 if (ADVari::adc.rad_need_reinit) {
1753 for(d = DErp::LastDerp; d; d = d->
next)
1756 #endif //}} RAD_REINIT
1758 if (!(ADVari::adc.rad_need_reinit & 1)) {
1759 ADVari::adc.rad_need_reinit = 1;
1760 ADVari::adc.rad_mleft_save = ADVari::adc.Mleft;
1761 ADVari::adc.Mleft = 0;
1765 if (ADVari::gcgen_cur == ADVari::zap_gcgen1) {
1767 if (!(fname = getenv(
"RAD_DEBUG_FILE")))
1768 fname =
"rad_debug.out";
1772 ADVari::debug_file = fopen(fname,
"w");
1773 ADVari::zap_gcgen1 = -1;
1776 #if RAD_REINIT > 0 //{{
1777 if (ADVari::adc.DMleft < ADVari::adc.nderps) {
1778 for(i = 0; i < n; i++)
1779 V[i]->cv->
aval = w[i];
1780 mb = ADVari::adc.DBusy;
1781 d = ((DErp*)mb->
memblk) + ADVari::adc.DMleft;
1782 de = ((DErp*)mb->
memblk) + ADVari::adc.nderps;
1786 if (ADVari::debug_file) {
1787 for(; d < de; d++) {
1788 fprintf(ADVari::debug_file,
"%d\t%d\t%g + %g * %g",
1791 fprintf(ADVari::debug_file,
" = %g\n", d->
c->
aval);
1801 de = d + ADVari::adc.nderps;
1804 #else //}{ RAD_REINIT == 0
1805 if ((d = DErp::LastDerp) != 0) {
1806 for(i = 0; i < n; i++)
1807 V[i]->cv->
aval = w[i];
1809 if (ADVari::debug_file)
1811 fprintf(ADVari::debug_file,
"%d\t%d\t%g + %g * %g",
1814 fprintf(ADVari::debug_file,
" = %g\n", d->
c->
aval);
1815 }
while((d = d->
next));
1819 while((d = d->
next));
1822 if (ADVari::debug_file) {
1823 fclose(ADVari::debug_file);
1824 ADVari::debug_file = 0;
1827 #endif // }} RAD_REINIT
1829 if (ADVari::debug_file)
1830 fflush(ADVari::debug_file);
1831 ADVari::gcgen_cur++;
1832 ADVari::last_opno = 0;
1836 template<
typename Double>
void
1844 template<
typename Double>
void
1847 for(DErp *d = DErp::LastDerp; d; d = d->
next) {
1849 *(
const_cast<Double*
>(d->
a)) =
Double(0.0);
1861 template<
typename Double>
1866 RAD_REINIT_2(Val = d; this->gen = this->IndepADvar_root.gen;)
1869 template<typename Double>
1873 cv =
new ADVari(
Double(i));
1874 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
1877 template<typename Double>
1881 cv =
new ADVari(
Double(i));
1882 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
1885 template<typename Double>
1889 cv =
new ADVari(
Double(i));
1890 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
1893 template<typename Double>
1897 this->cv =
new ConstADVari(0.);
1898 RAD_REINIT_2(this->Val = 0.; this->gen = this->IndepADvar_root.gen;)
1901 template<typename Double>
void
1905 this->cv =
new ConstADVari(d);
1906 RAD_REINIT_2(this->Val = d; this->gen = this->IndepADvar_root.gen;)
1909 template<typename Double>
1914 ConstADVari *
y =
new ConstADVari(x.
cv->Val);
1916 x.
cv->adc.new_Derp(&x.adc.One,
y, x.
cv);
1918 DErp *d =
new DErp(&x.adc.One,
y, x.
cv);
1921 RAD_REINIT_2(this->Val =
y->Val; this->gen = this->IndepADvar_root.gen;)
1924 template<
typename Double>
1929 ConstADVari *
y =
new ConstADVari(x.
cv->Val);
1931 x.
cv->adc.new_Derp(&x.
cv->adc.One,
y, x.
cv);
1933 DErp *d =
new DErp(&x.
cv->adc.One,
y, (ADVari*)x.
cv);
1936 RAD_REINIT_2(this->Val =
y->Val; this->gen = this->IndepADvar_root.gen;)
1939 template<
typename Double>
1943 ConstADVari *
y =
new ConstADVari(x.
Val);
1945 x.
adc.new_Derp(&x.
adc.One,
y, &x);
1947 DErp *d =
new DErp(&x.
adc.One,
y, &x);
1950 RAD_REINIT_2(this->Val =
y->Val; this->gen = this->IndepADvar_root.gen;)
1953 template<
typename Double>
1959 ConstADVari *ncv =
new ConstADVari(v.
val());
1960 #ifdef RAD_AUTO_AD_Const
1967 template<
typename Double>
1971 #ifdef RAD_ALLOW_WANTDERIV
1973 if (this->gen != this->IndepADvar_root.gen) {
1974 cv =
new ADVari(Val);
1975 this->gen = this->IndepADvar_root.gen;
1978 return this->wantderiv = cv->wantderiv = n;
1981 #endif // RAD_ALLOW_WANTDERIV
1984 template<
typename Double>
1994 #elif RAD_REINIT == 1
1999 #ifdef RAD_AUTO_AD_Const
2001 template<
typename Double>
2004 this->ADvari_padv(x);
2008 template<typename Double>
2011 this->ADvari_padv(x);
2015 template<typename Double>
2017 ADVari(y.cv->Val), d((const Double*)&
ADcontext<Double>::One, (ADVari*)this, y.cv)
2019 this->ADvari_padv(x);
2022 template<
typename Double>
2024 ADVari(y.Val), d((const Double*)&ADcontext<Double>::One, this, &y)
2026 this->ADvari_padv(x);
2031 template<
typename Double>
2037 RAD_REINIT_2(This->Val = x.
Val; This->gen = This->IndepADvar_root.gen;)
2041 template<
typename Double>
2047 RAD_REINIT_2(This->Val = x.
Val; This->gen = This->IndepADvar_root.gen;)
2054 template<
typename Double>
2058 #ifdef RAD_AUTO_AD_Const
2061 this->cv =
new ADVari(
this,d);
2063 this->cv =
new ADVari(d);
2070 template<
typename Double>
2074 #ifdef RAD_AUTO_AD_Const
2077 this->cv =
new ADVari(
this,d);
2079 this->cv =
RAD_REINIT_0(ConstADVari::cadc.fpval_implies_const
2080 ?
new ConstADVari(d)
2083 RAD_REINIT_2(this->Val = d; this->gen = this->IndepADvar_root.gen;)
2088 template<
typename Double>
2095 template<
typename Double>
2103 #ifdef RAD_AUTO_AD_Const
2104 #define RAD_ACA ,this
2109 template<
typename Double>
2112 ADVari *Lcv = this->cv;
2120 template<
typename Double>
2127 template<
typename Double>
2130 ADVari *tcv = this->cv;
2131 this->cv =
new ADVar1(tcv->
Val + R, &tcv->
adc.One, tcv
RAD_ACA);
2138 template<
typename Double>
2145 template<
typename Double>
2153 template<
typename Double>
2156 ADVari *Lcv = this->cv;
2164 template<
typename Double>
2171 template<
typename Double>
2174 ADVari *tcv = this->cv;
2175 this->cv =
new ADVar1(tcv->
Val - R, &tcv->
adc.One, tcv
RAD_ACA);
2182 template<
typename Double>
2189 template<
typename Double>
2197 template<
typename Double>
2200 ADVari *Lcv = this->cv;
2208 template<
typename Double>
2215 template<
typename Double>
2218 ADVari *Lcv = this->cv;
2226 template<
typename Double>
2233 template<
typename Double>
2238 Double Lv = L.
Val, Rv = R.
Val, pL = 1. / Rv, q = Lv/Rv;
2242 template<
typename Double>
2245 ADVari *Lcv = this->cv;
2246 Double Lv = Lcv->
Val, Rv = R.
Val, pL = 1. / Rv, q = Lv/Rv;
2254 template<
typename Double>
2261 template<
typename Double>
2265 Double recip = 1. / R.
Val;
2266 Double q = L * recip;
2270 template<
typename Double>
2273 ADVari *Lcv = this->cv;
2281 template<
typename Double>
2289 template<
typename Double>
2297 template<
typename Double>
2305 template<
typename Double>
2317 template<
typename Double>
2325 template<
typename Double>
2333 template<
typename Double>
2338 Double x = L.
Val,
y = R.
Val, t = x*x +
y*
y;
2342 template<
typename Double>
2346 Double
y = R.
Val, t = x*x + y*
y;
2350 template<
typename Double>
2354 Double x = L.
Val, t = x*x + y*
y;
2358 template<
typename Double>
2367 template<
typename Double>
2376 template<
typename Double>
2385 template<
typename Double>
2394 template<
typename Double>
2403 template<
typename Double>
2412 template<
typename Double>
2419 template<
typename Double>
2426 template<
typename Double>
2435 rcv->
d.a = &rcv->
Val;
2441 template<
typename Double>
2449 template<
typename Double>
2453 static double num = 1. /
std::log(10.);
2458 template<
typename Double>
2467 template<
typename Double>
2475 template<
typename Double>
2483 template<
typename Double>
2490 template<
typename Double>
2497 template<
typename Double>
2505 template<
typename Double>
2513 template<
typename Double>
2521 template<
typename Double>
2527 if ((t = v.
Val) < 0) {
2534 template<
typename Double>
2543 if ((t = v.
Val) < 0) {
2550 template<
typename Double>
2558 template<
typename Double>
2564 template<
typename Double>
2565 inline ADvari<Double>&
2570 template<
typename Double>
2576 template<
typename Double>
2582 template<
typename Double>
2588 template<
typename Double>
2594 template<
typename Double>
2600 template<
typename Double>
2601 inline ADvari<Double>&
2606 template<
typename Double>
2613 #define A (ADvari<Double>*)
2614 #ifdef RAD_Const_WARN
2615 #define C(x) (((x)->opno < 0) ? RAD_Const_Warn(x) : 0, *A x)
2619 #define T template<typename Double> inline
2620 #define F ADvari<Double>&
2621 #define Ai const Base< ADvari<Double> >&
2622 #define AI const Base< IndepADvar<Double> >&
2624 #define CAI(x,y) const IndepADvar<Double> & x = y.derived()
2625 #define CAi(x,y) const ADvari<Double> & x = y.derived()
2627 T r f(Ai LL, AI RR) { CAi(L,LL); CAI(R,RR); RAD_cvchk(R) return f(L, C(R.cv)); } \
2628 T r f(AI LL, Ai RR) { CAI(L,LL); CAi(R,RR); RAD_cvchk(L) return f(C(L.cv), R); }\
2629 T r f(AI LL, AI RR) { CAI(L,LL); CAI(R,RR); RAD_cvchk(L) RAD_cvchk(R) return f(C(L.cv), C(R.cv)); }\
2630 T r f(AI LL, D R) { CAI(L,LL); RAD_cvchk(L) return f(C(L.cv), R); } \
2631 T r f(D L, AI RR) { CAI(R,RR); RAD_cvchk(R) return f(L, C(R.cv)); } \
2632 T r f(Ai L, Dtype R) { return f(L, (D)R); }\
2633 T r f(AI L, Dtype R) { return f(L, (D)R); }\
2634 T r f(Ai L, Ltype R) { return f(L, (D)R); }\
2635 T r f(AI L, Ltype R) { return f(L, (D)R); }\
2636 T r f(Ai L, Itype R) { return f(L, (D)R); }\
2637 T r f(AI L, Itype R) { return f(L, (D)R); }\
2638 T r f(Dtype L, Ai R) { return f((D)L, R); }\
2639 T r f(Dtype L, AI R) {return f((D)L, R); }\
2640 T r f(Ltype L, Ai R) { return f((D)L, R); }\
2641 T r f(Ltype L, AI R) { return f((D)L, R); }\
2642 T r f(Itype L, Ai R) { return f((D)L, R); }\
2643 T r f(Itype L, AI R) { return f((D)L, R); }
2664 T F f(AI xx) { CAI(x,xx); RAD_cvchk(x) return f(C(x.cv)); }
2719 #undef Allow_noderiv
static void Outvar_Gradcomp(ADVar &v)
ADvari< Double > & asinh(const Base< ADvari< Double > > &vv)
ADT_RAD ADvari< double > Ai
ADvari< Double > & pow(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
static ADcontext< Double > adc
ADvari< Double > & operator/(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
static void aval_reset(void)
ADvari< Double > & exp(const Base< ADvari< Double > > &vv)
ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv, const ADVari *Rcv)
void AD_Const1(Double *, const IndepADvar< Double > &)
ADT_RAD IndepADvar< double > AI
static CADcontext< Double > cadc
ADvar & operator+=(const ADVari &)
Sacado::RadVec::ADvar< double > ADVar
ADvari< Double > & abs(const Base< ADvari< Double > > &vv)
ADvari< Double > & ADf2(Double f, Double gx, Double gy, const IndepADvar< Double > &x, const IndepADvar< Double > &y)
void AD_Const(const IndepADvar< Double > &)
ADvar & operator*=(const ADVari &)
int operator!=(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
static bool setget_fpval_implies_const(bool newval)
ADvari< Double > & log(const Base< ADvari< Double > > &vv)
Double val(const ADvari< Double > &)
IndepADvar & operator=(IndepADvar &x)
ADvari< Double > & cbrt(const Base< ADvari< Double > > &vv)
Turn ADvar into a meta-function class usable with mpl::apply.
ADvari< Double > & atan2(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
ADvar1(Double val1, const ADVari *c1)
ConstADvar & operator=(ADVari &d)
Base class for Sacado types to control overload resolution.
IndepADvar< Double > & ADvar_operatoreq(IndepADvar< Double > *, const ADvari< Double > &)
ADvari< Double > & cosh(const Base< ADvari< Double > > &vv)
ADvari< Double > & sqrt(const Base< ADvari< Double > > &vv)
ADvari< Double > & max(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
ADvar1s(Double val1, Double a1, const ADVari *c1)
static void AD_Const(const IndepADvar &)
IndepADvar() Allow_noderiv(
IndepADVar::ADVari ADVari
static void Gradcomp(int wantgrad)
ADvari< Double > & asin(const Base< ADvari< Double > > &vv)
static void Weighted_Gradcomp(size_t, ADVar **, Double *)
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
FloatingPoint< double > Double
ADvar2(Double val1, const ADVari *Lcv, const Double *Lc, const ADVari *Rcv, const Double *Rc)
int operator>(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
static void set_fpval_implies_const(bool newval)
ADvari< Double > & atanh(const Base< ADvari< Double > > &vv)
ConstADvar & operator=(Double d)
int RAD_Const_Warn(void *v)
char memblk[1000 *sizeof(double)]
ADvar & operator-=(const ADVari &)
ADvar & operator=(const ADVari &x)
ADvar1(Double val1, const Double *a1, const ADVari *c1)
static void Weighted_Gradcomp(size_t n, ADVar **v, Double *w)
ScalarType< value_type >::type scalar_type
ADvari< Double > & acosh(const Base< ADvari< Double > > &vv)
static void Gradcomp(int wantgrad)
ADvari< Double > & min(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
ADvar & operator/=(const ADVari &)
atan2(expr1.val(), expr2.val())
ADvari< Double > & tan(const Base< ADvari< Double > > &vv)
ADvari< Double > & log10(const Base< ADvari< Double > > &vv)
ADvari< Double > & acos(const Base< ADvari< Double > > &vv)
ADvari< Double > & operator-(const Base< ADvari< Double > > &TT)
ADvari< Double > & tanh(const Base< ADvari< Double > > &vv)
ADvari< Double > & fabs(const Base< ADvari< Double > > &vv)
ADmemblock< Double > ADMemblock
static void Outvar_Gradcomp(ADvar &v)
ADvari< Double > & operator*(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
IndepADvar_base(Allow_noderiv(int wd))
ADvari< Double > & operator+(const Base< ADvari< Double > > &TT)
ADvarn(Double val1, int n1, const IndepADVar *x, const Double *g)
static void Outvar_Gradcomp(ADVar &)
int operator>=(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
int operator==(const Base< ADvari< Double > > &LL, const Base< ADvari< Double > > &RR)
SACADO_INLINE_FUNCTION mpl::enable_if_c< ExprLevel< Expr< T1 > >::value==ExprLevel< Expr< T2 > >::value, Expr< PowerOp< Expr< T1 >, Expr< T2 > > > >::type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
ADvari< Double > & sinh(const Base< ADvari< Double > > &vv)
const derived_type & derived() const
IndepADvar< Double > IndepADVar
ADVari::IndepADVar IndepADVar
ADvari< Double > & sin(const Base< ADvari< Double > > &vv)
void * new_ADmemblock(size_t)
ADvari< Double > & cos(const Base< ADvari< Double > > &vv)
ADvari< Double > & ADf1(Double f, Double g, const IndepADvar< Double > &x)
void * Memalloc(size_t len)
static void Weighted_Gradcomp(size_t n, ADvar **v, Double *w)
IndepADvar< Double > IndepADVar
ADvari< Double > & ADfn(Double f, int n, const IndepADvar< Double > *x, const Double *g)
static bool get_fpval_implies_const(void)
ConstADvari< Double > ConstADVari
ADVar::ConstADVari ConstADVari
ADvari< Double > & atan(const Base< ADvari< Double > > &vv)
ADVar::IndepADVar IndepADVar