00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef SACADO_TRADVEC_H
00036 #define SACADO_TRADVEC_H
00037
00038 #include "Sacado_ConfigDefs.h"
00039 #include "Sacado_trad_Traits.hpp"
00040
00041 #include <stddef.h>
00042 #include <cmath>
00043 #include <math.h>
00044
00045 #ifdef RAD_Const_WARN //{ ==> RAD_AUTO_AD_Const and RAD_DEBUG
00046 #ifndef RAD_AUTO_AD_Const
00047 #define RAD_AUTO_AD_Const
00048 #endif
00049 #ifndef RAD_DEBUG
00050 #define RAD_DEBUG
00051 #endif
00052 extern "C" int RAD_Const_Warn(const void*);
00053
00054 #endif //} RAD_Const_WARN
00055
00056 #ifdef RAD_DEBUG
00057 #include <cstdio>
00058 #include <stdlib.h>
00059 #endif
00060
00061 #ifndef RAD_AUTO_AD_Const
00062 #ifdef RAD_DEBUG_BLOCKKEEP
00063 #include <complex>
00064 #endif
00065 #endif
00066
00067 namespace Sacado {
00068 namespace RadVec {
00069
00070 #ifdef RAD_AUTO_AD_Const
00071 #undef RAD_DEBUG_BLOCKKEEP
00072 #define Padvinit ,padv(0)
00073 #else
00074 #define Padvinit
00075 #ifdef RAD_DEBUG_BLOCKKEEP
00076 #if !(RAD_DEBUG_BLOCKKEEP > 0)
00077 #undef RAD_DEBUG_BLOCKKEEP
00078 #else
00079 extern "C" void _uninit_f2c(void *x, int type, long len);
00080
00081 template <typename T>
00082 struct UninitType {};
00083
00084 template <>
00085 struct UninitType<float> {
00086 static const int utype = 4;
00087 };
00088
00089 template <>
00090 struct UninitType<double> {
00091 static const int utype = 5;
00092 };
00093
00094 template <typename T>
00095 struct UninitType< std::complex<T> > {
00096 static const int utype = UninitType<T>::utype + 2;
00097 };
00098
00099 #endif
00100 #endif
00101 #endif
00102
00103 class RAD_DoubleIgnore {};
00104
00105 template<typename T> class
00106 DoubleAvoid {
00107 public:
00108 typedef double dtype;
00109 typedef T ttype;
00110 };
00111 template<> class
00112 DoubleAvoid<double> {
00113 public:
00114 typedef RAD_DoubleIgnore &dtype;
00115 typedef RAD_DoubleIgnore &ttype;
00116 };
00117
00118 #define Dtype typename DoubleAvoid<Double>::dtype
00119 #define Ttype typename DoubleAvoid<Double>::ttype
00120
00121 template<typename Double> class IndepADvar;
00122 template<typename Double> class ConstADvar;
00123 template<typename Double> class ConstADvari;
00124 template<typename Double> class ADvar;
00125 template<typename Double> class ADvari;
00126 template<typename Double> class ADvar1;
00127 template<typename Double> class ADvar1s;
00128 template<typename Double> class ADvar2;
00129 template<typename Double> class ADvar2q;
00130 template<typename Double> class ADvarn;
00131 template<typename Double> class Derp;
00132
00133 template<typename Double> struct
00134 ADmemblock {
00135
00136
00137 ADmemblock *next;
00138 Double memblk[1000];
00139 };
00140
00141 template<typename Double> class
00142 ADcontext {
00143 typedef ADmemblock<Double> ADMemblock;
00144 typedef ADvar<Double> ADVar;
00145 typedef ADvari<Double> ADVari;
00146 typedef Derp<Double> DErp;
00147
00148 ADMemblock *Busy, *First, *Free, *Oldbusy;
00149 char *Mbase;
00150 size_t Mleft;
00151 int rad_need_reinit;
00152 size_t ncur, nmax, rad_mleft_save;
00153 #ifdef RAD_DEBUG_BLOCKKEEP
00154 int rad_busy_blocks;
00155 ADMemblock *rad_Oldcurmb;
00156 #endif
00157 void *new_ADmemblock(size_t);
00158 void derp_init(size_t);
00159 public:
00160 static const Double One, negOne;
00161 ADcontext();
00162 void *Memalloc(size_t len);
00163 static void Gradcomp();
00164 static void aval_reset(void);
00165 static void Weighted_Gradcomp(size_t, ADVar**, Double*);
00166 static void Weighted_GradcompVec(size_t, size_t*, ADVar***, Double**);
00167 static void Outvar_Gradcomp(ADVar&);
00168 };
00169
00170 template<typename Double> class
00171 CADcontext: public ADcontext<Double> {
00172 protected:
00173 bool fpval_implies_const;
00174 public:
00175 friend class ADvar<Double>;
00176 CADcontext(): ADcontext<Double>() { fpval_implies_const = false; }
00177 };
00178
00179 template<typename Double> class
00180 Derp {
00181 public:
00182 friend class ADvarn<Double>;
00183 typedef ADvari<Double> ADVari;
00184 static Derp *LastDerp;
00185 Derp *next;
00186 const Double *a;
00187 const ADVari *b;
00188 const ADVari *c;
00189 Derp(){};
00190 Derp(const ADVari *);
00191 Derp(const Double *, const ADVari *);
00192 Derp(const Double *, const ADVari *, const ADVari *);
00193 inline void *operator new(size_t len) { return (Derp*)ADVari::adc.Memalloc(len); }
00194
00195 };
00196
00197
00198
00199 #define Ai const ADvari<Double>&
00200 #define AI const IndepADvar<Double>&
00201 #define T template<typename Double>
00202 #define D Double
00203 #define T1(f) \
00204 T F f (AI); \
00205 T F f (Ai);
00206 #define T2(r,f) \
00207 T r f(Ai,Ai); \
00208 T r f(Ai,D); \
00209 T r f(Ai,Dtype); \
00210 T r f(Ai,long); \
00211 T r f(Ai,int); \
00212 T r f(D,Ai); \
00213 T r f(Dtype,Ai); \
00214 T r f(long,Ai); \
00215 T r f(int,Ai); \
00216 T r f(AI,D); \
00217 T r f(AI,Dtype); \
00218 T r f(AI,long); \
00219 T r f(AI,int); \
00220 T r f(D,AI); \
00221 T r f(Dtype,AI); \
00222 T r f(long,AI); \
00223 T r f(int,AI); \
00224 T r f(Ai,AI);\
00225 T r f(AI,Ai);\
00226 T r f(AI,AI);
00227
00228 #define F ADvari<Double>&
00229 T2(F, operator+)
00230 T2(F, operator-)
00231 T2(F, operator*)
00232 T2(F, operator/)
00233 T2(F, atan2)
00234 T2(F, pow)
00235 T2(F, max)
00236 T2(F, min)
00237 T2(int, operator<)
00238 T2(int, operator<=)
00239 T2(int, operator==)
00240 T2(int, operator!=)
00241 T2(int, operator>=)
00242 T2(int, operator>)
00243 T1(operator+)
00244 T1(operator-)
00245 T1(abs)
00246 T1(acos)
00247 T1(acosh)
00248 T1(asin)
00249 T1(asinh)
00250 T1(atan)
00251 T1(atanh)
00252 T1(cos)
00253 T1(cosh)
00254 T1(exp)
00255 T1(log)
00256 T1(log10)
00257 T1(sin)
00258 T1(sinh)
00259 T1(sqrt)
00260 T1(tan)
00261 T1(tanh)
00262 T1(fabs)
00263
00264 T F copy(AI);
00265 T F copy(Ai);
00266
00267 #undef F
00268 #undef T2
00269 #undef T1
00270 #undef D
00271 #undef T
00272 #undef AI
00273 #undef Ai
00274
00275 template<typename Double>ADvari<Double>& ADf1(Double f, Double g, const IndepADvar<Double> &x);
00276 template<typename Double>ADvari<Double>& ADf2(Double f, Double gx, Double gy,
00277 const IndepADvar<Double> &x, const IndepADvar<Double> &y);
00278 template<typename Double>ADvari<Double>& ADfn(Double f, int n,
00279 const IndepADvar<Double> *x, const Double *g);
00280
00281 template<typename Double> IndepADvar<Double>& ADvar_operatoreq(IndepADvar<Double>*,
00282 const ADvari<Double>&);
00283 template<typename Double> ADvar<Double>& ADvar_operatoreq(ADvar<Double>*, const ADvari<Double>&);
00284 template<typename Double> void AD_Const(const IndepADvar<Double>&);
00285 template<typename Double> void AD_Const1(Double*, const IndepADvar<Double>&);
00286 template<typename Double> ADvari<Double>& ADf1(Double, Double, const ADvari<Double>&);
00287 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00288 const ADvari<Double>&, const ADvari<Double>&);
00289 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00290 const IndepADvar<Double>&, const ADvari<Double>&);
00291 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00292 const ADvari<Double>&, const IndepADvar<Double>&);
00293 template<typename Double> Double val(const ADvari<Double>&);
00294
00295 template<typename Double> class
00296 ADvari {
00297 public:
00298 typedef Double value_type;
00299 typedef IndepADvar<Double> IndepADVar;
00300 #ifdef RAD_AUTO_AD_Const
00301 friend class IndepADvar<Double>;
00302 #ifdef RAD_Const_WARN
00303 mutable const IndepADVar *padv;
00304 #else
00305 protected:
00306 mutable const IndepADVar *padv;
00307 #endif //RAD_Const_WARN
00308 public:
00309 inline void ADvari_padv(const IndepADVar *v) {
00310 this->padv = v;
00311 }
00312 #endif //RAD_AUTO_AD_Const
00313 #ifdef RAD_DEBUG
00314 int gcgen;
00315 int opno;
00316 static int gcgen_cur, last_opno, zap_gcgen, zap_gcgen1, zap_opno;
00317 static FILE *debug_file;
00318 #endif
00319 Double Val;
00320 mutable Double *aval;
00321 static ADvari *First_ADvari, **Last_ADvari;
00322 ADvari *Next;
00323 private:
00324 inline void Linkup() {
00325 *Last_ADvari = this;
00326 Last_ADvari = &this->Next;
00327 }
00328 public:
00329 void *operator new(size_t len) {
00330 #ifdef RAD_DEBUG
00331 ADvari *rv = (ADvari*)ADvari::adc.Memalloc(len);
00332 rv->gcgen = gcgen_cur;
00333 rv->opno = ++last_opno;
00334 if (last_opno == zap_opno && gcgen_cur == zap_gcgen)
00335 printf("Got to opno %d\n", last_opno);
00336 return rv;
00337 #else
00338 return ADvari::adc.Memalloc(len);
00339 #endif
00340 }
00341 void operator delete(void*) {}
00342 inline ADvari(Double t): Val(t), aval(0) Padvinit { Linkup(); }
00343 inline ADvari(): Val(0.), aval(0) Padvinit { Linkup(); }
00344 #ifdef RAD_AUTO_AD_Const
00345 friend class ADcontext<Double>;
00346 friend class ADvar<Double>;
00347 friend class ADvar1<Double>;
00348 friend class ADvar1s<Double>;
00349 friend class ADvar2<Double>;
00350 friend class ADvar2q<Double>;
00351 friend class ConstADvar<Double>;
00352 ADvari(const IndepADVar *, Double);
00353 #endif
00354 #define F friend
00355 #define R ADvari&
00356 #define Ai const ADvari&
00357 #define T1(r,f) F r f <>(Ai);
00358 #define T2(r,f) \
00359 F r f <>(Ai,Ai); \
00360 F r f <>(Ttype,Ai); \
00361 F r f <>(Ai,Ttype); \
00362 F r f <>(double,Ai); \
00363 F r f <>(Ai,double); \
00364 F r f <>(long,Ai); \
00365 F r f <>(Ai,long); \
00366 F r f <>(int,Ai); \
00367 F r f <>(Ai,int);
00368 T1(R,operator+)
00369 T2(R,operator+)
00370 T1(R,operator-)
00371 T2(R,operator-)
00372 T2(R,operator*)
00373 T2(R,operator/)
00374 T1(R,abs)
00375 T1(R,acos)
00376 T1(R,acosh)
00377 T1(R,asin)
00378 T1(R,asinh)
00379 T1(R,atan)
00380 T1(R,atanh)
00381 T2(R,atan2)
00382 T2(R,max)
00383 T2(R,min)
00384 T1(R,cos)
00385 T1(R,cosh)
00386 T1(R,exp)
00387 T1(R,log)
00388 T1(R,log10)
00389 T2(R,pow)
00390 T1(R,sin)
00391 T1(R,sinh)
00392 T1(R,sqrt)
00393 T1(R,tan)
00394 T1(R,tanh)
00395 T1(R,fabs)
00396 T1(R,copy)
00397 T2(int,operator<)
00398 T2(int,operator<=)
00399 T2(int,operator==)
00400 T2(int,operator!=)
00401 T2(int,operator>=)
00402 T2(int,operator>)
00403 #undef T2
00404 #undef T1
00405 #undef Ai
00406 #undef R
00407 #undef F
00408
00409 friend ADvari& ADf1<>(Double f, Double g, const ADvari &x);
00410 friend ADvari& ADf2<>(Double f, Double gx, Double gy, const ADvari &x, const ADvari &y);
00411 friend ADvari& ADfn<>(Double f, int n, const IndepADVar *x, const Double *g);
00412
00413 inline operator Double() { return this->Val; }
00414 inline operator Double() const { return this->Val; }
00415
00416 static ADcontext<Double> adc;
00417 };
00418
00419 template<typename Double> class
00420 ADvar1: public ADvari<Double> {
00421 public:
00422 typedef ADvari<Double> ADVari;
00423 ADvar1(Double val1): ADVari(val1) {}
00424 Derp<Double> d;
00425 ADvar1(Double val1, const ADVari *c1): ADVari(val1), d(c1) {}
00426 ADvar1(Double val1, const Double *a1, const ADVari *c1):
00427 ADVari(val1), d(a1,this,c1) {}
00428 #ifdef RAD_AUTO_AD_Const
00429 typedef typename ADVari::IndepADVar IndepADVar;
00430 typedef ADvar<Double> ADVar;
00431 ADvar1(const IndepADVar*, const IndepADVar&);
00432 ADvar1(const IndepADVar*, const ADVari&);
00433 ADvar1(const Double val1, const Double *a1, const ADVari *c1, const ADVar *v):
00434 ADVari(val1), d(a1,this,c1) {
00435 c1->padv = 0;
00436 this->ADvari_padv(v);
00437 }
00438 #endif
00439 };
00440
00441
00442 template<typename Double> class
00443 ConstADvari: public ADvari<Double> {
00444 private:
00445 ConstADvari *prevcad;
00446 ConstADvari() {};
00447 static ConstADvari *lastcad;
00448 public:
00449 friend class ADcontext<Double>;
00450 typedef ADvari<Double> ADVari;
00451 typedef Derp<Double> DErp;
00452 static CADcontext<Double> cadc;
00453 inline void *operator new(size_t len) { return ConstADvari::cadc.Memalloc(len); }
00454 inline ConstADvari(Double t): ADVari(t) { prevcad = lastcad; lastcad = this; }
00455 static void aval_reset(void);
00456 };
00457
00458 template<typename Double> class
00459 IndepADvar {
00460 protected:
00461 static void AD_Const(const IndepADvar&);
00462 mutable ADvari<Double> *cv;
00463 private:
00464 IndepADvar& operator=(IndepADvar&x) {
00465
00466 #ifdef RAD_AUTO_AD_Const
00467 if (cv)
00468 cv->padv = 0;
00469 cv = new ADvar1<Double>(this,x);
00470 return *this;
00471 #elif defined(RAD_EQ_ALIAS)
00472 this->cv = x.cv;
00473 return *this;
00474 #else
00475 return ADvar_operatoreq(this,*x.cv);
00476 #endif //RAD_AUTO_AD_Const
00477 }
00478 public:
00479 int Wantderiv(int);
00480 typedef Double value_type;
00481 friend class ADvar<Double>;
00482 friend class ADcontext<Double>;
00483 friend class ADvar1<Double>;
00484 friend class ADvarn<Double>;
00485 typedef ADvari<Double> ADVari;
00486 typedef ADvar<Double> ADVar;
00487 IndepADvar(Ttype);
00488 IndepADvar(double);
00489 IndepADvar(int);
00490 IndepADvar(long);
00491 IndepADvar& operator= (Double);
00492 inline int Wantderiv() { return 1; }
00493 #ifdef RAD_AUTO_AD_Const //{
00494 inline IndepADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1<Double>(this, x) : 0; };
00495 inline IndepADvar() { cv = 0; }
00496 inline ~IndepADvar() {
00497 if (cv)
00498 cv->padv = 0;
00499 }
00500 #else
00501 inline IndepADvar() {
00502 #ifndef RAD_EQ_ALIAS
00503 cv = 0;
00504 #endif
00505 }
00506 inline ~IndepADvar() {}
00507 friend IndepADvar& ADvar_operatoreq<>(IndepADvar*, const ADVari&);
00508 #endif //}
00509
00510 #ifdef RAD_Const_WARN
00511 inline operator ADVari&() const {
00512 ADVari *tcv = this->cv;
00513 if (tcv->opno < 0)
00514 RAD_Const_Warn(tcv);
00515 return *tcv;
00516 }
00517 inline operator ADVari*() const {
00518 ADVari *tcv = this->cv;
00519 if (tcv->opno < 0)
00520 RAD_Const_Warn(tcv);
00521 return tcv;
00522 }
00523 #else //RAD_Const_WARN
00524 inline operator ADVari&() const { return *this->cv; }
00525 inline operator ADVari*() const { return this->cv; }
00526 #endif //RAD_Const_WARN
00527
00528 inline Double val() const {
00529 return cv->Val;
00530 }
00531 inline Double adj() const {
00532 return *cv->aval;
00533 }
00534 inline Double adj(int n) const {
00535 return cv->aval[n];
00536 }
00537
00538 friend void AD_Const1<>(Double*, const IndepADvar&);
00539
00540 friend ADVari& ADf1<>(Double, Double, const IndepADvar&);
00541 friend ADVari& ADf2<>(Double, Double, Double, const IndepADvar&, const IndepADvar&);
00542 friend ADVari& ADf2<>(Double, Double, Double, const ADVari&, const IndepADvar&);
00543 friend ADVari& ADf2<>(Double, Double, Double, const IndepADvar&, const ADVari&);
00544
00545 static inline void Gradcomp() { ADcontext<Double>::Gradcomp(); }
00546 static inline void aval_reset() { ConstADvari<Double>::aval_reset(); }
00547 static inline void Weighted_Gradcomp(size_t n, ADVar **v, Double *w)
00548 { ADcontext<Double>::Weighted_Gradcomp(n, v, w); }
00549 static inline void Weighted_GradcompVec(size_t n, size_t *np, ADVar ***v, Double **w)
00550 { ADcontext<Double>::Weighted_GradcompVec(n, np, v, w); }
00551 static inline void Outvar_Gradcomp(ADVar &v)
00552 { ADcontext<Double>::Outvar_Gradcomp(v); }
00553
00554
00555
00556
00557
00558 #define Ai const ADVari&
00559 #define AI const IndepADvar&
00560 #define D Double
00561 #define T2(r,f) \
00562 r f <>(AI,AI);\
00563 r f <>(Ai,AI);\
00564 r f <>(AI,Ai);\
00565 r f <>(Ttype,AI);\
00566 r f <>(double,AI);\
00567 r f <>(long,AI);\
00568 r f <>(int,AI);\
00569 r f <>(AI,Ttype);\
00570 r f <>(AI,double);\
00571 r f <>(AI,long);\
00572 r f <>(AI,int);
00573 #define T1(f) friend ADVari& f<> (AI);
00574
00575 #define F friend ADVari&
00576 T2(F, operator+)
00577 T2(F, operator-)
00578 T2(F, operator*)
00579 T2(F, operator/)
00580 T2(F, atan2)
00581 T2(F, max)
00582 T2(F, min)
00583 T2(F, pow)
00584 #undef F
00585 #define F friend int
00586 T2(F, operator<)
00587 T2(F, operator<=)
00588 T2(F, operator==)
00589 T2(F, operator!=)
00590 T2(F, operator>=)
00591 T2(F, operator>)
00592
00593 T1(operator+)
00594 T1(operator-)
00595 T1(abs)
00596 T1(acos)
00597 T1(acosh)
00598 T1(asin)
00599 T1(asinh)
00600 T1(atan)
00601 T1(atanh)
00602 T1(cos)
00603 T1(cosh)
00604 T1(exp)
00605 T1(log)
00606 T1(log10)
00607 T1(sin)
00608 T1(sinh)
00609 T1(sqrt)
00610 T1(tan)
00611 T1(tanh)
00612 T1(fabs)
00613 T1(copy)
00614
00615 #undef F
00616 #undef T1
00617 #undef T2
00618 #undef D
00619 #undef AI
00620 #undef Ai
00621
00622 };
00623
00624 template<typename Double> class
00625 ADvar: public IndepADvar<Double> {
00626 public:
00627 typedef IndepADvar<Double> IndepADVar;
00628 typedef typename IndepADVar::ADVari ADVari;
00629 typedef ConstADvari<Double> ConstADVari;
00630 private:
00631 void ADvar_ctr(Double d) {
00632 ADVari *x;
00633 if (ConstADVari::cadc.fpval_implies_const)
00634 x = new ConstADVari(d);
00635 else {
00636 #ifdef RAD_AUTO_AD_Const //{
00637 x = new ADVari((IndepADVar*)this, d);
00638 x->ADvari_padv(this);
00639 #else
00640 x = new ADVari(d);
00641 #endif //}
00642 }
00643 this->cv = x;
00644 }
00645 public:
00646 friend class ADvar1<Double>;
00647 typedef ADvar1<Double> ADVar1;
00648 inline ADvar() { }
00649 inline ADvar(Ttype d) { ADvar_ctr(d); }
00650 inline ADvar(double i) { ADvar_ctr(Double(i)); }
00651 inline ADvar(int i) { ADvar_ctr(Double(i)); }
00652 inline ADvar(long i) { ADvar_ctr(Double(i)); }
00653 inline ~ADvar() {}
00654 #ifdef RAD_AUTO_AD_Const //{{
00655 inline ADvar(IndepADVar &x) {
00656 this->cv = x.cv ? new ADVar1(this, x) : 0;
00657 }
00658 inline ADvar(ADVari &x) { this->cv = &x; x.ADvari_padv(this); }
00659 inline ADvar& operator=(IndepADVar &x) {
00660 if (this->cv)
00661 this->cv->padv = 0;
00662 this->cv = new ADVar1(this,x);
00663 return *this;
00664 }
00665 inline ADvar& operator=(ADVari &x) {
00666 if (this->cv)
00667 this->cv->padv = 0;
00668 this->cv = new ADVar1(this, x);
00669 return *this;
00670 }
00671 #else //}{
00672 friend ADvar& ADvar_operatoreq<>(ADvar*, const ADVari&);
00673 #ifdef RAD_EQ_ALIAS
00674
00675 inline ADvar(const IndepADVar &x) {
00676 this->cv = (ADVari*)x.cv;
00677 }
00678 inline ADvar(const ADVari &x) { this->cv = (ADVari*)&x; }
00679 inline ADvar& operator=(IndepADVar &x) {
00680 this->cv = (ADVari*)x.cv; return *this;
00681 }
00682 inline ADvar& operator=(const ADVari &x) { this->cv = (ADVari*)&x; return *this; }
00683 #else
00684 ADvar(const IndepADVar &x) {
00685 if (x.cv) {
00686 this->cv = new ADVar1(x.cv->Val, &this->cv->adc.One, x.cv);
00687 }
00688 else
00689 this->cv = 0;
00690 }
00691 ADvar(const ADvar&x) {
00692 if (x.cv) {
00693 this->cv = new ADVar1(x.cv->Val, &this->cv->adc.One, (ADVari*)x.cv);
00694 }
00695 else
00696 this->cv = 0;
00697 }
00698 ADvar(const ADVari &x) {
00699 this->cv = new ADVar1(x.Val, &this->cv->adc.One, &x);
00700 }
00701 inline ADvar& operator=(const ADVari &x) { return ADvar_operatoreq(this,x); };
00702 #endif
00703 #endif //}}
00704 ADvar& operator=(Double);
00705 ADvar& operator+=(const ADVari&);
00706 ADvar& operator+=(Double);
00707 ADvar& operator-=(const ADVari&);
00708 ADvar& operator-=(Double);
00709 ADvar& operator*=(const ADVari&);
00710 ADvar& operator*=(Double);
00711 ADvar& operator/=(const ADVari&);
00712 ADvar& operator/=(Double);
00713 inline static bool get_fpval_implies_const(void)
00714 { return ConstADVari::cadc.fpval_implies_const; }
00715 inline static void set_fpval_implies_const(bool newval)
00716 { ConstADVari::cadc.fpval_implies_const = newval; }
00717 inline static bool setget_fpval_implies_const(bool newval) {
00718 bool oldval = ConstADVari::cadc.fpval_implies_const;
00719 ConstADVari::cadc.fpval_implies_const = newval;
00720 return oldval;
00721 }
00722 static inline void Gradcomp() { ADcontext<Double>::Gradcomp(); }
00723 static inline void aval_reset() { ConstADVari::aval_reset(); }
00724 static inline void Weighted_Gradcomp(size_t n, ADvar **v, Double *w)
00725 { ADcontext<Double>::Weighted_Gradcomp(n, v, w); }
00726 static inline void Weighted_GradcompVec(size_t n, size_t *np, ADvar ***v, Double **w)
00727 { ADcontext<Double>::Weighted_GradcompVec(n, np, v, w); }
00728 static inline void Outvar_Gradcomp(ADvar &v)
00729 { ADcontext<Double>::Outvar_Gradcomp(v); }
00730 };
00731
00732 template<typename Double>
00733 inline void AD_Const1(Double *notused, const IndepADvar<Double>&v)
00734 { IndepADvar<Double>::AD_Const(v); }
00735
00736 template<typename Double>
00737 inline void AD_Const(const IndepADvar<Double>&v) { AD_Const1((Double*)0, v); }
00738
00739 template<typename Double> class
00740 ConstADvar: public ADvar<Double> {
00741 public:
00742 typedef ADvar<Double> ADVar;
00743 typedef typename ADVar::ADVar1 ADVar1;
00744 typedef typename ADVar::ADVari ADVari;
00745 typedef typename ADVar::ConstADVari ConstADVari;
00746 typedef Derp<Double> DErp;
00747 typedef typename ADVar::IndepADVar IndepADVar;
00748 private:
00749 ConstADvar& operator+=(ADVari&);
00750 ConstADvar& operator+=(Double);
00751 ConstADvar& operator-=(ADVari&);
00752 ConstADvar& operator-=(Double);
00753 ConstADvar& operator*=(ADVari&);
00754 ConstADvar& operator*=(Double);
00755 ConstADvar& operator/=(ADVari&);
00756 ConstADvar& operator/=(Double);
00757 void ConstADvar_ctr(Double);
00758 public:
00759 ConstADvar(Ttype d) { ConstADvar_ctr(d); }
00760 ConstADvar(double i) { ConstADvar_ctr(Double(i)); }
00761 ConstADvar(int i) { ConstADvar_ctr(Double(i)); }
00762 ConstADvar(long i) { ConstADvar_ctr(Double(i)); }
00763 ConstADvar(const IndepADVar&);
00764 ConstADvar(const ConstADvar&);
00765 ConstADvar(const ADVari&);
00766 inline ~ConstADvar() {}
00767 #ifdef RAD_NO_CONST_UPDATE
00768 private:
00769 #endif
00770 ConstADvar();
00771 inline ConstADvar& operator=(Double d) {
00772 this->cv->Val = d;
00773 return *this;
00774 }
00775 inline ConstADvar& operator=(ADVari& d) {
00776 this->cv->Val = d.Val;
00777 return *this;
00778 }
00779 };
00780
00781 #define ADvar_nd ADvar
00782
00783 template<typename Double> class
00784 ADvar1s: public ADvar1<Double> {
00785 public:
00786 typedef ADvar1<Double> ADVar1;
00787 typedef typename ADVar1::ADVari ADVari;
00788 Double a;
00789 ADvar1s(Double val1, Double a1, const ADVari *c1): ADVar1(val1,&a,c1), a(a1) {}
00790 #ifdef RAD_AUTO_AD_Const
00791 typedef typename ADVar1::ADVar ADVar;
00792 ADvar1s(Double val1, Double a1, const ADVari *c1, const ADVar *v):
00793 ADVar1(val1,&a,c1,v), a(a1) {}
00794 #endif
00795 };
00796
00797 template<typename Double> class
00798 ADvar2: public ADvari<Double> {
00799 public:
00800 typedef ADvari<Double> ADVari;
00801 typedef Derp<Double> DErp;
00802 ADvar2(Double val1): ADVari(val1) {}
00803 DErp dL, dR;
00804 ADvar2(Double val1, const ADVari *Lcv, const Double *Lc,
00805 const ADVari *Rcv, const Double *Rc):
00806 ADVari(val1) {
00807 dR.next = DErp::LastDerp;
00808 dL.next = &dR;
00809 DErp::LastDerp = &dL;
00810 dL.a = Lc;
00811 dL.c = Lcv;
00812 dR.a = Rc;
00813 dR.c = Rcv;
00814 dL.b = dR.b = this;
00815 }
00816 #ifdef RAD_AUTO_AD_Const
00817 typedef ADvar<Double> ADVar;
00818 ADvar2(Double val1, const ADVari *Lcv, const Double *Lc,
00819 const ADVari *Rcv, const Double *Rc, ADVar *v):
00820 ADVari(val1) {
00821 dR.next = DErp::LastDerp;
00822 dL.next = &dR;
00823 DErp::LastDerp = &dL;
00824 dL.a = Lc;
00825 dL.c = Lcv;
00826 dR.a = Rc;
00827 dR.c = Rcv;
00828 dL.b = dR.b = this;
00829 Lcv->padv = 0;
00830 this->ADvari_padv(v);
00831 }
00832 #endif
00833 };
00834
00835 template<typename Double> class
00836 ADvar2q: public ADvar2<Double> {
00837 public:
00838 typedef ADvar2<Double> ADVar2;
00839 typedef typename ADVar2::ADVari ADVari;
00840 typedef typename ADVar2::DErp DErp;
00841 Double a, b;
00842 ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv, const ADVari *Rcv):
00843 ADVar2(val1), a(Lp), b(Rp) {
00844 this->dR.next = DErp::LastDerp;
00845 this->dL.next = &this->dR;
00846 DErp::LastDerp = &this->dL;
00847 this->dL.a = &a;
00848 this->dL.c = Lcv;
00849 this->dR.a = &b;
00850 this->dR.c = Rcv;
00851 this->dL.b = this->dR.b = this;
00852 }
00853 #ifdef RAD_AUTO_AD_Const
00854 typedef typename ADVar2::ADVar ADVar;
00855 ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv,
00856 const ADVari *Rcv, const ADVar *v):
00857 ADVar2(val1), a(Lp), b(Rp) {
00858 this->dR.next = DErp::LastDerp;
00859 this->dL.next = &this->dR;
00860 DErp::LastDerp = &this->dL;
00861 this->dL.a = &a;
00862 this->dL.c = Lcv;
00863 this->dR.a = &b;
00864 this->dR.c = Rcv;
00865 this->dL.b = this->dR.b = this;
00866 Lcv->padv = 0;
00867 this->ADvari_padv(v);
00868 }
00869 #endif
00870 };
00871
00872 template<typename Double> class
00873 ADvarn: public ADvari<Double> {
00874 public:
00875 typedef ADvari<Double> ADVari;
00876 typedef typename ADVari::IndepADVar IndepADVar;
00877 typedef Derp<Double> DErp;
00878 int n;
00879 Double *a;
00880 DErp *Da;
00881 ADvarn(Double val1, int n1, const IndepADVar *x, const Double *g):
00882 ADVari(val1), n(n1) {
00883 DErp *d1, *dlast;
00884 Double *a1;
00885 int i;
00886
00887 a1 = a = (Double*)ADVari::adc.Memalloc(n*sizeof(*a));
00888 d1 = Da = (DErp*)ADVari::adc.Memalloc(n*sizeof(DErp));
00889 dlast = DErp::LastDerp;
00890 for(i = 0; i < n1; i++, d1++) {
00891 d1->next = dlast;
00892 dlast = d1;
00893 a1[i] = g[i];
00894 d1->a = &a1[i];
00895 d1->b = this;
00896 d1->c = x[i].cv;
00897 }
00898 DErp::LastDerp = dlast;
00899 }
00900 };
00901
00902 template<typename Double>
00903 inline ADvari<Double>& operator+(const ADvari<Double> &T) { return *(ADvari<Double>*)&T; }
00904
00905 template<typename Double>
00906 inline int operator<(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val < R.Val; }
00907 template<typename Double>
00908 inline int operator<(const ADvari<Double> &L, Double R) { return L.Val < R; }
00909 template<typename Double>
00910 inline int operator<(Double L, const ADvari<Double> &R) { return L < R.Val; }
00911
00912 template<typename Double>
00913 inline int operator<=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val <= R.Val; }
00914 template<typename Double>
00915 inline int operator<=(const ADvari<Double> &L, Double R) { return L.Val <= R; }
00916 template<typename Double>
00917 inline int operator<=(Double L, const ADvari<Double> &R) { return L <= R.Val; }
00918
00919 template<typename Double>
00920 inline int operator==(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val == R.Val; }
00921 template<typename Double>
00922 inline int operator==(const ADvari<Double> &L, Double R) { return L.Val == R; }
00923 template<typename Double>
00924 inline int operator==(Double L, const ADvari<Double> &R) { return L == R.Val; }
00925
00926 template<typename Double>
00927 inline int operator!=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val != R.Val; }
00928 template<typename Double>
00929 inline int operator!=(const ADvari<Double> &L, Double R) { return L.Val != R; }
00930 template<typename Double>
00931 inline int operator!=(Double L, const ADvari<Double> &R) { return L != R.Val; }
00932
00933 template<typename Double>
00934 inline int operator>=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val >= R.Val; }
00935 template<typename Double>
00936 inline int operator>=(const ADvari<Double> &L, Double R) { return L.Val >= R; }
00937 template<typename Double>
00938 inline int operator>=(Double L, const ADvari<Double> &R) { return L >= R.Val; }
00939
00940 template<typename Double>
00941 inline int operator>(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val > R.Val; }
00942 template<typename Double>
00943 inline int operator>(const ADvari<Double> &L, Double R) { return L.Val > R; }
00944 template<typename Double>
00945 inline int operator>(Double L, const ADvari<Double> &R) { return L > R.Val; }
00946
00947 template<typename Double>
00948 inline void *ADcontext<Double>::Memalloc(size_t len) {
00949 if (Mleft >= len)
00950 return Mbase + (Mleft -= len);
00951 return new_ADmemblock(len);
00952 }
00953
00954 template<typename Double>
00955 inline Derp<Double>::Derp(const ADVari *c1): c(c1) {
00956 next = LastDerp;
00957 LastDerp = this;
00958 }
00959
00960 template<typename Double>
00961 inline Derp<Double>::Derp(const Double *a1, const ADVari *c1): a(a1), c(c1) {
00962 next = LastDerp;
00963 LastDerp = this;
00964 }
00965
00966
00967 template<typename Double>
00968 inline Derp<Double>::Derp(const Double *a1, const ADVari *b1, const ADVari *c1): a(a1), b(b1), c(c1) {
00969 next = LastDerp;
00970 LastDerp = this;
00971 }
00972
00973
00974
00975 template<typename Double> Derp<Double> *Derp<Double>::LastDerp = 0;
00976 template<typename Double> ADcontext<Double> ADvari<Double>::adc;
00977 template<typename Double> const Double ADcontext<Double>::One = 1.;
00978 template<typename Double> const Double ADcontext<Double>::negOne = -1.;
00979 template<typename Double> CADcontext<Double> ConstADvari<Double>::cadc;
00980 template<typename Double> ConstADvari<Double> *ConstADvari<Double>::lastcad;
00981
00982 template<typename Double> ADvari<Double>* ADvari<Double>::First_ADvari;
00983 template<typename Double> ADvari<Double>** ADvari<Double>::Last_ADvari = &ADvari<Double>::First_ADvari;
00984
00985 #ifdef RAD_DEBUG
00986 #ifndef RAD_DEBUG_gcgen1
00987 #define RAD_DEBUG_gcgen1 -1
00988 #endif
00989 template<typename Double> int ADvari<Double>::gcgen_cur;
00990 template<typename Double> int ADvari<Double>::last_opno;
00991 template<typename Double> int ADvari<Double>::zap_gcgen;
00992 template<typename Double> int ADvari<Double>::zap_gcgen1 = RAD_DEBUG_gcgen1;
00993 template<typename Double> int ADvari<Double>::zap_opno;
00994 template<typename Double> FILE *ADvari<Double>::debug_file;
00995 #endif
00996
00997
00998 template<typename Double> ADcontext<Double>::ADcontext()
00999 {
01000 First = new ADMemblock;
01001 First->next = 0;
01002 Busy = First;
01003 Free = Oldbusy = 0;
01004 Mbase = (char*)First->memblk;
01005 Mleft = sizeof(First->memblk);
01006 ncur = nmax = rad_need_reinit = 0;
01007 #ifdef RAD_DEBUG_BLOCKKEEP
01008 rad_busy_blocks = 0;
01009 rad_mleft_save = 0;
01010 rad_Oldcurmb = 0;
01011 #endif
01012 }
01013
01014 template<typename Double> void*
01015 ADcontext<Double>::new_ADmemblock(size_t len)
01016 {
01017 ADMemblock *mb, *mb0, *mb1, *mbf, *x;
01018 #ifdef RAD_AUTO_AD_Const
01019 ADVari *a, *anext;
01020 IndepADvar<Double> *v;
01021 #ifdef RAD_Const_WARN
01022 ADVari *cv;
01023 int i, j;
01024 #endif
01025 #endif
01026
01027 if (rad_need_reinit && this == &ADVari::adc) {
01028 rad_need_reinit = 0;
01029 nmax = 0;
01030 DErp::LastDerp = 0;
01031 ADVari::Last_ADvari = &ADVari::First_ADvari;
01032 #ifdef RAD_DEBUG_BLOCKKEEP
01033 Mleft = rad_mleft_save;
01034 if (Mleft < sizeof(First->memblk))
01035 _uninit_f2c(Mbase + Mleft,
01036 UninitType<Double>::utype,
01037 (sizeof(First->memblk) - Mleft)
01038 /sizeof(typename Sacado::ValueType<Double>::type));
01039 if ((mb = Busy->next)) {
01040 mb0 = rad_Oldcurmb;
01041 for(;; mb = mb->next) {
01042 _uninit_f2c(mb->memblk,
01043 UninitType<Double>::utype,
01044 sizeof(First->memblk)
01045 /sizeof(typename Sacado::ValueType<Double>::type));
01046 if (mb == mb0)
01047 break;
01048 }
01049 }
01050 rad_Oldcurmb = Busy;
01051 if (rad_busy_blocks >= RAD_DEBUG_BLOCKKEEP) {
01052 rad_busy_blocks = 0;
01053 rad_Oldcurmb = 0;
01054 mb0 = 0;
01055 mbf = Free;
01056 for(mb = Busy; mb != mb0; mb = mb1) {
01057 mb1 = mb->next;
01058 mb->next = mbf;
01059 mbf = mb;
01060 }
01061 Free = mbf;
01062 Busy = mb;
01063 Mbase = (char*)First->memblk;
01064 Mleft = sizeof(First->memblk);
01065 }
01066
01067 #else
01068
01069 mb0 = First;
01070 mbf = Free;
01071 for(mb = Busy; mb != mb0; mb = mb1) {
01072 mb1 = mb->next;
01073 mb->next = mbf;
01074 mbf = mb;
01075 }
01076 Free = mbf;
01077 Busy = mb;
01078 Mbase = (char*)First->memblk;
01079 Mleft = sizeof(First->memblk);
01080 #endif
01081 #ifdef RAD_AUTO_AD_Const
01082 if ((a = ADVari::First_ADvari)) {
01083 do {
01084 anext = a->Next;
01085 if ((v = (IndepADvar<Double> *)a->padv)) {
01086 #ifdef RAD_Const_WARN
01087 if ((i = a->opno) > 0)
01088 i = -i;
01089 j = a->gcgen;
01090 v->cv = cv = new ADVari(v, a->Val);
01091 cv->opno = i;
01092 cv->gcgen = j;
01093 #else
01094 v->cv = new ADVari(v, a->Val);
01095 #endif
01096 }
01097 }
01098 while((a = anext));
01099 }
01100 #endif // } RAD_AUTO_AD_Const
01101 if (Mleft >= len)
01102 return Mbase + (Mleft -= len);
01103 }
01104
01105 if ((x = Free))
01106 Free = x->next;
01107 else
01108 x = new ADMemblock;
01109 #ifdef RAD_DEBUG_BLOCKKEEP
01110 rad_busy_blocks++;
01111 #endif
01112 x->next = Busy;
01113 Busy = x;
01114 return (Mbase = (char*)x->memblk) +
01115 (Mleft = sizeof(First->memblk) - len);
01116 }
01117
01118 template<typename Double> void
01119 ADcontext<Double>::derp_init(size_t n)
01120 {
01121 ADMemblock *mb, *mb0, *mb1, *mbf;
01122 ADVari *a;
01123 ConstADvari<Double> *c;
01124 Double *d, *de;
01125 size_t len;
01126
01127 if (!rad_need_reinit) {
01128 rad_mleft_save = Mleft;
01129 Oldbusy = Busy;
01130 }
01131 len = n * sizeof(Double);
01132 ncur = n;
01133 if (!nmax) {
01134 if (n > 0)
01135 goto aval_alloc;
01136 }
01137 else if (n > nmax) {
01138 mb0 = Oldbusy;
01139 mb = Busy;
01140 if (mb != mb0) {
01141 mbf = Free;
01142 do {
01143 mb1 = mb->next;
01144 mb->next = mbf;
01145 mbf = mb;
01146 mb = mb1;
01147 }
01148 while(mb != mb0);
01149 Free = mbf;
01150 }
01151 Mleft = rad_mleft_save;
01152 Busy = Oldbusy;
01153 aval_alloc:
01154 rad_need_reinit = 0;
01155 nmax = n;
01156 *ADVari::Last_ADvari = 0;
01157 for(a = ADVari::First_ADvari; a; a = a->Next) {
01158 d = a->aval = (Double*)Memalloc(len);
01159 de = d + n;
01160 do *d = 0.; while(++d < de);
01161 }
01162 for(c = ConstADvari<Double>::lastcad; c; c = c->prevcad) {
01163 d = c->aval = (Double*)Memalloc(len);
01164 de = d + n;
01165 do *d = 0.; while(++d < de);
01166 }
01167 }
01168 else if (!n) {
01169 nmax = 0;
01170 for(a = ADVari::First_ADvari; a; a = a->Next)
01171 a->aval = 0;
01172 }
01173 else for(a = ADVari::First_ADvari; a; a = a->Next) {
01174 d = a->aval;
01175 de = d + n;
01176 do *d = 0.; while(++d < de);
01177 }
01178 Mleft = 0;
01179 rad_need_reinit = 1;
01180 #ifdef RAD_DEBUG
01181 if (ADVari::gcgen_cur == ADVari::zap_gcgen1) {
01182 const char *fname;
01183 if (!(fname = getenv("RAD_DEBUG_FILE")))
01184 fname = "rad_debug.out";
01185 else if (!*fname)
01186 fname = 0;
01187 if (fname)
01188 ADVari::debug_file = fopen(fname, "w");
01189 ADVari::zap_gcgen1 = -1;
01190 }
01191 #endif
01192 }
01193
01194 template<typename Double> void
01195 ADcontext<Double>::Gradcomp()
01196 {
01197 DErp *d;
01198 #ifdef RAD_AUTO_AD_Const
01199 ADVari *a, *anext;
01200 IndepADvar<Double> *v;
01201 #ifdef RAD_Const_WARN
01202 ADVari *cv;
01203 int i, j;
01204 #endif
01205 #endif
01206
01207 ADVari::adc.derp_init(1);
01208 if ((d = DErp::LastDerp)) {
01209 *d->b->aval = 1;
01210 #ifdef RAD_DEBUG
01211 if (ADVari::debug_file)
01212 do {
01213 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01214 d->c->opno, d->b->opno, &d->c->aval, *d->a, *d->b->aval);
01215 d->c->aval += *d->a * d->b->aval;
01216 fprintf(ADVari::debug_file, " = %g\n", *d->c->aval);
01217 } while((d = d->next));
01218 else
01219 #endif
01220 do *d->c->aval += *d->a * *d->b->aval;
01221 while((d = d->next));
01222 }
01223 #ifdef RAD_DEBUG
01224 if (ADVari::debug_file) {
01225 fclose(ADVari::debug_file);
01226 ADVari::debug_file = 0;
01227 }
01228 ADVari::gcgen_cur++;
01229 ADVari::last_opno = 0;
01230 #endif
01231 }
01232
01233 template<typename Double> void
01234 ADcontext<Double>::Weighted_Gradcomp(size_t n, ADVar **V, Double *w)
01235 {
01236 size_t i;
01237 DErp *d;
01238 #ifdef RAD_AUTO_AD_Const
01239 ADVari *a, *anext;
01240 IndepADvar<Double> *v;
01241 #ifdef RAD_Const_WARN
01242 ADVari *cv;
01243 int j, k;
01244 #endif
01245 #endif
01246
01247 ADVari::adc.derp_init(1);
01248
01249 if (d = DErp::LastDerp) {
01250 for(i = 0; i < n; i++)
01251 *V[i]->cv->aval = w[i];
01252 #ifdef RAD_DEBUG
01253 if (ADVari::debug_file)
01254 do {
01255 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01256 d->c->opno, d->b->opno, *d->c->aval, *d->a, *d->b->aval);
01257 *d->c->aval += *d->a * *d->b->aval;
01258 fprintf(ADVari::debug_file, " = %g\n", *d->c->aval);
01259 } while((d = d->next));
01260 else
01261 #endif
01262 do *d->c->aval += *d->a * *d->b->aval;
01263 while((d = d->next));
01264 }
01265 #ifdef RAD_DEBUG
01266 if (ADVari::debug_file) {
01267 fclose(ADVari::debug_file);
01268 ADVari::debug_file = 0;
01269 }
01270 if (ADVari::debug_file)
01271 fflush(ADVari::debug_file);
01272 ADVari::gcgen_cur++;
01273 ADVari::last_opno = 0;
01274 #endif
01275 }
01276
01277 template<typename Double> void
01278 ADcontext<Double>::Weighted_GradcompVec(size_t n, size_t *np, ADVar ***V, Double **w)
01279 {
01280 size_t i, ii, ni;
01281 ADVar **Vi;
01282 DErp *d;
01283 Double A, *D, *D1, *De, *wi;
01284 #ifdef RAD_AUTO_AD_Const
01285 ADVari *a, *anext;
01286 IndepADvar<Double> *v;
01287 #ifdef RAD_Const_WARN
01288 ADVari *cv;
01289 int j, k;
01290 #endif
01291 #endif
01292
01293 ADVari::adc.derp_init(n);
01294 if (!n)
01295 return;
01296
01297 if (d = DErp::LastDerp) {
01298 for(i = 0; i < n; i++) {
01299 ni = np[i];
01300 wi = w[i];
01301 Vi = V[i];
01302 for(ii = 0; ii < ni; ++ii)
01303 Vi[ii]->cv->aval[i] = wi[ii];
01304 }
01305 #ifdef RAD_DEBUG
01306 if (ADVari::debug_file)
01307 do {
01308 D = d->c->aval;
01309 De = D + n;
01310 D1 = d->b->aval;
01311 A = *d->a;
01312 for(i = 0; i < n; ++i, ++D, ++D1) {
01313 fprintf(ADVari::debug_file, "%d:\t%d\t%d\t%g + %g * %g",
01314 i, d->c->opno, d->b->opno, *D, A, *D1);
01315 *D += A * *D1;
01316 fprintf(ADVari::debug_file, " = %g\n", *D);
01317 }
01318 } while((d = d->next));
01319 else
01320 #endif
01321 do {
01322 D = d->c->aval;
01323 De = D + n;
01324 D1 = d->b->aval;
01325 A = *d->a;
01326 do *D++ += A * *D1++; while(D < De);
01327 }
01328 while((d = d->next));
01329 }
01330 #ifdef RAD_DEBUG
01331 if (ADVari::debug_file) {
01332 fclose(ADVari::debug_file);
01333 ADVari::debug_file = 0;
01334 }
01335 if (ADVari::debug_file)
01336 fflush(ADVari::debug_file);
01337 ADVari::gcgen_cur++;
01338 ADVari::last_opno = 0;
01339 #endif
01340 }
01341
01342 template<typename Double> void
01343 ADcontext<Double>::Outvar_Gradcomp(ADVar &V)
01344 {
01345 Double w = 1;
01346 ADVar *v = &V;
01347 ADcontext<Double>::Weighted_Gradcomp(1, &v, &w);
01348 }
01349
01350 template<typename Double>
01351 IndepADvar<Double>::IndepADvar(Ttype d)
01352 {
01353 cv = new ADVari(d);
01354 }
01355
01356 template<typename Double>
01357 IndepADvar<Double>::IndepADvar(double i)
01358 {
01359 cv = new ADVari(Double(i));
01360 }
01361
01362 template<typename Double>
01363 IndepADvar<Double>::IndepADvar(int i)
01364 {
01365 cv = new ADVari(Double(i));
01366 }
01367
01368 template<typename Double>
01369 IndepADvar<Double>::IndepADvar(long i)
01370 {
01371 cv = new ADVari(Double(i));
01372 }
01373
01374 template<typename Double>
01375 ConstADvar<Double>::ConstADvar()
01376 {
01377 this->cv = new ConstADVari(0.);
01378 }
01379
01380 template<typename Double> void
01381 ConstADvar<Double>::ConstADvar_ctr(Double d)
01382 {
01383 this->cv = new ConstADVari(d);
01384 }
01385
01386 template<typename Double>
01387 ConstADvar<Double>::ConstADvar(const IndepADVar &x)
01388 {
01389 ConstADVari *y = new ConstADVari(x.cv->Val);
01390 DErp *d = new DErp(&x.adc.One, y, x.cv);
01391 this->cv = y;
01392 }
01393
01394 template<typename Double>
01395 ConstADvar<Double>::ConstADvar(const ConstADvar &x)
01396 {
01397 ConstADVari *y = new ConstADVari(x.cv->Val);
01398 DErp *d = new DErp(&x.cv->adc.One, y, (ADVari*)x.cv);
01399 this->cv = y;
01400 }
01401
01402 template<typename Double>
01403 ConstADvar<Double>::ConstADvar(const ADVari &x)
01404 {
01405 ConstADVari *y = new ConstADVari(x.Val);
01406 DErp *d = new DErp(&x.adc.One, y, &x);
01407 this->cv = y;
01408 }
01409
01410 template<typename Double>
01411 void
01412 IndepADvar<Double>::AD_Const(const IndepADvar &v)
01413 {
01414 typedef ConstADvari<Double> ConstADVari;
01415
01416 ConstADVari *ncv = new ConstADVari(v.val());
01417 #ifdef RAD_AUTO_AD_Const
01418 v.cv->padv = 0;
01419 #endif
01420 v.cv = ncv;
01421 }
01422
01423 template<typename Double>
01424 int
01425 IndepADvar<Double>::Wantderiv(int n)
01426 {
01427 return 1;
01428 }
01429
01430 template<typename Double>
01431 void
01432 ConstADvari<Double>::aval_reset()
01433 {
01434 ConstADvari *x = ConstADvari::lastcad;
01435 while(x) {
01436 x->aval = 0;
01437 x = x->prevcad;
01438 }
01439 }
01440
01441 #ifdef RAD_AUTO_AD_Const
01442
01443 template<typename Double>
01444 ADvari<Double>::ADvari(const IndepADVar *x, Double d): Val(d), aval(0)
01445 {
01446 this->ADvari_padv(x);
01447 Linkup();
01448 }
01449
01450 template<typename Double>
01451 ADvar1<Double>::ADvar1(const IndepADVar *x, const IndepADVar &y):
01452 ADVari(y.cv->Val), d((const Double*)&ADcontext<Double>::One, (ADVari*)this, y.cv)
01453 {
01454 this->ADvari_padv(x);
01455 }
01456
01457 template<typename Double>
01458 ADvar1<Double>::ADvar1(const IndepADVar *x, const ADVari &y):
01459 ADVari(y.Val), d((const Double*)&ADcontext<Double>::One, this, &y)
01460 {
01461 this->ADvari_padv(x);
01462 }
01463
01464 #else
01465
01466 template<typename Double>
01467 IndepADvar<Double>&
01468 ADvar_operatoreq(IndepADvar<Double> *This, const ADvari<Double> &x)
01469 {
01470 This->cv = new ADvar1<Double>(x.Val, &x.adc.One, &x);
01471 return *(IndepADvar<Double>*) This;
01472 }
01473
01474 template<typename Double>
01475 ADvar<Double>&
01476 ADvar_operatoreq(ADvar<Double> *This, const ADvari<Double> &x)
01477 {
01478 This->cv = new ADvar1<Double>(x.Val, &x.adc.One, &x);
01479 return *(ADvar<Double>*) This;
01480 }
01481
01482 #endif
01483
01484
01485 template<typename Double>
01486 IndepADvar<Double>&
01487 IndepADvar<Double>::operator=(Double d)
01488 {
01489 #ifdef RAD_AUTO_AD_Const
01490 if (this->cv)
01491 this->cv->padv = 0;
01492 this->cv = new ADVari(this,d);
01493 #else
01494 this->cv = new ADVari(d);
01495 #endif
01496 return *this;
01497 }
01498
01499 template<typename Double>
01500 ADvar<Double>&
01501 ADvar<Double>::operator=(Double d)
01502 {
01503 #ifdef RAD_AUTO_AD_Const
01504 if (this->cv)
01505 this->cv->padv = 0;
01506 this->cv = new ADVari(this,d);
01507 #else
01508 this->cv = ConstADVari::cadc.fpval_implies_const
01509 ? new ConstADVari(d)
01510 : new ADVari(d);
01511 #endif
01512 return *this;
01513 }
01514
01515 template<typename Double>
01516 ADvari<Double>&
01517 operator-(const ADvari<Double> &T) {
01518 return *(new ADvar1<Double>(-T.Val, &T.adc.negOne, &T));
01519 }
01520
01521 template<typename Double>
01522 ADvari<Double>&
01523 operator+(const ADvari<Double> &L, const ADvari<Double> &R) {
01524 return *(new ADvar2<Double>(L.Val + R.Val, &L, &L.adc.One, &R, &L.adc.One));
01525 }
01526
01527 #ifdef RAD_AUTO_AD_Const
01528 #define RAD_ACA ,this
01529 #else
01530 #define RAD_ACA
01531 #endif
01532
01533 template<typename Double>
01534 ADvar<Double>&
01535 ADvar<Double>::operator+=(const ADVari &R) {
01536 ADVari *Lcv = this->cv;
01537 this->cv = new ADvar2<Double>(Lcv->Val + R.Val, Lcv, &R.adc.One, &R, &R.adc.One RAD_ACA);
01538 return *this;
01539 }
01540
01541 template<typename Double>
01542 ADvari<Double>&
01543 operator+(const ADvari<Double> &L, Double R) {
01544 return *(new ADvar1<Double>(L.Val + R, &L.adc.One, &L));
01545 }
01546
01547 template<typename Double>
01548 ADvar<Double>&
01549 ADvar<Double>::operator+=(Double R) {
01550 ADVari *tcv = this->cv;
01551 this->cv = new ADVar1(tcv->Val + R, &tcv->adc.One, tcv RAD_ACA);
01552 return *this;
01553 }
01554
01555 template<typename Double>
01556 ADvari<Double>&
01557 operator+(Double L, const ADvari<Double> &R) {
01558 return *(new ADvar1<Double>(L + R.Val, &R.adc.One, &R));
01559 }
01560
01561 template<typename Double>
01562 ADvari<Double>&
01563 operator-(const ADvari<Double> &L, const ADvari<Double> &R) {
01564 return *(new ADvar2<Double>(L.Val - R.Val, &L, &L.adc.One, &R, &L.adc.negOne));
01565 }
01566
01567 template<typename Double>
01568 ADvar<Double>&
01569 ADvar<Double>::operator-=(const ADVari &R) {
01570 ADVari *Lcv = this->cv;
01571 this->cv = new ADvar2<Double>(Lcv->Val - R.Val, Lcv, &R.adc.One, &R, &R.adc.negOne RAD_ACA);
01572 return *this;
01573 }
01574
01575 template<typename Double>
01576 ADvari<Double>&
01577 operator-(const ADvari<Double> &L, Double R) {
01578 return *(new ADvar1<Double>(L.Val - R, &L.adc.One, &L));
01579 }
01580
01581 template<typename Double>
01582 ADvar<Double>&
01583 ADvar<Double>::operator-=(Double R) {
01584 ADVari *tcv = this->cv;
01585 this->cv = new ADVar1(tcv->Val - R, &tcv->adc.One, tcv RAD_ACA);
01586 return *this;
01587 }
01588
01589 template<typename Double>
01590 ADvari<Double>&
01591 operator-(Double L, const ADvari<Double> &R) {
01592 return *(new ADvar1<Double>(L - R.Val, &R.adc.negOne, &R));
01593 }
01594
01595 template<typename Double>
01596 ADvari<Double>&
01597 operator*(const ADvari<Double> &L, const ADvari<Double> &R) {
01598 return *(new ADvar2<Double>(L.Val * R.Val, &L, &R.Val, &R, &L.Val));
01599 }
01600
01601 template<typename Double>
01602 ADvar<Double>&
01603 ADvar<Double>::operator*=(const ADVari &R) {
01604 ADVari *Lcv = this->cv;
01605 this->cv = new ADvar2<Double>(Lcv->Val * R.Val, Lcv, &R.Val, &R, &Lcv->Val RAD_ACA);
01606 return *this;
01607 }
01608
01609 template<typename Double>
01610 ADvari<Double>&
01611 operator*(const ADvari<Double> &L, Double R) {
01612 return *(new ADvar1s<Double>(L.Val * R, R, &L));
01613 }
01614
01615 template<typename Double>
01616 ADvar<Double>&
01617 ADvar<Double>::operator*=(Double R) {
01618 ADVari *Lcv = this->cv;
01619 this->cv = new ADvar1s<Double>(Lcv->Val * R, R, Lcv RAD_ACA);
01620 return *this;
01621 }
01622
01623 template<typename Double>
01624 ADvari<Double>&
01625 operator*(Double L, const ADvari<Double> &R) {
01626 return *(new ADvar1s<Double>(L * R.Val, L, &R));
01627 }
01628
01629 template<typename Double>
01630 ADvari<Double>&
01631 operator/(const ADvari<Double> &L, const ADvari<Double> &R) {
01632 Double Lv = L.Val, Rv = R.Val, pL = 1. / Rv, q = Lv/Rv;
01633 return *(new ADvar2q<Double>(q, pL, -q*pL, &L, &R));
01634 }
01635
01636 template<typename Double>
01637 ADvar<Double>&
01638 ADvar<Double>::operator/=(const ADVari &R) {
01639 ADVari *Lcv = this->cv;
01640 Double Lv = Lcv->Val, Rv = R.Val, pL = 1. / Rv, q = Lv/Rv;
01641 this->cv = new ADvar2q<Double>(q, pL, -q*pL, Lcv, &R RAD_ACA);
01642 return *this;
01643 }
01644
01645 template<typename Double>
01646 ADvari<Double>&
01647 operator/(const ADvari<Double> &L, Double R) {
01648 return *(new ADvar1s<Double>(L.Val / R, 1./R, &L));
01649 }
01650
01651 template<typename Double>
01652 ADvari<Double>&
01653 operator/(Double L, const ADvari<Double> &R) {
01654 Double recip = 1. / R.Val;
01655 Double q = L * recip;
01656 return *(new ADvar1s<Double>(q, -q*recip, &R));
01657 }
01658
01659 template<typename Double>
01660 ADvar<Double>&
01661 ADvar<Double>::operator/=(Double R) {
01662 ADVari *Lcv = this->cv;
01663 this->cv = new ADvar1s<Double>(Lcv->Val / R, 1./R, Lcv RAD_ACA);
01664 return *this;
01665 }
01666
01667 template<typename Double>
01668 ADvari<Double>&
01669 acos(const ADvari<Double> &v) {
01670 Double t = v.Val;
01671 return *(new ADvar1s<Double>(std::acos(t), -1./std::sqrt(1. - t*t), &v));
01672 }
01673
01674 template<typename Double>
01675 ADvari<Double>&
01676 acosh(const ADvari<Double> &v) {
01677 Double t = v.Val, t1 = std::sqrt(t*t - 1.);
01678 return *(new ADvar1s<Double>(std::log(t + t1), 1./t1, &v));
01679 }
01680
01681 template<typename Double>
01682 ADvari<Double>&
01683 asin(const ADvari<Double> &v) {
01684 Double t = v.Val;
01685 return *(new ADvar1s<Double>(std::asin(t), 1./std::sqrt(1. - t*t), &v));
01686 }
01687
01688 template<typename Double>
01689 ADvari<Double>&
01690 asinh(const ADvari<Double> &v) {
01691 Double t = v.Val, td = 1., t1 = std::sqrt(t*t + 1.);
01692 if (t < 0.) {
01693 t = -t;
01694 td = -1.;
01695 }
01696 return *(new ADvar1s<Double>(td*std::log(t + t1), 1./t1, &v));
01697 }
01698
01699 template<typename Double>
01700 ADvari<Double>&
01701 atan(const ADvari<Double> &v) {
01702 Double t = v.Val;
01703 return *(new ADvar1s<Double>(std::atan(t), 1./(1. + t*t), &v));
01704 }
01705
01706 template<typename Double>
01707 ADvari<Double>&
01708 atanh(const ADvari<Double> &v) {
01709 Double t = v.Val;
01710 return *(new ADvar1s<Double>(0.5*std::log((1.+t)/(1.-t)), 1./(1. - t*t), &v));
01711 }
01712
01713 template<typename Double>
01714 ADvari<Double>&
01715 atan2(const ADvari<Double> &L, const ADvari<Double> &R) {
01716 Double x = L.Val, y = R.Val, t = x*x + y*y;
01717 return *(new ADvar2q<Double>(std::atan2(x,y), y/t, -x/t, &L, &R));
01718 }
01719
01720 template<typename Double>
01721 ADvari<Double>&
01722 atan2(Double x, const ADvari<Double> &R) {
01723 Double y = R.Val, t = x*x + y*y;
01724 return *(new ADvar1s<Double>(std::atan2(x,y), -x/t, &R));
01725 }
01726
01727 template<typename Double>
01728 ADvari<Double>&
01729 atan2(const ADvari<Double> &L, Double y) {
01730 Double x = L.Val, t = x*x + y*y;
01731 return *(new ADvar1s<Double>(std::atan2(x,y), y/t, &L));
01732 }
01733
01734 template<typename Double>
01735 ADvari<Double>&
01736 max(const ADvari<Double> &L, const ADvari<Double> &R) {
01737 const ADvari<Double> &x = L.Val >= R.Val ? L : R;
01738 return *(new ADvar1<Double>(x.Val, &x.adc.One, &x));
01739 }
01740
01741 template<typename Double>
01742 ADvari<Double>&
01743 max(Double L, const ADvari<Double> &R) {
01744 if (L >= R.Val)
01745 return *(new ADvari<Double>(L));
01746 return *(new ADvar1<Double>(R.Val, &R.adc.One, &R));
01747 }
01748
01749 template<typename Double>
01750 ADvari<Double>&
01751 max(const ADvari<Double> &L, Double R) {
01752 if (L.Val >= R)
01753 return *(new ADvar1<Double>(L.Val, &L.adc.One, &L));
01754 return *(new ADvari<Double>(R));
01755 }
01756
01757 template<typename Double>
01758 ADvari<Double>&
01759 min(const ADvari<Double> &L, const ADvari<Double> &R) {
01760 const ADvari<Double> &x = L.Val <= R.Val ? L : R;
01761 return *(new ADvar1<Double>(x.Val, &x.adc.One, &x));
01762 }
01763
01764 template<typename Double>
01765 ADvari<Double>&
01766 min(Double L, const ADvari<Double> &R) {
01767 if (L <= R.Val)
01768 return *(new ADvari<Double>(L));
01769 return *(new ADvar1<Double>(R.Val, &R.adc.One, &R));
01770 }
01771
01772 template<typename Double>
01773 ADvari<Double>&
01774 min(const ADvari<Double> &L, Double R) {
01775 if (L.Val <= R)
01776 return *(new ADvar1<Double>(L.Val, &L.adc.One, &L));
01777 return *(new ADvari<Double>(R));
01778 }
01779
01780 template<typename Double>
01781 ADvari<Double>&
01782 cos(const ADvari<Double> &v) {
01783 return *(new ADvar1s<Double>(std::cos(v.Val), -std::sin(v.Val), &v));
01784 }
01785
01786 template<typename Double>
01787 ADvari<Double>&
01788 cosh(const ADvari<Double> &v) {
01789 return *(new ADvar1s<Double>(std::cosh(v.Val), std::sinh(v.Val), &v));
01790 }
01791
01792 template<typename Double>
01793 ADvari<Double>&
01794 exp(const ADvari<Double> &v) {
01795 ADvar1<Double>* rcv = new ADvar1<Double>(std::exp(v.Val), &v);
01796 rcv->d.a = &rcv->Val;
01797 rcv->d.b = rcv;
01798 return *rcv;
01799 }
01800
01801 template<typename Double>
01802 ADvari<Double>&
01803 log(const ADvari<Double> &v) {
01804 Double x = v.Val;
01805 return *(new ADvar1s<Double>(std::log(x), 1. / x, &v));
01806 }
01807
01808 template<typename Double>
01809 ADvari<Double>&
01810 log10(const ADvari<Double> &v) {
01811 static double num = 1. / std::log(10.);
01812 Double x = v.Val;
01813 return *(new ADvar1s<Double>(std::log10(x), num / x, &v));
01814 }
01815
01816 template<typename Double>
01817 ADvari<Double>&
01818 pow(const ADvari<Double> &L, const ADvari<Double> &R) {
01819 Double x = L.Val, y = R.Val, t = std::pow(x,y);
01820 return *(new ADvar2q<Double>(t, y*t/x, t*std::log(x), &L, &R));
01821 }
01822
01823 template<typename Double>
01824 ADvari<Double>&
01825 pow(Double x, const ADvari<Double> &R) {
01826 Double t = std::pow(x,R.Val);
01827 return *(new ADvar1s<Double>(t, t*std::log(x), &R));
01828 }
01829
01830 template<typename Double>
01831 ADvari<Double>&
01832 pow(const ADvari<Double> &L, Double y) {
01833 Double x = L.Val, t = std::pow(x,y);
01834 return *(new ADvar1s<Double>(t, y*t/x, &L));
01835 }
01836
01837 template<typename Double>
01838 ADvari<Double>&
01839 sin(const ADvari<Double> &v) {
01840 return *(new ADvar1s<Double>(std::sin(v.Val), std::cos(v.Val), &v));
01841 }
01842
01843 template<typename Double>
01844 ADvari<Double>&
01845 sinh(const ADvari<Double> &v) {
01846 return *(new ADvar1s<Double>(std::sinh(v.Val), std::cosh(v.Val), &v));
01847 }
01848
01849 template<typename Double>
01850 ADvari<Double>&
01851 sqrt(const ADvari<Double> &v) {
01852 Double t = std::sqrt(v.Val);
01853 return *(new ADvar1s<Double>(t, 0.5/t, &v));
01854 }
01855
01856 template<typename Double>
01857 ADvari<Double>&
01858 tan(const ADvari<Double> &v) {
01859 Double t = std::cos(v.Val);
01860 return *(new ADvar1s<Double>(std::tan(v.Val), 1./(t*t), &v));
01861 }
01862
01863 template<typename Double>
01864 ADvari<Double>&
01865 tanh(const ADvari<Double> &v) {
01866 Double t = 1. / std::cosh(v.Val);
01867 return *(new ADvar1s<Double>(std::tanh(v.Val), t*t, &v));
01868 }
01869
01870 template<typename Double>
01871 ADvari<Double>&
01872 abs(const ADvari<Double> &v) {
01873 Double t, p;
01874 p = 1;
01875 if ((t = v.Val) < 0) {
01876 t = -t;
01877 p = -p;
01878 }
01879 return *(new ADvar1s<Double>(t, p, &v));
01880 }
01881
01882 template<typename Double>
01883 ADvari<Double>&
01884 fabs(const ADvari<Double> &v) {
01885
01886
01887 Double t, p;
01888 p = 1;
01889 if ((t = v.Val) < 0) {
01890 t = -t;
01891 p = -p;
01892 }
01893 return *(new ADvar1s<Double>(t, p, &v));
01894 }
01895
01896 template<typename Double>
01897 ADvari<Double>&
01898 ADf1(Double f, Double g, const ADvari<Double> &x) {
01899 return *(new ADvar1s<Double>(f, g, &x));
01900 }
01901
01902 template<typename Double>
01903 inline ADvari<Double>&
01904 ADf1(Double f, Double g, const IndepADvar<Double> &x) {
01905 return *(new ADvar1s<Double>(f, g, x.cv));
01906 }
01907
01908 template<typename Double>
01909 ADvari<Double>&
01910 ADf2(Double f, Double gx, Double gy, const ADvari<Double> &x, const ADvari<Double> &y) {
01911 return *(new ADvar2q<Double>(f, gx, gy, &x, &y));
01912 }
01913
01914 template<typename Double>
01915 ADvari<Double>&
01916 ADf2(Double f, Double gx, Double gy, const ADvari<Double> &x, const IndepADvar<Double> &y) {
01917 return *(new ADvar2q<Double>(f, gx, gy, &x, y.cv));
01918 }
01919
01920 template<typename Double>
01921 ADvari<Double>&
01922 ADf2(Double f, Double gx, Double gy, const IndepADvar<Double> &x, const ADvari<Double> &y) {
01923 return *(new ADvar2q<Double>(f, gx, gy, x.cv, &y));
01924 }
01925
01926 template<typename Double>
01927 ADvari<Double>&
01928 ADf2(Double f, Double gx, Double gy, const IndepADvar<Double> &x, const IndepADvar<Double> &y) {
01929 return *(new ADvar2q<Double>(f, gx, gy, x.cv, y.cv));
01930 }
01931
01932 template<typename Double>
01933 ADvari<Double>&
01934 ADfn(Double f, int n, const IndepADvar<Double> *x, const Double *g) {
01935 return *(new ADvarn<Double>(f, n, x, g));
01936 }
01937
01938 template<typename Double>
01939 inline ADvari<Double>&
01940 ADfn(Double f, int n, const ADvar<Double> *x, const Double *g) {
01941 return ADfn<Double>(f, n, (IndepADvar<Double>*)x, g);
01942 }
01943
01944 template<typename Double>
01945 inline Double
01946 val(const ADvari<Double> &x) {
01947 return x.Val;
01948 }
01949
01950 #undef RAD_ACA
01951 #define A (ADvari<Double>*)
01952 #ifdef RAD_Const_WARN
01953 #define C(x) (((x)->opno < 0) ? RAD_Const_Warn(x) : 0, *A x)
01954 #else
01955 #define C(x) *A x
01956 #endif
01957 #define T template<typename Double> inline
01958 #define F ADvari<Double>&
01959 #define Ai const ADvari<Double>&
01960 #define AI const IndepADvar<Double>&
01961 #define D Double
01962 #define T2(r,f) \
01963 T r f(Ai L, AI R) { return f(L, C(R.cv)); }\
01964 T r f(AI L, Ai R) { return f(C(L.cv), R); }\
01965 T r f(AI L, AI R) { return f(C(L.cv), C(R.cv)); }\
01966 T r f(AI L, D R) { return f(C(L.cv), R); }\
01967 T r f(Ai L, Dtype R) { return f(L, (D)R); }\
01968 T r f(AI L, Dtype R) { return f(C(L.cv), (D)R); }\
01969 T r f(Ai L, long R) { return f(L, (D)R); }\
01970 T r f(AI L, long R) { return f(C(L.cv), (D)R); }\
01971 T r f(Ai L, int R) { return f(L, (D)R); }\
01972 T r f(AI L, int R) { return f(C(L.cv), (D)R); }\
01973 T r f(D L, AI R) { return f(L, C(R.cv)); }\
01974 T r f(Dtype L, Ai R) { return f((D)L, R); }\
01975 T r f(Dtype L, AI R) { return f((D)L, C(R.cv)); }\
01976 T r f(long L, Ai R) { return f((D)L, R); }\
01977 T r f(long L, AI R) { return f((D)L, C(R.cv)); }\
01978 T r f(int L, Ai R) { return f((D)L, R); }\
01979 T r f(int L, AI R) { return f((D)L, C(R.cv)); }
01980
01981 T2(F, operator+)
01982 T2(F, operator-)
01983 T2(F, operator*)
01984 T2(F, operator/)
01985 T2(F, atan2)
01986 T2(F, pow)
01987 T2(F, max)
01988 T2(F, min)
01989 T2(int, operator<)
01990 T2(int, operator<=)
01991 T2(int, operator==)
01992 T2(int, operator!=)
01993 T2(int, operator>=)
01994 T2(int, operator>)
01995
01996 #undef T2
01997 #undef D
01998
01999 #define T1(f)\
02000 T F f(AI x) { return f(C(x.cv)); }
02001
02002 T1(operator+)
02003 T1(operator-)
02004 T1(abs)
02005 T1(acos)
02006 T1(acosh)
02007 T1(asin)
02008 T1(asinh)
02009 T1(atan)
02010 T1(atanh)
02011 T1(cos)
02012 T1(cosh)
02013 T1(exp)
02014 T1(log)
02015 T1(log10)
02016 T1(sin)
02017 T1(sinh)
02018 T1(sqrt)
02019 T1(tan)
02020 T1(tanh)
02021 T1(fabs)
02022
02023 T F copy(AI x)
02024 {
02025 return *(new ADvar1<Double>(x.cv->Val, &ADcontext<Double>::One, (ADvari<Double>*)x.cv));
02026 }
02027
02028 T F copy(Ai x)
02029 { return *(new ADvar1<Double>(x.Val, &ADcontext<Double>::One, (ADvari<Double>*)&x)); }
02030
02031 #undef T1
02032 #undef AI
02033 #undef Ai
02034 #undef F
02035 #undef T
02036 #undef A
02037 #undef C
02038 #undef Ttype
02039 #undef Dtype
02040 #undef Padvinit
02041
02042 }
02043 }
02044
02045 #undef SNS
02046
02047 #endif