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_TRAD_H
00036 #define SACADO_TRAD_H
00037
00038 #include "Sacado_ConfigDefs.h"
00039 #include "Sacado_trad_Traits.hpp"
00040
00041 #ifndef RAD_REINIT
00042 #define RAD_REINIT 0
00043 #endif //RAD_REINIT
00044
00045
00046
00047
00048
00049 #undef RAD_ALLOW_WANTDERIV
00050 #ifndef RAD_DISALLOW_WANTDERIV
00051 #define RAD_ALLOW_WANTDERIV
00052 #endif
00053
00054
00055
00056
00057 #define RAD_REINIT_0(x)
00058 #define RAD_REINIT_1(x)
00059 #define RAD_REINIT_2(x)
00060 #define RAD_cvchk(x)
00061
00062 #if RAD_REINIT == 1 //{
00063 #undef RAD_REINIT_1
00064 #define RAD_REINIT_1(x) x
00065 #ifdef RAD_ALLOW_WANTDERIV
00066 #define ADvar ADvar_1n
00067 #define IndepADvar IndepADvar_1n
00068 #else
00069 #define ADvar ADvar_1
00070 #define IndepADvar IndepADvar_1
00071 #endif //RAD_ALLOW_WANTDERIV
00072 #elif RAD_REINIT == 2
00073 #undef RAD_REINIT_2
00074 #define RAD_REINIT_2(x) x
00075 #undef RAD_cvchk
00076 #define RAD_cvchk(x) if (x.gen != x.IndepADvar_root.gen) { x.cv = new ADvari<Double>(x.Val);\
00077 x.gen = x.IndepADvar_root.gen; }
00078 #ifdef RAD_ALLOW_WANTDERIV
00079 #define IndepADvar IndepADvar_2n
00080 #define ADvar ADvar_2n
00081 #else
00082 #define IndepADvar IndepADvar_2
00083 #define ADvar ADvar_2
00084 #endif //RAD_ALLOW_WANTDERIV
00085 #elif RAD_REINIT != 0
00086 Botch! Expected "RAD_REINIT" to be 0, 1, or 2.
00087 Got "RAD_REINIT = " RAD_REINIT .
00088 #else
00089 #undef RAD_ALLOW_WANTDERIV
00090 #undef RAD_REINIT_0
00091 #define RAD_REINIT_0(x) x
00092 #endif //}
00093
00094 #ifdef RAD_ALLOW_WANTDERIV
00095 #define Allow_noderiv(x) x
00096 #else
00097 #define Allow_noderiv(x)
00098 #endif
00099
00100 #if RAD_REINIT > 0
00101 #undef RAD_Const_WARN
00102 #undef RAD_AUTO_AD_Const
00103 #undef RAD_DEBUG_BLOCKKEEP
00104 #endif
00105
00106 #include <stddef.h>
00107 #include <cmath>
00108 #include <math.h>
00109
00110 #ifdef RAD_Const_WARN // ==> RAD_AUTO_AD_Const and RAD_DEBUG
00111 #ifndef RAD_AUTO_AD_Const
00112 #define RAD_AUTO_AD_Const
00113 #endif
00114 #ifndef RAD_DEBUG
00115 #define RAD_DEBUG
00116 #endif
00117 extern "C" int RAD_Const_Warn(const void*);
00118
00119 #endif // RAD_Const_WARN
00120
00121 #ifdef RAD_DEBUG
00122 #include <cstdio>
00123 #include <stdlib.h>
00124 #endif
00125
00126 #ifndef RAD_AUTO_AD_Const
00127 #ifdef RAD_DEBUG_BLOCKKEEP
00128 #include <complex>
00129 #endif
00130 #endif
00131
00132 namespace Sacado {
00133 namespace Rad {
00134
00135 #ifdef RAD_AUTO_AD_Const
00136 #undef RAD_DEBUG_BLOCKKEEP
00137 #else
00138 #ifdef RAD_DEBUG_BLOCKKEEP
00139 #if !(RAD_DEBUG_BLOCKKEEP > 0)
00140 #undef RAD_DEBUG_BLOCKKEEP
00141 #else
00142 extern "C" void _uninit_f2c(void *x, int type, long len);
00143
00144 template <typename T>
00145 struct UninitType {};
00146
00147 template <>
00148 struct UninitType<float> {
00149 static const int utype = 4;
00150 };
00151
00152 template <>
00153 struct UninitType<double> {
00154 static const int utype = 5;
00155 };
00156
00157 template <typename T>
00158 struct UninitType< std::complex<T> > {
00159 static const int utype = UninitType<T>::utype + 2;
00160 };
00161
00162 #endif
00163 #endif
00164 #endif
00165
00166 class RAD_DoubleIgnore {};
00167
00168 template<typename T> class
00169 DoubleAvoid {
00170 public:
00171 typedef double dtype;
00172 typedef T ttype;
00173 };
00174 template<> class
00175 DoubleAvoid<double> {
00176 public:
00177 typedef RAD_DoubleIgnore &dtype;
00178 typedef RAD_DoubleIgnore &ttype;
00179 };
00180
00181 #define Dtype typename DoubleAvoid<Double>::dtype
00182 #define Ttype typename DoubleAvoid<Double>::ttype
00183
00184 template<typename Double> class IndepADvar;
00185 template<typename Double> class ConstADvar;
00186 template<typename Double> class ConstADvari;
00187 template<typename Double> class ADvar;
00188 template<typename Double> class ADvari;
00189 template<typename Double> class ADvar1;
00190 template<typename Double> class ADvar1s;
00191 template<typename Double> class ADvar2;
00192 template<typename Double> class ADvar2q;
00193 template<typename Double> class ADvarn;
00194 template<typename Double> class Derp;
00195
00196 template<typename Double> struct
00197 ADmemblock {
00198
00199
00200 ADmemblock *next;
00201 Double memblk[1000];
00202 };
00203
00204 template<typename Double> class
00205 ADcontext {
00206 typedef ADmemblock<Double> ADMemblock;
00207 typedef Derp<Double> DErp;
00208 ADMemblock *Busy, *First, *Free;
00209 char *Mbase;
00210 size_t Mleft;
00211 #if RAD_REINIT > 0
00212 ADMemblock *DBusy, *DFree;
00213 size_t DMleft, nderps;
00214 double DFirst0[(sizeof(ADMemblock) + sizeof(double) - 1) / sizeof(double)];
00215 #endif
00216 double First0[(sizeof(ADMemblock) + sizeof(double) - 1) / sizeof(double)];
00217 void *new_ADmemblock(size_t);
00218 typedef ADvari<Double> ADVari;
00219 typedef ADvar<Double> ADVar;
00220 int rad_need_reinit;
00221 size_t rad_mleft_save;
00222 #ifdef RAD_DEBUG_BLOCKKEEP
00223 int rad_busy_blocks;
00224 ADMemblock *rad_Oldcurmb;
00225 #endif
00226 public:
00227 static const Double One, negOne;
00228 ADcontext();
00229 void *Memalloc(size_t len);
00230 static void Gradcomp();
00231 static void aval_reset(void);
00232 static void Weighted_Gradcomp(int, ADVar**, Double*);
00233 #if RAD_REINIT > 0
00234 DErp *new_Derp(const Double *, const ADVari*, const ADVari*);
00235 RAD_REINIT_1(friend class ConstADvari<Double>;)
00236 #endif
00237 };
00238
00239 #if RAD_REINIT == 0
00240 template<typename Double> class
00241 CADcontext: public ADcontext<Double> {
00242 protected:
00243 bool fpval_implies_const;
00244 public:
00245 friend class ADvar<Double>;
00246 CADcontext(): ADcontext<Double>() { fpval_implies_const = false; }
00247 };
00248 #endif
00249
00250 template<typename Double> class
00251 Derp {
00252 public:
00253 friend class ADvarn<Double>;
00254 typedef ADvari<Double> ADVari;
00255 #if RAD_REINIT > 0
00256 const Double a;
00257 inline void *operator new(size_t, Derp *x) { return x; }
00258 #else
00259 static Derp *LastDerp;
00260 Derp *next;
00261 const Double *a;
00262 #endif
00263 const ADVari *b;
00264 const ADVari *c;
00265 Derp(){};
00266 Derp(const ADVari *);
00267 Derp(const Double *, const ADVari *);
00268 Derp(const Double *, const ADVari *, const ADVari *);
00269 inline void *operator new(size_t len) { return (Derp*)ADVari::adc.Memalloc(len); }
00270
00271 };
00272
00273 #if RAD_REINIT > 0 //{
00274 template<typename Double> Derp<Double>*
00275 ADcontext<Double>::new_Derp(const Double *a, const ADvari<Double> *b, const ADvari<Double> *c)
00276 {
00277 ADMemblock *x;
00278 DErp *rv;
00279 Allow_noderiv(if (!b->wantderiv) return 0;)
00280 if (this->DMleft == 0) {
00281 if ((x = DFree))
00282 DFree = x->next;
00283 else
00284 x = new ADMemblock;
00285 x->next = DBusy;
00286 DBusy = x;
00287 this->DMleft = nderps;
00288 }
00289 rv = &((DErp*)DBusy->memblk)[--this->DMleft];
00290 new(rv) DErp(a,b,c);
00291 return rv;
00292 }
00293 #endif //}
00294
00295
00296
00297 #define Ai const ADvari<Double>&
00298 #define AI const IndepADvar<Double>&
00299 #define T template<typename Double>
00300 #define D Double
00301 #define T1(f) \
00302 T F f (AI); \
00303 T F f (Ai);
00304 #define T2(r,f) \
00305 T r f(Ai,Ai); \
00306 T r f(Ai,D); \
00307 T r f(Ai,Dtype); \
00308 T r f(Ai,long); \
00309 T r f(Ai,int); \
00310 T r f(D,Ai); \
00311 T r f(Dtype,Ai); \
00312 T r f(long,Ai); \
00313 T r f(int,Ai); \
00314 T r f(AI,D); \
00315 T r f(AI,Dtype); \
00316 T r f(AI,long); \
00317 T r f(AI,int); \
00318 T r f(D,AI); \
00319 T r f(Dtype,AI); \
00320 T r f(long,AI); \
00321 T r f(int,AI); \
00322 T r f(Ai,AI);\
00323 T r f(AI,Ai);\
00324 T r f(AI,AI);
00325
00326 #define F ADvari<Double>&
00327 T2(F, operator+)
00328 T2(F, operator-)
00329 T2(F, operator*)
00330 T2(F, operator/)
00331 T2(F, atan2)
00332 T2(F, pow)
00333 T2(F, max)
00334 T2(F, min)
00335 T2(int, operator<)
00336 T2(int, operator<=)
00337 T2(int, operator==)
00338 T2(int, operator!=)
00339 T2(int, operator>=)
00340 T2(int, operator>)
00341 T1(operator+)
00342 T1(operator-)
00343 T1(abs)
00344 T1(acos)
00345 T1(acosh)
00346 T1(asin)
00347 T1(asinh)
00348 T1(atan)
00349 T1(atanh)
00350 T1(cos)
00351 T1(cosh)
00352 T1(exp)
00353 T1(log)
00354 T1(log10)
00355 T1(sin)
00356 T1(sinh)
00357 T1(sqrt)
00358 T1(tan)
00359 T1(tanh)
00360 T1(fabs)
00361
00362 T F copy(AI);
00363 T F copy(Ai);
00364
00365 #undef F
00366 #undef T2
00367 #undef T1
00368 #undef D
00369 #undef T
00370 #undef AI
00371 #undef Ai
00372
00373 template<typename Double>ADvari<Double>& ADf1(Double f, Double g, const IndepADvar<Double> &x);
00374 template<typename Double>ADvari<Double>& ADf2(Double f, Double gx, Double gy,
00375 const IndepADvar<Double> &x, const IndepADvar<Double> &y);
00376 template<typename Double>ADvari<Double>& ADfn(Double f, int n,
00377 const IndepADvar<Double> *x, const Double *g);
00378
00379 template<typename Double> IndepADvar<Double>& ADvar_operatoreq(IndepADvar<Double>*,
00380 const ADvari<Double>&);
00381 template<typename Double> ADvar<Double>& ADvar_operatoreq(ADvar<Double>*, const ADvari<Double>&);
00382 template<typename Double> void AD_Const(const IndepADvar<Double>&);
00383 template<typename Double> void AD_Const1(Double*, const IndepADvar<Double>&);
00384 template<typename Double> ADvari<Double>& ADf1(Double, Double, const ADvari<Double>&);
00385 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00386 const ADvari<Double>&, const ADvari<Double>&);
00387 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00388 const IndepADvar<Double>&, const ADvari<Double>&);
00389 template<typename Double> ADvari<Double>& ADf2(Double, Double, Double,
00390 const ADvari<Double>&, const IndepADvar<Double>&);
00391 template<typename Double> Double val(const ADvari<Double>&);
00392
00393 template<typename Double> class
00394 ADvari {
00395 public:
00396 typedef Double value_type;
00397 typedef IndepADvar<Double> IndepADVar;
00398 #ifdef RAD_AUTO_AD_Const
00399 friend class IndepADvar<Double>;
00400 #ifdef RAD_Const_WARN
00401 mutable const IndepADVar *padv;
00402 #else
00403 protected:
00404 mutable const IndepADVar *padv;
00405 #endif //RAD_Const_WARN
00406 private:
00407 ADvari *Next;
00408 static ADvari *First_ADvari, **Last_ADvari;
00409 public:
00410 #endif //RAD_AUTO_AD_Const
00411 #ifdef RAD_DEBUG
00412 int gcgen;
00413 int opno;
00414 static int gcgen_cur, last_opno, zap_gcgen, zap_gcgen1, zap_opno;
00415 static FILE *debug_file;
00416 #endif
00417 Double Val;
00418 mutable Double aval;
00419 Allow_noderiv(mutable int wantderiv;)
00420 void *operator new(size_t len) {
00421 #ifdef RAD_DEBUG
00422 ADvari *rv = (ADvari*)ADvari::adc.Memalloc(len);
00423 rv->gcgen = gcgen_cur;
00424 rv->opno = ++last_opno;
00425 if (last_opno == zap_opno && gcgen_cur == zap_gcgen)
00426 printf("");
00427 return rv;
00428 #else
00429 return ADvari::adc.Memalloc(len);
00430 #endif
00431 }
00432 void operator delete(void*) {}
00433 #ifdef RAD_ALLOW_WANTDERIV
00434 inline ADvari(Double t): Val(t), aval(0.), wantderiv(1) {}
00435 inline ADvari(): Val(0.), aval(0.), wantderiv(1) {}
00436 inline void no_deriv() { wantderiv = 0; }
00437 #else
00438 inline ADvari(Double t): Val(t), aval(0.) {}
00439 inline ADvari(): Val(0.), aval(0.) {}
00440 #endif
00441 #ifdef RAD_AUTO_AD_Const
00442 friend class ADcontext<Double>;
00443 friend class ADvar<Double>;
00444 friend class ADvar1<Double>;
00445 friend class ADvar1s<Double>;
00446 friend class ADvar2<Double>;
00447 friend class ADvar2q<Double>;
00448 friend class ConstADvar<Double>;
00449 ADvari(const IndepADVar *, Double);
00450 ADvari(const IndepADVar *, Double, Double);
00451 #endif
00452 #define F friend
00453 #define R ADvari&
00454 #define Ai const ADvari&
00455 #define T1(r,f) F r f <>(Ai);
00456 #define T2(r,f) \
00457 F r f <>(Ai,Ai); \
00458 F r f <>(Ttype,Ai); \
00459 F r f <>(Ai,Ttype); \
00460 F r f <>(double,Ai); \
00461 F r f <>(Ai,double); \
00462 F r f <>(long,Ai); \
00463 F r f <>(Ai,long); \
00464 F r f <>(int,Ai); \
00465 F r f <>(Ai,int);
00466 T1(R,operator+)
00467 T2(R,operator+)
00468 T1(R,operator-)
00469 T2(R,operator-)
00470 T2(R,operator*)
00471 T2(R,operator/)
00472 T1(R,abs)
00473 T1(R,acos)
00474 T1(R,acosh)
00475 T1(R,asin)
00476 T1(R,asinh)
00477 T1(R,atan)
00478 T1(R,atanh)
00479 T2(R,atan2)
00480 T2(R,max)
00481 T2(R,min)
00482 T1(R,cos)
00483 T1(R,cosh)
00484 T1(R,exp)
00485 T1(R,log)
00486 T1(R,log10)
00487 T2(R,pow)
00488 T1(R,sin)
00489 T1(R,sinh)
00490 T1(R,sqrt)
00491 T1(R,tan)
00492 T1(R,tanh)
00493 T1(R,fabs)
00494 T1(R,copy)
00495 T2(int,operator<)
00496 T2(int,operator<=)
00497 T2(int,operator==)
00498 T2(int,operator!=)
00499 T2(int,operator>=)
00500 T2(int,operator>)
00501 #undef T2
00502 #undef T1
00503 #undef Ai
00504 #undef R
00505 #undef F
00506
00507 friend ADvari& ADf1<>(Double f, Double g, const ADvari &x);
00508 friend ADvari& ADf2<>(Double f, Double gx, Double gy, const ADvari &x, const ADvari &y);
00509 friend ADvari& ADfn<>(Double f, int n, const IndepADVar *x, const Double *g);
00510
00511 inline operator Double() { return this->Val; }
00512 inline operator Double() const { return this->Val; }
00513
00514 static ADcontext<Double> adc;
00515 };
00516
00517 template<typename Double> class
00518 ADvar1: public ADvari<Double> {
00519 public:
00520 typedef ADvari<Double> ADVari;
00521 ADvar1(Double val1): ADVari(val1) {}
00522 #if RAD_REINIT > 0
00523 ADvar1(Double val1, const Double *a1, const ADVari *c1): ADVari(val1) {
00524 #ifdef RAD_ALLOW_WANTDERIV
00525 if (!ADVari::adc.new_Derp(a1,this,c1))
00526 this->no_deriv();
00527 #else
00528 ADVari::adc.new_Derp(a1,this,c1);
00529 #endif
00530 }
00531 #else // RAD_REINIT == 0
00532 Derp<Double> d;
00533 ADvar1(Double val1, const ADVari *c1): ADVari(val1), d(c1) {}
00534 ADvar1(Double val1, const Double *a1, const ADVari *c1):
00535 ADVari(val1), d(a1,this,c1) {}
00536 #ifdef RAD_AUTO_AD_Const
00537 typedef typename ADVari::IndepADVar IndepADVar;
00538 typedef ADvar<Double> ADVar;
00539 ADvar1(const IndepADVar*, const IndepADVar&);
00540 ADvar1(const IndepADVar*, const ADVari&);
00541 ADvar1(const Double val1, const Double *a1, const ADVari *c1, const ADVar *v):
00542 ADVari(val1), d(a1,this,c1) {
00543 c1->padv = 0;
00544 *ADVari::Last_ADvari = this;
00545 ADVari::Last_ADvari = &this->Next;
00546 this->padv = v;
00547 }
00548 #endif
00549 #endif // RAD_REININT > 0
00550 };
00551
00552
00553 template<typename Double> class
00554 ConstADvari: public ADvari<Double> {
00555 private:
00556 RAD_REINIT_0(ConstADvari *prevcad;)
00557 ConstADvari() {};
00558 RAD_REINIT_0(static ConstADvari *lastcad;)
00559 public:
00560 typedef ADvari<Double> ADVari;
00561 typedef Derp<Double> DErp;
00562 #if RAD_REINIT == 0
00563 static CADcontext<Double> cadc;
00564 inline void *operator new(size_t len) { return ConstADvari::cadc.Memalloc(len); }
00565 inline ConstADvari(Double t): ADVari(t) { prevcad = lastcad; lastcad = this; }
00566 #else
00567 inline void *operator new(size_t len) { return ADVari::adc.Memalloc(len); }
00568 inline ConstADvari(Double t): ADVari(t) {}
00569 #endif
00570 static void aval_reset(void);
00571 };
00572
00573 template<typename Double> class
00574 IndepADvar_base0 {
00575 public:
00576 #if RAD_REINIT == 1
00577 IndepADvar_base0 *ADvnext, *ADvprev;
00578 inline IndepADvar_base0(double) { ADvnext = ADvprev = this; }
00579 #elif RAD_REINIT == 2
00580 typedef unsigned long ADGenType;
00581 mutable ADGenType gen;
00582 inline IndepADvar_base0(double) { gen = 1; }
00583 #endif
00584 inline IndepADvar_base0() {}
00585 };
00586
00587 template<typename Double> class
00588 IndepADvar_base: public IndepADvar_base0<Double> {
00589 public:
00590 #if RAD_REINIT > 0
00591 Allow_noderiv(mutable int wantderiv;)
00592 static IndepADvar_base0<Double> IndepADvar_root;
00593 RAD_REINIT_2(static typename IndepADvar_base0<Double>::ADGenType gen0;)
00594 #endif
00595 inline IndepADvar_base(Allow_noderiv(int wd)) {
00596 #if RAD_REINIT == 1
00597 IndepADvar_root.ADvprev = (this->ADvprev = IndepADvar_root.ADvprev)->ADvnext = this;
00598 this->ADvnext = &IndepADvar_root;
00604 #endif
00605 Allow_noderiv(this->wantderiv = wd;)
00606 }
00607 inline ~IndepADvar_base() {
00608 #if RAD_REINIT == 1
00609 (this->ADvnext->ADvprev = this->ADvprev)->ADvnext = this->ADvnext;
00610 #endif
00611 }
00612 #if RAD_REINIT > 0
00613 private:
00614 inline IndepADvar_base(double d): IndepADvar_base0<Double>(d) {}
00615 #endif
00616 #if RAD_REINIT == 1
00617 protected:
00618 void Move_to_end();
00619 #endif
00620 };
00621
00622 #if RAD_REINIT > 0 //{
00623 template<typename Double> IndepADvar_base0<Double>
00624 IndepADvar_base<Double>::IndepADvar_root(0.);
00625 #if RAD_REINIT == 1
00626 template<typename Double> void
00627 IndepADvar_base<Double>::Move_to_end() {
00628 if (this != IndepADvar_root.ADvprev) {
00629 (this->ADvnext->ADvprev = this->ADvprev)->ADvnext = this->ADvnext;
00630 IndepADvar_root.ADvprev = (this->ADvprev = IndepADvar_root.ADvprev)->ADvnext = this;
00631 this->ADvnext = &IndepADvar_root;
00632 }
00633 }
00634 #elif RAD_REINIT == 2
00635 template<typename Double> typename IndepADvar_base0<Double>::ADGenType
00636 IndepADvar_base<Double>::gen0(1);
00637 #endif
00638 #endif //}
00639
00640 template<typename Double> class
00641 IndepADvar: protected IndepADvar_base<Double> {
00642 protected:
00643 static void AD_Const(const IndepADvar&);
00644 mutable ADvari<Double> *cv;
00645 private:
00646 IndepADvar& operator=(IndepADvar&x) {
00647
00648 RAD_cvchk(x)
00649 #ifdef RAD_AUTO_AD_Const
00650 if (cv)
00651 cv->padv = 0;
00652 cv = new ADvar1<Double>(this,x);
00653 return *this;
00654 #elif defined(RAD_EQ_ALIAS)
00655 this->cv = x.cv;
00656 return *this;
00657 #else
00658 return ADvar_operatoreq(this,*x.cv);
00659 #endif //RAD_REINIT
00660 }
00661 public:
00662 int Wantderiv(int);
00663 RAD_REINIT_2(Double Val;)
00664 typedef Double value_type;
00665 friend class ADvar<Double>;
00666 friend class ADcontext<Double>;
00667 friend class ADvar1<Double>;
00668 friend class ADvarn<Double>;
00669 typedef ADvari<Double> ADVari;
00670 typedef ADvar<Double> ADVar;
00671 IndepADvar(Ttype);
00672 IndepADvar(double);
00673 IndepADvar(int);
00674 IndepADvar(long);
00675 IndepADvar& operator= (Double);
00676 #ifdef RAD_ALLOW_WANTDERIV
00677 inline int Wantderiv() { return this->wantderiv; }
00678 protected:
00679 inline IndepADvar(void*, int wd): IndepADvar_base<Double>(wd){RAD_REINIT_1(cv = 0;)}
00680 IndepADvar(Ttype, int);
00681 IndepADvar(double, int);
00682 public:
00683 #else
00684 inline int Wantderiv() { return 1; }
00685 #endif
00686 #ifdef RAD_AUTO_AD_Const
00687 inline IndepADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1<Double>(this, x) : 0; };
00688 inline IndepADvar() { cv = 0; }
00689 inline ~IndepADvar() {
00690 if (cv)
00691 cv->padv = 0;
00692 }
00693 #else
00694 inline IndepADvar() Allow_noderiv(: IndepADvar_base<Double>(1)) {
00695 #ifndef RAD_EQ_ALIAS
00696 cv = 0;
00697 #endif
00698 }
00699 inline ~IndepADvar() {}
00700 friend IndepADvar& ADvar_operatoreq<>(IndepADvar*, const ADVari&);
00701 #endif
00702
00703 #ifdef RAD_Const_WARN
00704 inline operator ADVari&() const {
00705 ADVari *tcv = this->cv;
00706 if (tcv->opno < 0)
00707 RAD_Const_Warn(tcv);
00708 return *tcv;
00709 }
00710 inline operator ADVari*() const {
00711 ADVari *tcv = this->cv;
00712 if (tcv->opno < 0)
00713 RAD_Const_Warn(tcv);
00714 return tcv;
00715 }
00716 #else //RAD_Const_WARN
00717 inline operator ADVari&() const { RAD_cvchk((*this)) return *this->cv; }
00718 inline operator ADVari*() const { RAD_cvchk((*this)) return this->cv; }
00719 #endif //RAD_Const_WARN
00720
00721 inline Double val() const {
00722 #if RAD_REINIT == 2
00723 return Val;
00724 #else
00725 return cv->Val;
00726 #endif
00727 }
00728 inline Double adj() const {
00729 return
00730 RAD_REINIT_2(this->gen != this->gen0 ? 0. :)
00731 cv->aval;
00732 }
00733
00734 friend void AD_Const1<>(Double*, const IndepADvar&);
00735
00736 friend ADVari& ADf1<>(Double, Double, const IndepADvar&);
00737 friend ADVari& ADf2<>(Double, Double, Double, const IndepADvar&, const IndepADvar&);
00738 friend ADVari& ADf2<>(Double, Double, Double, const ADVari&, const IndepADvar&);
00739 friend ADVari& ADf2<>(Double, Double, Double, const IndepADvar&, const ADVari&);
00740
00741 static inline void Gradcomp() { ADcontext<Double>::Gradcomp(); }
00742 static inline void aval_reset() { ConstADvari<Double>::aval_reset(); }
00743 static inline void Weighted_Gradcomp(int n, ADVar **v, Double *w)
00744 { ADcontext<Double>::Weighted_Gradcomp(n, v, w); }
00745
00746
00747
00748
00749
00750 #define Ai const ADVari&
00751 #define AI const IndepADvar&
00752 #define D Double
00753 #define T2(r,f) \
00754 r f <>(AI,AI);\
00755 r f <>(Ai,AI);\
00756 r f <>(AI,Ai);\
00757 r f <>(Ttype,AI);\
00758 r f <>(double,AI);\
00759 r f <>(long,AI);\
00760 r f <>(int,AI);\
00761 r f <>(AI,Ttype);\
00762 r f <>(AI,double);\
00763 r f <>(AI,long);\
00764 r f <>(AI,int);
00765 #define T1(f) friend ADVari& f<> (AI);
00766
00767 #define F friend ADVari&
00768 T2(F, operator+)
00769 T2(F, operator-)
00770 T2(F, operator*)
00771 T2(F, operator/)
00772 T2(F, atan2)
00773 T2(F, max)
00774 T2(F, min)
00775 T2(F, pow)
00776 #undef F
00777 #define F friend int
00778 T2(F, operator<)
00779 T2(F, operator<=)
00780 T2(F, operator==)
00781 T2(F, operator!=)
00782 T2(F, operator>=)
00783 T2(F, operator>)
00784
00785 T1(operator+)
00786 T1(operator-)
00787 T1(abs)
00788 T1(acos)
00789 T1(acosh)
00790 T1(asin)
00791 T1(asinh)
00792 T1(atan)
00793 T1(atanh)
00794 T1(cos)
00795 T1(cosh)
00796 T1(exp)
00797 T1(log)
00798 T1(log10)
00799 T1(sin)
00800 T1(sinh)
00801 T1(sqrt)
00802 T1(tan)
00803 T1(tanh)
00804 T1(fabs)
00805 T1(copy)
00806
00807 #undef F
00808 #undef T1
00809 #undef T2
00810 #undef D
00811 #undef AI
00812 #undef Ai
00813
00814 };
00815
00816 template<typename Double> class
00817 ADvar: public IndepADvar<Double> {
00818 public:
00819 typedef IndepADvar<Double> IndepADVar;
00820 typedef typename IndepADVar::ADVari ADVari;
00821 typedef ConstADvari<Double> ConstADVari;
00822 private:
00823 void ADvar_ctr(Double d) {
00824 #if RAD_REINIT == 0 //{
00825 ADVari *x = ConstADVari::cadc.fpval_implies_const
00826 ? new ConstADVari(d)
00827 #ifdef RAD_AUTO_AD_Const //{
00828 : new ADVari((IndepADVar*)this, d);
00829 #else
00830 : new ADVari(d);
00831 #endif //}
00832 #else
00833 RAD_REINIT_1(this->cv = 0;)
00834 ADVari *x = new ADVari(d);
00835 RAD_REINIT_2(this->Val = d;)
00836 #endif //}
00837 this->cv = x;
00838 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
00839 }
00840 public:
00841 friend class ADvar1<Double>;
00842 typedef ADvar1<Double> ADVar1;
00843 inline ADvar() { }
00844 inline ADvar(Ttype d) { ADvar_ctr(d); }
00845 inline ADvar(double i) { ADvar_ctr(Double(i)); }
00846 inline ADvar(int i) { ADvar_ctr(Double(i)); }
00847 inline ADvar(long i) { ADvar_ctr(Double(i)); }
00848 inline ~ADvar() {}
00849 Allow_noderiv(inline ADvar(void *v, int wd): IndepADVar(v, wd) {})
00850 #ifdef RAD_AUTO_AD_Const
00851 inline ADvar(IndepADVar &x) {
00852 this->cv = x.cv ? new ADVar1(this, x) : 0;
00853 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
00854 }
00855 inline ADvar(ADVari &x) { this->cv = &x; x.padv = this; }
00856 inline ADvar& operator=(IndepADVar &x) {
00857 if (this->cv)
00858 this->cv->padv = 0;
00859 this->cv = new ADVar1(this,x);
00860 return *this;
00861 }
00862 inline ADvar& operator=(ADVari &x) {
00863 if (this->cv)
00864 this->cv->padv = 0;
00865 this->cv = new ADVar1(this, x);
00866 return *this;
00867 }
00868 #else
00869 friend ADvar& ADvar_operatoreq<>(ADvar*, const ADVari&);
00870 #ifdef RAD_EQ_ALIAS
00871
00872 inline ADvar(const IndepADVar &x) {
00873 RAD_cvchk(x)
00874 this->cv = (ADVari*)x.cv;
00875 }
00876 inline ADvar(const ADVari &x) { this->cv = (ADVari*)&x; }
00877 inline ADvar& operator=(IndepADVar &x) {
00878 RAD_cvchk(x)
00879 this->cv = (ADVari*)x.cv; return *this;
00880 }
00881 inline ADvar& operator=(const ADVari &x) { this->cv = (ADVari*)&x; return *this; }
00882 #else
00883 ADvar(const IndepADVar &x) {
00884 if (x.cv) {
00885 RAD_cvchk(x)
00886 RAD_REINIT_1(this->cv = 0;)
00887 this->cv = new ADVar1(x.cv->Val, &this->cv->adc.One, x.cv);
00888 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
00889 }
00890 else
00891 this->cv = 0;
00892 }
00893 ADvar(const ADvar&x) {
00894 if (x.cv) {
00895 RAD_cvchk(x)
00896 RAD_REINIT_1(this->cv = 0;)
00897 this->cv = new ADVar1(x.cv->Val, &this->cv->adc.One, (ADVari*)x.cv);
00898 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
00899 }
00900 else
00901 this->cv = 0;
00902 }
00903 ADvar(const ADVari &x) {
00904 RAD_REINIT_1(this->cv = 0;)
00905 this->cv = new ADVar1(x.Val, &this->cv->adc.One, &x);
00906 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
00907 }
00908 inline ADvar& operator=(const ADVari &x) { return ADvar_operatoreq(this,x); };
00909 #endif
00910 #endif
00911 ADvar& operator=(Double);
00912 ADvar& operator+=(const ADVari&);
00913 ADvar& operator+=(Double);
00914 ADvar& operator-=(const ADVari&);
00915 ADvar& operator-=(Double);
00916 ADvar& operator*=(const ADVari&);
00917 ADvar& operator*=(Double);
00918 ADvar& operator/=(const ADVari&);
00919 ADvar& operator/=(Double);
00920 #if RAD_REINIT == 0
00921 inline static bool get_fpval_implies_const(void)
00922 { return ConstADVari::cadc.fpval_implies_const; }
00923 inline static void set_fpval_implies_const(bool newval)
00924 { ConstADVari::cadc.fpval_implies_const = newval; }
00925 inline static bool setget_fpval_implies_const(bool newval) {
00926 bool oldval = ConstADVari::cadc.fpval_implies_const;
00927 ConstADVari::cadc.fpval_implies_const = newval;
00928 return oldval;
00929 }
00930 #else
00931 inline static bool get_fpval_implies_const(void) { return true; }
00932 inline static void set_fpval_implies_const(bool newval) {}
00933 inline static bool setget_fpval_implies_const(bool newval) { return newval; }
00934 #endif
00935 static inline void Gradcomp() { ADcontext<Double>::Gradcomp(); }
00936 static inline void aval_reset() { ConstADVari::aval_reset(); }
00937 static inline void Weighted_Gradcomp(int n, ADvar **v, Double *w)
00938 { ADcontext<Double>::Weighted_Gradcomp(n, v, w); }
00939 };
00940
00941 #if RAD_REINIT == 0
00942 template<typename Double>
00943 inline void AD_Const1(Double *notused, const IndepADvar<Double>&v)
00944 { IndepADvar<Double>::AD_Const(v); }
00945
00946 template<typename Double>
00947 inline void AD_Const(const IndepADvar<Double>&v) { AD_Const1((Double*)0, v); }
00948 #else
00949 template<typename Double>
00950 inline void AD_Const(const IndepADvar<Double>&v) {}
00951 #endif //RAD_REINIT == 0
00952
00953 template<typename Double> class
00954 ConstADvar: public ADvar<Double> {
00955 public:
00956 typedef ADvar<Double> ADVar;
00957 typedef typename ADVar::ADVar1 ADVar1;
00958 typedef typename ADVar::ADVari ADVari;
00959 typedef typename ADVar::ConstADVari ConstADVari;
00960 typedef Derp<Double> DErp;
00961 typedef typename ADVar::IndepADVar IndepADVar;
00962 private:
00963 ConstADvar& operator+=(ADVari&);
00964 ConstADvar& operator+=(Double);
00965 ConstADvar& operator-=(ADVari&);
00966 ConstADvar& operator-=(Double);
00967 ConstADvar& operator*=(ADVari&);
00968 ConstADvar& operator*=(Double);
00969 ConstADvar& operator/=(ADVari&);
00970 ConstADvar& operator/=(Double);
00971 void ConstADvar_ctr(Double);
00972 public:
00973 ConstADvar(Ttype d) { ConstADvar_ctr(d); }
00974 ConstADvar(double i) { ConstADvar_ctr(Double(i)); }
00975 ConstADvar(int i) { ConstADvar_ctr(Double(i)); }
00976 ConstADvar(long i) { ConstADvar_ctr(Double(i)); }
00977 ConstADvar(const IndepADVar&);
00978 ConstADvar(const ConstADvar&);
00979 ConstADvar(const ADVari&);
00980 inline ~ConstADvar() {}
00981 #ifdef RAD_NO_CONST_UPDATE
00982 private:
00983 #endif
00984 ConstADvar();
00985 inline ConstADvar& operator=(Double d) {
00986 #if RAD_REINIT > 0
00987 this->cv = new ADVari(d);
00988 RAD_REINIT_2(this->Val = d;)
00989 #else
00990 this->cv->Val = d;
00991 #endif
00992 return *this;
00993 }
00994 inline ConstADvar& operator=(ADVari& d) {
00995 #if RAD_REINIT > 0
00996 this->cv = new ADVar1(this,d);
00997 RAD_REINIT_2(this->Val = d;)
00998 #else
00999 this->cv->Val = d.Val;
01000 #endif
01001 return *this;
01002 }
01003 };
01004
01005 #ifdef RAD_ALLOW_WANTDERIV
01006 template<typename Double> class
01007 ADvar_nd: public ADvar<Double>
01008 {
01009 public:
01010 typedef ADvar<Double> ADVar;
01011 typedef IndepADvar<Double> IndepADVar;
01012 typedef typename IndepADVar::ADVari ADVari;
01013 typedef ADvar1<Double> ADVar1;
01014 private:
01015 void ADvar_ndctr(Double d) {
01016 ADVari *x = new ADVari(d);
01017 this->cv = x;
01018 RAD_REINIT_2(this->Val = d;)
01019 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
01020 }
01021 public:
01022 inline ADvar_nd(): ADVar((void*)0,0) {}
01023 inline ADvar_nd(Ttype d): ADVar((void*)0,0) { ADvar_ndctr(d); }
01024 inline ADvar_nd(double i): ADVar((void*)0,0) { ADvar_ndctr(Double(i)); }
01025 inline ADvar_nd(int i): ADVar((void*)0,0) { ADvar_ndctr(Double(i)); }
01026 inline ADvar_nd(long i): ADVar((void*)0,0) { ADvar_ndctr(Double(i)); }
01027 inline ~ADvar_nd() {}
01028 ADvar_nd(const IndepADVar &x): ADVar((void*)0,0) {
01029 if (x.cv) {
01030 this->cv = new ADVar1(x.cv->Val, &this->cv->adc.One, x.cv);
01031 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
01032 }
01033 else
01034 this->cv = 0;
01035 }
01036 ADvar_nd(const ADVari &x): ADVar((void*)0,0) {
01037 this->cv = new ADVar1(x.Val, &this->cv->adc.One, &x);
01038 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
01039 }
01040 inline ADvar_nd& operator=(const ADVari &x) { return (ADvar_nd&)ADvar_operatoreq(this,x); };
01041 };
01042 #else
01043 #define ADvar_nd ADvar
01044 #endif //RAD_ALLOW_WANTDERIV
01045
01046 template<typename Double> class
01047 ADvar1s: public ADvar1<Double> {
01048 public:
01049 typedef ADvar1<Double> ADVar1;
01050 typedef typename ADVar1::ADVari ADVari;
01051 #if RAD_REINIT > 0 //{{
01052 inline ADvar1s(Double val1, Double a1, const ADVari *c1): ADVar1(val1,&a1,c1) {}
01053 #else //}{
01054 Double a;
01055 ADvar1s(Double val1, Double a1, const ADVari *c1): ADVar1(val1,&a,c1), a(a1) {}
01056 #ifdef RAD_AUTO_AD_Const
01057 typedef typename ADVar1::ADVar ADVar;
01058 ADvar1s(Double val1, Double a1, const ADVari *c1, const ADVar *v):
01059 ADVar1(val1,&a,c1,v), a(a1) {}
01060 #endif
01061 #endif // }} RAD_REINIT > 0
01062 };
01063
01064 template<typename Double> class
01065 ADvar2: public ADvari<Double> {
01066 public:
01067 typedef ADvari<Double> ADVari;
01068 typedef Derp<Double> DErp;
01069 ADvar2(Double val1): ADVari(val1) {}
01070 #if RAD_REINIT > 0 //{{
01071 ADvar2(Double val1, const ADVari *Lcv, const Double *Lc,
01072 const ADVari *Rcv, const Double *Rc): ADVari(val1) {
01073 #ifdef RAD_ALLOW_WANTDERIV
01074 DErp *Ld, *Rd;
01075 Ld = ADVari::adc.new_Derp(Lc, this, Lcv);
01076 Rd = ADVari::adc.new_Derp(Rc, this, Rcv);
01077 if (!Ld && !Rd)
01078 this->no_deriv();
01079 #else
01080 ADVari::adc.new_Derp(Lc, this, Lcv);
01081 ADVari::adc.new_Derp(Rc, this, Rcv);
01082 #endif //RAD_ALLOW_WANTDERIV
01083 }
01084 #else //}{ RAD_REINIT == 0
01085 DErp dL, dR;
01086 ADvar2(Double val1, const ADVari *Lcv, const Double *Lc,
01087 const ADVari *Rcv, const Double *Rc):
01088 ADVari(val1) {
01089 dR.next = DErp::LastDerp;
01090 dL.next = &dR;
01091 DErp::LastDerp = &dL;
01092 dL.a = Lc;
01093 dL.c = Lcv;
01094 dR.a = Rc;
01095 dR.c = Rcv;
01096 dL.b = dR.b = this;
01097 }
01098 #ifdef RAD_AUTO_AD_Const
01099 typedef ADvar<Double> ADVar;
01100 ADvar2(Double val1, const ADVari *Lcv, const Double *Lc,
01101 const ADVari *Rcv, const Double *Rc, ADVar *v):
01102 ADVari(val1) {
01103 dR.next = DErp::LastDerp;
01104 dL.next = &dR;
01105 DErp::LastDerp = &dL;
01106 dL.a = Lc;
01107 dL.c = Lcv;
01108 dR.a = Rc;
01109 dR.c = Rcv;
01110 dL.b = dR.b = this;
01111 Lcv->padv = 0;
01112 *ADVari::Last_ADvari = this;
01113 ADVari::Last_ADvari = &this->Next;
01114 this->padv = v;
01115 }
01116 #endif
01117 #endif // }} RAD_REINIT
01118 };
01119
01120 template<typename Double> class
01121 ADvar2q: public ADvar2<Double> {
01122 public:
01123 typedef ADvar2<Double> ADVar2;
01124 typedef typename ADVar2::ADVari ADVari;
01125 typedef typename ADVar2::DErp DErp;
01126 #if RAD_REINIT > 0 //{{
01127 inline ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv, const ADVari *Rcv):
01128 ADVar2(val1) {
01129 #ifdef RAD_ALLOW_WANTDERIV
01130 DErp *Ld, *Rd;
01131 Ld = ADVari::adc.new_Derp(&Lp, this, Lcv);
01132 Rd = ADVari::adc.new_Derp(&Rp, this, Rcv);
01133 if (!Ld && !Rd)
01134 this->no_deriv();
01135 #else
01136 ADVari::adc.new_Derp(&Lp, this, Lcv);
01137 ADVari::adc.new_Derp(&Rp, this, Rcv);
01138 #endif //RAD_ALLOW_WANTDERIV
01139 }
01140 #else //}{ RADINIT == 0
01141 Double a, b;
01142 ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv, const ADVari *Rcv):
01143 ADVar2(val1), a(Lp), b(Rp) {
01144 this->dR.next = DErp::LastDerp;
01145 this->dL.next = &this->dR;
01146 DErp::LastDerp = &this->dL;
01147 this->dL.a = &a;
01148 this->dL.c = Lcv;
01149 this->dR.a = &b;
01150 this->dR.c = Rcv;
01151 this->dL.b = this->dR.b = this;
01152 }
01153 #ifdef RAD_AUTO_AD_Const
01154 typedef typename ADVar2::ADVar ADVar;
01155 ADvar2q(Double val1, Double Lp, Double Rp, const ADVari *Lcv,
01156 const ADVari *Rcv, const ADVar *v):
01157 ADVar2(val1), a(Lp), b(Rp) {
01158 this->dR.next = DErp::LastDerp;
01159 this->dL.next = &this->dR;
01160 DErp::LastDerp = &this->dL;
01161 this->dL.a = &a;
01162 this->dL.c = Lcv;
01163 this->dR.a = &b;
01164 this->dR.c = Rcv;
01165 this->dL.b = this->dR.b = this;
01166 Lcv->padv = 0;
01167 *ADVari::Last_ADvari = this;
01168 ADVari::Last_ADvari = &this->Next;
01169 this->padv = v;
01170 }
01171 #endif
01172 #endif //}} RAD_REINIT > 0
01173 };
01174
01175 template<typename Double> class
01176 ADvarn: public ADvari<Double> {
01177 public:
01178 typedef ADvari<Double> ADVari;
01179 typedef typename ADVari::IndepADVar IndepADVar;
01180 typedef Derp<Double> DErp;
01181 #if RAD_REINIT > 0 // {{
01182 ADvarn(Double val1, int n1, const IndepADVar *x, const Double *g): ADVari(val1) {
01183 #ifdef RAD_ALLOW_WANTDERIV
01184 int i, nd;
01185 for(i = nd = 0; i < n1; i++)
01186 if (ADVari::adc.new_Derp(g+i, this, x[i].cv))
01187 ++nd;
01188 if (!nd)
01189 this->no_deriv();
01190 #else
01191 for(int i = 0; i < n1; i++)
01192 ADVari::adc.new_Derp(g+i, this, x[i].cv);
01193 #endif // RAD_ALLOW_WANTDERIV
01194 }
01195 #else //}{
01196 int n;
01197 Double *a;
01198 DErp *Da;
01199 ADvarn(Double val1, int n1, const IndepADVar *x, const Double *g):
01200 ADVari(val1), n(n1) {
01201 DErp *d1, *dlast;
01202 Double *a1;
01203 int i;
01204
01205 a1 = a = (Double*)ADVari::adc.Memalloc(n*sizeof(*a));
01206 d1 = Da = (DErp*)ADVari::adc.Memalloc(n*sizeof(DErp));
01207 dlast = DErp::LastDerp;
01208 for(i = 0; i < n1; i++, d1++) {
01209 d1->next = dlast;
01210 dlast = d1;
01211 a1[i] = g[i];
01212 d1->a = &a1[i];
01213 d1->b = this;
01214 d1->c = x[i].cv;
01215 }
01216 DErp::LastDerp = dlast;
01217 }
01218 #endif //}} RAD_REINIT > 0
01219 };
01220
01221 template<typename Double>
01222 inline ADvari<Double>& operator+(const ADvari<Double> &T) { return *(ADvari<Double>*)&T; }
01223
01224 template<typename Double>
01225 inline int operator<(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val < R.Val; }
01226 template<typename Double>
01227 inline int operator<(const ADvari<Double> &L, Double R) { return L.Val < R; }
01228 template<typename Double>
01229 inline int operator<(Double L, const ADvari<Double> &R) { return L < R.Val; }
01230
01231 template<typename Double>
01232 inline int operator<=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val <= R.Val; }
01233 template<typename Double>
01234 inline int operator<=(const ADvari<Double> &L, Double R) { return L.Val <= R; }
01235 template<typename Double>
01236 inline int operator<=(Double L, const ADvari<Double> &R) { return L <= R.Val; }
01237
01238 template<typename Double>
01239 inline int operator==(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val == R.Val; }
01240 template<typename Double>
01241 inline int operator==(const ADvari<Double> &L, Double R) { return L.Val == R; }
01242 template<typename Double>
01243 inline int operator==(Double L, const ADvari<Double> &R) { return L == R.Val; }
01244
01245 template<typename Double>
01246 inline int operator!=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val != R.Val; }
01247 template<typename Double>
01248 inline int operator!=(const ADvari<Double> &L, Double R) { return L.Val != R; }
01249 template<typename Double>
01250 inline int operator!=(Double L, const ADvari<Double> &R) { return L != R.Val; }
01251
01252 template<typename Double>
01253 inline int operator>=(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val >= R.Val; }
01254 template<typename Double>
01255 inline int operator>=(const ADvari<Double> &L, Double R) { return L.Val >= R; }
01256 template<typename Double>
01257 inline int operator>=(Double L, const ADvari<Double> &R) { return L >= R.Val; }
01258
01259 template<typename Double>
01260 inline int operator>(const ADvari<Double> &L, const ADvari<Double> &R) { return L.Val > R.Val; }
01261 template<typename Double>
01262 inline int operator>(const ADvari<Double> &L, Double R) { return L.Val > R; }
01263 template<typename Double>
01264 inline int operator>(Double L, const ADvari<Double> &R) { return L > R.Val; }
01265
01266 template<typename Double>
01267 inline void *ADcontext<Double>::Memalloc(size_t len) {
01268 if (Mleft >= len)
01269 return Mbase + (Mleft -= len);
01270 return new_ADmemblock(len);
01271 }
01272 #if RAD_REINIT > 0 //{{
01273
01274 template<typename Double>
01275 inline Derp<Double>::Derp(const ADVari *c1): c(c1) {}
01276
01277 template<typename Double>
01278 inline Derp<Double>::Derp(const Double *a1, const ADVari *c1): a(*a1), c(c1) {}
01279
01280
01281 template<typename Double>
01282 inline Derp<Double>::Derp(const Double *a1, const ADVari *b1, const ADVari *c1):
01283 a(*a1), b(b1), c(c1) {}
01284 #else //}{ RAD_REINIT == 0
01285
01286 template<typename Double>
01287 inline Derp<Double>::Derp(const ADVari *c1): c(c1) {
01288 next = LastDerp;
01289 LastDerp = this;
01290 }
01291
01292 template<typename Double>
01293 inline Derp<Double>::Derp(const Double *a1, const ADVari *c1): a(a1), c(c1) {
01294 next = LastDerp;
01295 LastDerp = this;
01296 }
01297
01298
01299 template<typename Double>
01300 inline Derp<Double>::Derp(const Double *a1, const ADVari *b1, const ADVari *c1): a(a1), b(b1), c(c1) {
01301 next = LastDerp;
01302 LastDerp = this;
01303 }
01304 #endif //}} RAD_REINIT
01305
01306
01307
01308 #if RAD_REINIT > 0
01309 #else
01310 template<typename Double> Derp<Double> *Derp<Double>::LastDerp = 0;
01311 #endif //RAD_REINIT
01312 template<typename Double> ADcontext<Double> ADvari<Double>::adc;
01313 template<typename Double> const Double ADcontext<Double>::One = 1.;
01314 template<typename Double> const Double ADcontext<Double>::negOne = -1.;
01315 RAD_REINIT_0(template<typename Double> CADcontext<Double> ConstADvari<Double>::cadc;)
01316 RAD_REINIT_0(template<typename Double> ConstADvari<Double> *ConstADvari<Double>::lastcad;)
01317
01318 #ifdef RAD_AUTO_AD_Const
01319 template<typename Double> ADvari<Double>* ADvari<Double>::First_ADvari;
01320 template<typename Double> ADvari<Double>** ADvari<Double>::Last_ADvari = &ADvari<Double>::First_ADvari;
01321 #endif
01322
01323 #ifdef RAD_DEBUG
01324 #ifndef RAD_DEBUG_gcgen1
01325 #define RAD_DEBUG_gcgen1 -1
01326 #endif
01327 template<typename Double> int ADvari<Double>::gcgen_cur;
01328 template<typename Double> int ADvari<Double>::last_opno;
01329 template<typename Double> int ADvari<Double>::zap_gcgen;
01330 template<typename Double> int ADvari<Double>::zap_gcgen1 = RAD_DEBUG_gcgen1;
01331 template<typename Double> int ADvari<Double>::zap_opno;
01332 template<typename Double> FILE *ADvari<Double>::debug_file;
01333 #endif
01334
01335
01336 template<typename Double> ADcontext<Double>::ADcontext()
01337 {
01338 First = (ADMemblock*)First0;
01339 First->next = 0;
01340 Busy = First;
01341 Free = 0;
01342 Mbase = (char*)First->memblk;
01343 Mleft = sizeof(First->memblk);
01344 rad_need_reinit = 0;
01345 #ifdef RAD_DEBUG_BLOCKKEEP
01346 rad_busy_blocks = 0;
01347 rad_mleft_save = 0;
01348 rad_Oldcurmb = 0;
01349 #endif
01350 #if RAD_REINIT > 0
01351 DBusy = (ADMemblock*)DFirst0;
01352 DBusy->next = 0;
01353 DFree = 0;
01354 DMleft = nderps = sizeof(DBusy->memblk)/sizeof(DErp);
01355 #endif
01356 }
01357
01358 template<typename Double> void*
01359 ADcontext<Double>::new_ADmemblock(size_t len)
01360 {
01361 ADMemblock *mb, *mb0, *mb1, *mbf, *x;
01362 #if RAD_REINIT == 1
01363 typedef IndepADvar_base0<Double> ADvb;
01364 typedef IndepADvar<Double> IADv;
01365 ADVari *tcv;
01366 ADvb *vb, *vb0;
01367 #endif
01368
01369 if ((rad_need_reinit & 1) && this == &ADVari::adc) {
01370 rad_need_reinit &= ~1;
01371 RAD_REINIT_0(DErp::LastDerp = 0;)
01372 #ifdef RAD_DEBUG_BLOCKKEEP
01373 Mleft = rad_mleft_save;
01374 if (Mleft < sizeof(First->memblk))
01375 _uninit_f2c(Mbase + Mleft,
01376 UninitType<Double>::utype,
01377 (sizeof(First->memblk) - Mleft)
01378 /sizeof(typename Sacado::ValueType<Double>::type));
01379 if (mb = Busy->next) {
01380 if (!(mb0 = rad_Oldcurmb))
01381 mb0 = (ADMemblock*)First0;
01382 for(;; mb = mb->next) {
01383 _uninit_f2c(mb->memblk,
01384 UninitType<Double>::utype,
01385 sizeof(First->memblk)
01386 /sizeof(typename Sacado::ValueType<Double>::type));
01387 if (mb == mb0)
01388 break;
01389 }
01390 }
01391 rad_Oldcurmb = Busy;
01392 if (rad_busy_blocks >= RAD_DEBUG_BLOCKKEEP) {
01393 rad_busy_blocks = 0;
01394 rad_Oldcurmb = 0;
01395 mb0 = (ADMemblock*)First0;
01396 mbf = Free;
01397 for(mb = Busy; mb != mb0; mb = mb1) {
01398 mb1 = mb->next;
01399 mb->next = mbf;
01400 mbf = mb;
01401 }
01402 Free = mbf;
01403 Busy = mb;
01404 Mbase = (char*)First->memblk;
01405 Mleft = sizeof(First->memblk);
01406 }
01407
01408 #else
01409
01410 mb0 = First;
01411 mbf = Free;
01412 for(mb = Busy; mb != mb0; mb = mb1) {
01413 mb1 = mb->next;
01414 mb->next = mbf;
01415 mbf = mb;
01416 }
01417 Free = mbf;
01418 Busy = mb;
01419 Mbase = (char*)First->memblk;
01420 Mleft = sizeof(First->memblk);
01421 #endif
01422 #if RAD_REINIT > 0
01423 mb = mb0 = DBusy;
01424 while(mb1 = mb->next) {
01425 mb->next = mb0;
01426 mb0 = mb;
01427 mb = mb1;
01428 }
01429 DBusy = mb;
01430 DFree = mb->next;
01431 mb->next = 0;
01432 DMleft = nderps;
01433 #if RAD_REINIT == 1
01434 vb = vb0 = &IndepADvar_base<Double>::IndepADvar_root;
01435 while((vb = vb->ADvnext) != vb0)
01436 if ((tcv = ((IADv*)vb)->cv))
01437 ((IADv*)vb)->cv = new ADVari(tcv->Val);
01438 #elif RAD_REINIT == 2
01439 ++IndepADvar<Double>::gen0;
01440 #endif
01441 #endif
01442 if (Mleft >= len)
01443 return Mbase + (Mleft -= len);
01444 }
01445
01446 if ((x = Free))
01447 Free = x->next;
01448 else
01449 x = new ADMemblock;
01450 #ifdef RAD_DEBUG_BLOCKKEEP
01451 rad_busy_blocks++;
01452 #endif
01453 x->next = Busy;
01454 Busy = x;
01455 return (Mbase = (char*)x->memblk) +
01456 (Mleft = sizeof(First->memblk) - len);
01457 }
01458
01459 template<typename Double> void
01460 ADcontext<Double>::Gradcomp()
01461 {
01462 #if RAD_REINIT > 0 //{{
01463 ADMemblock *mb;
01464 DErp *d, *de;
01465
01466 if (ADVari::adc.rad_need_reinit) {
01467 mb = ADVari::adc.DBusy;
01468 d = ((DErp*)mb->memblk) + ADVari::adc.DMleft;
01469 de = ((DErp*)mb->memblk) + ADVari::adc.nderps;
01470 for(;;) {
01471 for(; d < de; d++)
01472 d->c->aval = 0;
01473 if (!(mb = mb->next))
01474 break;
01475 d = (DErp*)mb->memblk;
01476 de = d + ADVari::adc.nderps;
01477 }
01478 }
01479 #else //}{ RAD_REINIT == 0
01480 DErp *d;
01481 #ifdef RAD_AUTO_AD_Const
01482 ADVari *a, *anext;
01483 IndepADvar<Double> *v;
01484 #ifdef RAD_Const_WARN
01485 ADVari *cv;
01486 int i, j;
01487 #endif
01488 #endif
01489
01490 if (ADVari::adc.rad_need_reinit) {
01491 for(d = DErp::LastDerp; d; d = d->next)
01492 d->c->aval = 0;
01493 }
01494 #endif //}} RAD_REINIT
01495
01496 if (!(ADVari::adc.rad_need_reinit & 1)) {
01497 ADVari::adc.rad_need_reinit = 1;
01498 ADVari::adc.rad_mleft_save = ADVari::adc.Mleft;
01499 ADVari::adc.Mleft = 0;
01500 RAD_REINIT_2(++IndepADvar_base<Double>::IndepADvar_root.gen;)
01501 }
01502 #ifdef RAD_DEBUG
01503 if (ADVari::gcgen_cur == ADVari::zap_gcgen1) {
01504 const char *fname;
01505 if (!(fname = getenv("RAD_DEBUG_FILE")))
01506 fname = "rad_debug.out";
01507 else if (!*fname)
01508 fname = 0;
01509 if (fname)
01510 ADVari::debug_file = fopen(fname, "w");
01511 ADVari::zap_gcgen1 = -1;
01512 }
01513 #endif
01514 #if RAD_REINIT > 0 //{{
01515 if (ADVari::adc.DMleft < ADVari::adc.nderps) {
01516 mb = ADVari::adc.DBusy;
01517 d = ((DErp*)mb->memblk) + ADVari::adc.DMleft;
01518 de = ((DErp*)mb->memblk) + ADVari::adc.nderps;
01519 d->b->aval = 1;
01520 for(;;) {
01521 #ifdef RAD_DEBUG
01522 if (ADVari::debug_file) {
01523 for(; d < de; d++) {
01524 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01525 d->c->opno, d->b->opno, d->c->aval, d->a, d->b->aval);
01526 d->c->aval += d->a * d->b->aval;
01527 fprintf(ADVari::debug_file, " = %g\n", d->c->aval);
01528 }
01529 }
01530 else
01531 #endif
01532 for(; d < de; d++)
01533 d->c->aval += d->a * d->b->aval;
01534 if (!(mb = mb->next))
01535 break;
01536 d = (DErp*)mb->memblk;
01537 de = d + ADVari::adc.nderps;
01538 }
01539 }
01540 #else //}{ RAD_REINIT == 0
01541 if ((d = DErp::LastDerp)) {
01542 d->b->aval = 1;
01543 #ifdef RAD_DEBUG
01544 if (ADVari::debug_file)
01545 do {
01546 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01547 d->c->opno, d->b->opno, d->c->aval, *d->a, d->b->aval);
01548 d->c->aval += *d->a * d->b->aval;
01549 fprintf(ADVari::debug_file, " = %g\n", d->c->aval);
01550 } while(d = d->next);
01551 else
01552 #endif
01553 do d->c->aval += *d->a * d->b->aval;
01554 while((d = d->next));
01555 }
01556 #ifdef RAD_DEBUG
01557 if (ADVari::debug_file) {
01558 fclose(ADVari::debug_file);
01559 ADVari::debug_file = 0;
01560 }
01561 #endif //RAD_DEBUG
01562 #ifdef RAD_AUTO_AD_Const // {
01563 *ADVari::Last_ADvari = 0;
01564 ADVari::Last_ADvari = &ADVari::First_ADvari;
01565 if ((anext = ADVari::First_ADvari) && !(ADVari::adc.rad_need_reinit & 2)) {
01566 ADVari::adc.rad_need_reinit = 3;
01567 while((a = anext)) {
01568 anext = a->Next;
01569 if ((v = (IndepADvar<Double> *)a->padv)) {
01570 #ifdef RAD_Const_WARN
01571 if ((i = a->opno) > 0)
01572 i = -i;
01573 j = a->gcgen;
01574 v->cv = cv = new ADVari(v, a->Val, a->aval);
01575 cv->opno = i;
01576 cv->gcgen = j;
01577 #else
01578 v->cv = new ADVari(v, a->Val, a->aval);
01579 #endif
01580 }
01581 }
01582 }
01583 #endif // } RAD_AUTO_AD_Const
01584 #endif // }} RAD_REINIT
01585 #ifdef RAD_DEBUG
01586 if (ADVari::debug_file)
01587 fflush(ADVari::debug_file);
01588 ADVari::gcgen_cur++;
01589 ADVari::last_opno = 0;
01590 #endif
01591 }
01592
01593 template<typename Double> void
01594 ADcontext<Double>::Weighted_Gradcomp(int n, ADVar **V, Double *w)
01595 {
01596 int i;
01597 #if RAD_REINIT > 0 //{{
01598 ADMemblock *mb;
01599 DErp *d, *de;
01600
01601 if (ADVari::adc.rad_need_reinit) {
01602 mb = ADVari::adc.DBusy;
01603 d = ((DErp*)mb->memblk) + ADVari::adc.DMleft;
01604 de = ((DErp*)mb->memblk) + ADVari::adc.nderps;
01605 for(;;) {
01606 for(; d < de; d++)
01607 d->c->aval = 0;
01608 if (!(mb = mb->next))
01609 break;
01610 d = (DErp*)mb->memblk;
01611 de = d + ADVari::adc.nderps;
01612 }
01613 }
01614 #else //}{ RAD_REINIT == 0
01615 DErp *d;
01616 #ifdef RAD_AUTO_AD_Const
01617 ADVari *a, *anext;
01618 IndepADvar<Double> *v;
01619 #ifdef RAD_Const_WARN
01620 ADVari *cv;
01621 int j;
01622 #endif
01623 #endif
01624
01625 if (ADVari::adc.rad_need_reinit) {
01626 for(d = DErp::LastDerp; d; d = d->next)
01627 d->c->aval = 0;
01628 }
01629 #endif //}} RAD_REINIT
01630
01631 if (!(ADVari::adc.rad_need_reinit & 1)) {
01632 ADVari::adc.rad_need_reinit = 1;
01633 ADVari::adc.rad_mleft_save = ADVari::adc.Mleft;
01634 ADVari::adc.Mleft = 0;
01635 RAD_REINIT_2(++IndepADvar_base<Double>::IndepADvar_root.gen;)
01636 }
01637 #ifdef RAD_DEBUG
01638 if (ADVari::gcgen_cur == ADVari::zap_gcgen1) {
01639 const char *fname;
01640 if (!(fname = getenv("RAD_DEBUG_FILE")))
01641 fname = "rad_debug.out";
01642 else if (!*fname)
01643 fname = 0;
01644 if (fname)
01645 ADVari::debug_file = fopen(fname, "w");
01646 ADVari::zap_gcgen1 = -1;
01647 }
01648 #endif
01649 #if RAD_REINIT > 0 //{{
01650 if (ADVari::adc.DMleft < ADVari::adc.nderps) {
01651 for(i = 0; i < n; i++)
01652 V[i]->cv->aval = w[i];
01653 mb = ADVari::adc.DBusy;
01654 d = ((DErp*)mb->memblk) + ADVari::adc.DMleft;
01655 de = ((DErp*)mb->memblk) + ADVari::adc.nderps;
01656 d->b->aval = 1;
01657 for(;;) {
01658 #ifdef RAD_DEBUG
01659 if (ADVari::debug_file) {
01660 for(; d < de; d++) {
01661 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01662 d->c->opno, d->b->opno, d->c->aval, d->a, d->b->aval);
01663 d->c->aval += d->a * d->b->aval;
01664 fprintf(ADVari::debug_file, " = %g\n", d->c->aval);
01665 }
01666 }
01667 else
01668 #endif
01669 for(; d < de; d++)
01670 d->c->aval += d->a * d->b->aval;
01671 if (!(mb = mb->next))
01672 break;
01673 d = (DErp*)mb->memblk;
01674 de = d + ADVari::adc.nderps;
01675 }
01676 }
01677 #else //}{ RAD_REINIT == 0
01678 if (d = DErp::LastDerp) {
01679 for(i = 0; i < n; i++)
01680 V[i]->cv->aval = w[i];
01681 #ifdef RAD_DEBUG
01682 if (ADVari::debug_file)
01683 do {
01684 fprintf(ADVari::debug_file, "%d\t%d\t%g + %g * %g",
01685 d->c->opno, d->b->opno, d->c->aval, *d->a, d->b->aval);
01686 d->c->aval += *d->a * d->b->aval;
01687 fprintf(ADVari::debug_file, " = %g\n", d->c->aval);
01688 } while(d = d->next);
01689 else
01690 #endif
01691 do d->c->aval += *d->a * d->b->aval;
01692 while((d = d->next));
01693 }
01694 #ifdef RAD_DEBUG
01695 if (ADVari::debug_file) {
01696 fclose(ADVari::debug_file);
01697 ADVari::debug_file = 0;
01698 }
01699 #endif //RAD_DEBUG
01700 #ifdef RAD_AUTO_AD_Const // {
01701 *ADVari::Last_ADvari = 0;
01702 ADVari::Last_ADvari = &ADVari::First_ADvari;
01703 if ((anext = ADVari::First_ADvari) && !(ADVari::adc.rad_need_reinit & 2)) {
01704 ADVari::adc.rad_need_reinit = 3;
01705 while((a = anext)) {
01706 anext = a->Next;
01707 if ((v = (IndepADvar<Double> *)a->padv)) {
01708 #ifdef RAD_Const_WARN
01709 if ((i = a->opno) > 0)
01710 i = -i;
01711 j = a->gcgen;
01712 v->cv = cv = new ADVari(v, a->Val, a->aval);
01713 cv->opno = i;
01714 cv->gcgen = j;
01715 #else
01716 v->cv = new ADVari(v, a->Val, a->aval);
01717 #endif
01718 }
01719 }
01720 }
01721 #endif // } RAD_AUTO_AD_Const
01722 #endif // }} RAD_REINIT
01723 #ifdef RAD_DEBUG
01724 if (ADVari::debug_file)
01725 fflush(ADVari::debug_file);
01726 ADVari::gcgen_cur++;
01727 ADVari::last_opno = 0;
01728 #endif
01729 }
01730
01731 template<typename Double>
01732 IndepADvar<Double>::IndepADvar(Ttype d) Allow_noderiv(: IndepADvar_base<Double>(1))
01733 {
01734 RAD_REINIT_1(cv = 0;)
01735 cv = new ADVari(d);
01736 RAD_REINIT_2(Val = d; this->gen = this->IndepADvar_root.gen;)
01737 }
01738
01739 template<typename Double>
01740 IndepADvar<Double>::IndepADvar(double i) Allow_noderiv(: IndepADvar_base<Double>(1))
01741 {
01742 RAD_REINIT_1(cv = 0;)
01743 cv = new ADVari(Double(i));
01744 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
01745 }
01746
01747 template<typename Double>
01748 IndepADvar<Double>::IndepADvar(int i) Allow_noderiv(: IndepADvar_base<Double>(1))
01749 {
01750 RAD_REINIT_1(cv = 0;)
01751 cv = new ADVari(Double(i));
01752 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
01753 }
01754
01755 template<typename Double>
01756 IndepADvar<Double>::IndepADvar(long i) Allow_noderiv(: IndepADvar_base<Double>(1))
01757 {
01758 RAD_REINIT_1(cv = 0;)
01759 cv = new ADVari(Double(i));
01760 RAD_REINIT_2(Val = i; this->gen = this->IndepADvar_root.gen;)
01761 }
01762
01763 template<typename Double>
01764 ConstADvar<Double>::ConstADvar()
01765 {
01766 RAD_REINIT_1(this->cv = 0;)
01767 this->cv = new ConstADVari(0.);
01768 RAD_REINIT_2(this->Val = 0.; this->gen = this->IndepADvar_root.gen;)
01769 }
01770
01771 template<typename Double> void
01772 ConstADvar<Double>::ConstADvar_ctr(Double d)
01773 {
01774 RAD_REINIT_1(this->cv = 0;)
01775 this->cv = new ConstADVari(d);
01776 RAD_REINIT_2(this->Val = d; this->gen = this->IndepADvar_root.gen;)
01777 }
01778
01779 template<typename Double>
01780 ConstADvar<Double>::ConstADvar(const IndepADVar &x)
01781 {
01782 RAD_cvchk(x)
01783 RAD_REINIT_1(this->cv = 0;)
01784 ConstADVari *y = new ConstADVari(x.cv->Val);
01785 #if RAD_REINIT > 0
01786 x.cv->adc.new_Derp(&x.adc.One, y, x.cv);
01787 #else
01788 DErp *d = new DErp(&x.adc.One, y, x.cv);
01789 #endif
01790 this->cv = y;
01791 RAD_REINIT_2(this->Val = y->Val; this->gen = this->IndepADvar_root.gen;)
01792 }
01793
01794 template<typename Double>
01795 ConstADvar<Double>::ConstADvar(const ConstADvar &x)
01796 {
01797 RAD_cvchk(x)
01798 RAD_REINIT_1(this->cv = 0;)
01799 ConstADVari *y = new ConstADVari(x.cv->Val);
01800 #if RAD_REINIT > 0
01801 x.cv->adc.new_Derp(&x.cv->adc.One, y, x.cv);
01802 #else
01803 DErp *d = new DErp(&x.cv->adc.One, y, (ADVari*)x.cv);
01804 #endif
01805 this->cv = y;
01806 RAD_REINIT_2(this->Val = y->Val; this->gen = this->IndepADvar_root.gen;)
01807 }
01808
01809 template<typename Double>
01810 ConstADvar<Double>::ConstADvar(const ADVari &x)
01811 {
01812 RAD_REINIT_1(this->cv = 0;)
01813 ConstADVari *y = new ConstADVari(x.Val);
01814 #if RAD_REINIT > 0
01815 x.adc.new_Derp(&x.adc.One, y, &x);
01816 #else
01817 DErp *d = new DErp(&x.adc.One, y, &x);
01818 #endif
01819 this->cv = y;
01820 RAD_REINIT_2(this->Val = y->Val; this->gen = this->IndepADvar_root.gen;)
01821 }
01822
01823 template<typename Double>
01824 void
01825 IndepADvar<Double>::AD_Const(const IndepADvar &v)
01826 {
01827 typedef ConstADvari<Double> ConstADVari;
01828
01829 ConstADVari *ncv = new ConstADVari(v.val());
01830 #ifdef RAD_AUTO_AD_Const
01831 v.cv->padv = 0;
01832 #endif
01833 v.cv = ncv;
01834 RAD_REINIT_2(v.gen = v.IndepADvar_root.gen;)
01835 }
01836
01837 template<typename Double>
01838 int
01839 IndepADvar<Double>::Wantderiv(int n)
01840 {
01841 #ifdef RAD_ALLOW_WANTDERIV
01842 #if RAD_REINIT == 2
01843 if (this->gen != this->IndepADvar_root.gen) {
01844 cv = new ADVari(Val);
01845 this->gen = this->IndepADvar_root.gen;
01846 }
01847 #endif
01848 return this->wantderiv = cv->wantderiv = n;
01849 #else
01850 return 1;
01851 #endif // RAD_ALLOW_WANTDERIV
01852 }
01853
01854 template<typename Double>
01855 void
01856 ConstADvari<Double>::aval_reset()
01857 {
01858 #if RAD_REINIT == 0
01859 ConstADvari *x = ConstADvari::lastcad;
01860 while(x) {
01861 x->aval = 0;
01862 x = x->prevcad;
01863 }
01864 #elif RAD_REINIT == 1
01865 ADvari<Double>::adc.new_ADmemblock(0);
01866 #endif
01867 }
01868
01869 #ifdef RAD_AUTO_AD_Const
01870
01871 template<typename Double>
01872 ADvari<Double>::ADvari(const IndepADVar *x, Double d): Val(d), aval(0.)
01873 {
01874 *Last_ADvari = this;
01875 Last_ADvari = &Next;
01876 this->padv = (IndepADVar*)x;
01877 Allow_noderiv(wantderiv = 1;)
01878 }
01879
01880 template<typename Double>
01881 ADvari<Double>::ADvari(const IndepADVar *x, Double d, Double g): Val(d), aval(g)
01882 {
01883 *Last_ADvari = this;
01884 Last_ADvari = &Next;
01885 this->padv = (IndepADVar*)x;
01886 Allow_noderiv(wantderiv = 1;)
01887 }
01888
01889 template<typename Double>
01890 ADvar1<Double>::ADvar1(const IndepADVar *x, const IndepADVar &y):
01891 ADVari(y.cv->Val), d((const Double*)&ADcontext<Double>::One, (ADVari*)this, y.cv)
01892 {
01893 *ADVari::Last_ADvari = this;
01894 ADVari::Last_ADvari = &this->Next;
01895 this->padv = x;
01896 }
01897
01898 template<typename Double>
01899 ADvar1<Double>::ADvar1(const IndepADVar *x, const ADVari &y):
01900 ADVari(y.Val), d((const Double*)&ADcontext<Double>::One, this, &y)
01901 {
01902 *ADVari::Last_ADvari = this;
01903 ADVari::Last_ADvari = &this->Next;
01904 this->padv = x;
01905 }
01906
01907 #else
01908
01909 template<typename Double>
01910 IndepADvar<Double>&
01911 ADvar_operatoreq(IndepADvar<Double> *This, const ADvari<Double> &x)
01912 {
01913 This->cv = new ADvar1<Double>(x.Val, &x.adc.One, &x);
01914 RAD_REINIT_1(This->Move_to_end();)
01915 RAD_REINIT_2(This->Val = x.Val; This->gen = This->IndepADvar_root.gen;)
01916 return *(IndepADvar<Double>*) This;
01917 }
01918
01919 template<typename Double>
01920 ADvar<Double>&
01921 ADvar_operatoreq(ADvar<Double> *This, const ADvari<Double> &x)
01922 {
01923 This->cv = new ADvar1<Double>(x.Val, &x.adc.One, &x);
01924 RAD_REINIT_1(This->Move_to_end();)
01925 RAD_REINIT_2(This->Val = x.Val; This->gen = This->IndepADvar_root.gen;)
01926 return *(ADvar<Double>*) This;
01927 }
01928
01929 #endif
01930
01931
01932 template<typename Double>
01933 IndepADvar<Double>&
01934 IndepADvar<Double>::operator=(Double d)
01935 {
01936 #ifdef RAD_AUTO_AD_Const
01937 if (this->cv)
01938 this->cv->padv = 0;
01939 this->cv = new ADVari(this,d);
01940 #else
01941 this->cv = new ADVari(d);
01942 RAD_REINIT_1(this->Move_to_end();)
01943 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
01944 #endif
01945 return *this;
01946 }
01947
01948 template<typename Double>
01949 ADvar<Double>&
01950 ADvar<Double>::operator=(Double d)
01951 {
01952 #ifdef RAD_AUTO_AD_Const
01953 if (this->cv)
01954 this->cv->padv = 0;
01955 this->cv = new ADVari(this,d);
01956 #else
01957 this->cv = RAD_REINIT_0(ConstADVari::cadc.fpval_implies_const
01958 ? new ConstADVari(d)
01959 : ) new ADVari(d);
01960 RAD_REINIT_1(this->Move_to_end();)
01961 RAD_REINIT_2(this->Val = d; this->gen = this->IndepADvar_root.gen;)
01962 #endif
01963 return *this;
01964 }
01965
01966 template<typename Double>
01967 ADvari<Double>&
01968 operator-(const ADvari<Double> &T) {
01969 return *(new ADvar1<Double>(-T.Val, &T.adc.negOne, &T));
01970 }
01971
01972 template<typename Double>
01973 ADvari<Double>&
01974 operator+(const ADvari<Double> &L, const ADvari<Double> &R) {
01975 return *(new ADvar2<Double>(L.Val + R.Val, &L, &L.adc.One, &R, &L.adc.One));
01976 }
01977
01978 #ifdef RAD_AUTO_AD_Const
01979 #define RAD_ACA ,this
01980 #else
01981 #define RAD_ACA
01982 #endif
01983
01984 template<typename Double>
01985 ADvar<Double>&
01986 ADvar<Double>::operator+=(const ADVari &R) {
01987 ADVari *Lcv = this->cv;
01988 this->cv = new ADvar2<Double>(Lcv->Val + R.Val, Lcv, &R.adc.One, &R, &R.adc.One RAD_ACA);
01989 RAD_REINIT_1(this->Move_to_end();)
01990 RAD_REINIT_2(this->Val = this->cv->Val;)
01991 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
01992 return *this;
01993 }
01994
01995 template<typename Double>
01996 ADvari<Double>&
01997 operator+(const ADvari<Double> &L, Double R) {
01998 return *(new ADvar1<Double>(L.Val + R, &L.adc.One, &L));
01999 }
02000
02001 template<typename Double>
02002 ADvar<Double>&
02003 ADvar<Double>::operator+=(Double R) {
02004 ADVari *tcv = this->cv;
02005 this->cv = new ADVar1(tcv->Val + R, &tcv->adc.One, tcv RAD_ACA);
02006 RAD_REINIT_1(this->Move_to_end();)
02007 RAD_REINIT_2(this->Val = this->cv->Val;)
02008 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02009 return *this;
02010 }
02011
02012 template<typename Double>
02013 ADvari<Double>&
02014 operator+(Double L, const ADvari<Double> &R) {
02015 return *(new ADvar1<Double>(L + R.Val, &R.adc.One, &R));
02016 }
02017
02018 template<typename Double>
02019 ADvari<Double>&
02020 operator-(const ADvari<Double> &L, const ADvari<Double> &R) {
02021 return *(new ADvar2<Double>(L.Val - R.Val, &L, &L.adc.One, &R, &L.adc.negOne));
02022 }
02023
02024 template<typename Double>
02025 ADvar<Double>&
02026 ADvar<Double>::operator-=(const ADVari &R) {
02027 ADVari *Lcv = this->cv;
02028 this->cv = new ADvar2<Double>(Lcv->Val - R.Val, Lcv, &R.adc.One, &R, &R.adc.negOne RAD_ACA);
02029 RAD_REINIT_1(this->Move_to_end();)
02030 RAD_REINIT_2(this->Val = this->cv->Val;)
02031 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02032 return *this;
02033 }
02034
02035 template<typename Double>
02036 ADvari<Double>&
02037 operator-(const ADvari<Double> &L, Double R) {
02038 return *(new ADvar1<Double>(L.Val - R, &L.adc.One, &L));
02039 }
02040
02041 template<typename Double>
02042 ADvar<Double>&
02043 ADvar<Double>::operator-=(Double R) {
02044 ADVari *tcv = this->cv;
02045 this->cv = new ADVar1(tcv->Val - R, &tcv->adc.One, tcv RAD_ACA);
02046 RAD_REINIT_1(this->Move_to_end();)
02047 RAD_REINIT_2(this->Val = this->cv->Val;)
02048 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02049 return *this;
02050 }
02051
02052 template<typename Double>
02053 ADvari<Double>&
02054 operator-(Double L, const ADvari<Double> &R) {
02055 return *(new ADvar1<Double>(L - R.Val, &R.adc.negOne, &R));
02056 }
02057
02058 template<typename Double>
02059 ADvari<Double>&
02060 operator*(const ADvari<Double> &L, const ADvari<Double> &R) {
02061 return *(new ADvar2<Double>(L.Val * R.Val, &L, &R.Val, &R, &L.Val));
02062 }
02063
02064 template<typename Double>
02065 ADvar<Double>&
02066 ADvar<Double>::operator*=(const ADVari &R) {
02067 ADVari *Lcv = this->cv;
02068 this->cv = new ADvar2<Double>(Lcv->Val * R.Val, Lcv, &R.Val, &R, &Lcv->Val RAD_ACA);
02069 RAD_REINIT_1(this->Move_to_end();)
02070 RAD_REINIT_2(this->Val = this->cv->Val;)
02071 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02072 return *this;
02073 }
02074
02075 template<typename Double>
02076 ADvari<Double>&
02077 operator*(const ADvari<Double> &L, Double R) {
02078 return *(new ADvar1s<Double>(L.Val * R, R, &L));
02079 }
02080
02081 template<typename Double>
02082 ADvar<Double>&
02083 ADvar<Double>::operator*=(Double R) {
02084 ADVari *Lcv = this->cv;
02085 this->cv = new ADvar1s<Double>(Lcv->Val * R, R, Lcv RAD_ACA);
02086 RAD_REINIT_1(this->Move_to_end();)
02087 RAD_REINIT_2(this->Val = this->cv->Val;)
02088 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02089 return *this;
02090 }
02091
02092 template<typename Double>
02093 ADvari<Double>&
02094 operator*(Double L, const ADvari<Double> &R) {
02095 return *(new ADvar1s<Double>(L * R.Val, L, &R));
02096 }
02097
02098 template<typename Double>
02099 ADvari<Double>&
02100 operator/(const ADvari<Double> &L, const ADvari<Double> &R) {
02101 Double Lv = L.Val, Rv = R.Val, pL = 1. / Rv, q = Lv/Rv;
02102 return *(new ADvar2q<Double>(q, pL, -q*pL, &L, &R));
02103 }
02104
02105 template<typename Double>
02106 ADvar<Double>&
02107 ADvar<Double>::operator/=(const ADVari &R) {
02108 ADVari *Lcv = this->cv;
02109 Double Lv = Lcv->Val, Rv = R.Val, pL = 1. / Rv, q = Lv/Rv;
02110 this->cv = new ADvar2q<Double>(q, pL, -q*pL, Lcv, &R RAD_ACA);
02111 RAD_REINIT_1(this->Move_to_end();)
02112 RAD_REINIT_2(this->Val = this->cv->Val;)
02113 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02114 return *this;
02115 }
02116
02117 template<typename Double>
02118 ADvari<Double>&
02119 operator/(const ADvari<Double> &L, Double R) {
02120 return *(new ADvar1s<Double>(L.Val / R, 1./R, &L));
02121 }
02122
02123 template<typename Double>
02124 ADvari<Double>&
02125 operator/(Double L, const ADvari<Double> &R) {
02126 Double recip = 1. / R.Val;
02127 Double q = L * recip;
02128 return *(new ADvar1s<Double>(q, -q*recip, &R));
02129 }
02130
02131 template<typename Double>
02132 ADvar<Double>&
02133 ADvar<Double>::operator/=(Double R) {
02134 ADVari *Lcv = this->cv;
02135 this->cv = new ADvar1s<Double>(Lcv->Val / R, 1./R, Lcv RAD_ACA);
02136 RAD_REINIT_1(this->Move_to_end();)
02137 RAD_REINIT_2(this->Val = this->cv->Val;)
02138 RAD_REINIT_2(this->gen = this->IndepADvar_root.gen;)
02139 return *this;
02140 }
02141
02142 template<typename Double>
02143 ADvari<Double>&
02144 acos(const ADvari<Double> &v) {
02145 Double t = v.Val;
02146 return *(new ADvar1s<Double>(std::acos(t), -1./std::sqrt(1. - t*t), &v));
02147 }
02148
02149 template<typename Double>
02150 ADvari<Double>&
02151 acosh(const ADvari<Double> &v) {
02152 Double t = v.Val, t1 = std::sqrt(t*t - 1.);
02153 return *(new ADvar1s<Double>(std::log(t + t1), 1./t1, &v));
02154 }
02155
02156 template<typename Double>
02157 ADvari<Double>&
02158 asin(const ADvari<Double> &v) {
02159 Double t = v.Val;
02160 return *(new ADvar1s<Double>(std::asin(t), 1./std::sqrt(1. - t*t), &v));
02161 }
02162
02163 template<typename Double>
02164 ADvari<Double>&
02165 asinh(const ADvari<Double> &v) {
02166 Double t = v.Val, td = 1., t1 = std::sqrt(t*t + 1.);
02167 if (t < 0.) {
02168 t = -t;
02169 td = -1.;
02170 }
02171 return *(new ADvar1s<Double>(td*std::log(t + t1), 1./t1, &v));
02172 }
02173
02174 template<typename Double>
02175 ADvari<Double>&
02176 atan(const ADvari<Double> &v) {
02177 Double t = v.Val;
02178 return *(new ADvar1s<Double>(std::atan(t), 1./(1. + t*t), &v));
02179 }
02180
02181 template<typename Double>
02182 ADvari<Double>&
02183 atanh(const ADvari<Double> &v) {
02184 Double t = v.Val;
02185 return *(new ADvar1s<Double>(0.5*std::log((1.+t)/(1.-t)), 1./(1. - t*t), &v));
02186 }
02187
02188 template<typename Double>
02189 ADvari<Double>&
02190 atan2(const ADvari<Double> &L, const ADvari<Double> &R) {
02191 Double x = L.Val, y = R.Val, t = x*x + y*y;
02192 return *(new ADvar2q<Double>(std::atan2(x,y), y/t, -x/t, &L, &R));
02193 }
02194
02195 template<typename Double>
02196 ADvari<Double>&
02197 atan2(Double x, const ADvari<Double> &R) {
02198 Double y = R.Val, t = x*x + y*y;
02199 return *(new ADvar1s<Double>(std::atan2(x,y), -x/t, &R));
02200 }
02201
02202 template<typename Double>
02203 ADvari<Double>&
02204 atan2(const ADvari<Double> &L, Double y) {
02205 Double x = L.Val, t = x*x + y*y;
02206 return *(new ADvar1s<Double>(std::atan2(x,y), y/t, &L));
02207 }
02208
02209 template<typename Double>
02210 ADvari<Double>&
02211 max(const ADvari<Double> &L, const ADvari<Double> &R) {
02212 const ADvari<Double> &x = L.Val >= R.Val ? L : R;
02213 return *(new ADvar1<Double>(x.Val, &x.adc.One, &x));
02214 }
02215
02216 template<typename Double>
02217 ADvari<Double>&
02218 max(Double L, const ADvari<Double> &R) {
02219 if (L >= R.Val)
02220 return *(new ADvari<Double>(L));
02221 return *(new ADvar1<Double>(R.Val, &R.adc.One, &R));
02222 }
02223
02224 template<typename Double>
02225 ADvari<Double>&
02226 max(const ADvari<Double> &L, Double R) {
02227 if (L.Val >= R)
02228 return *(new ADvar1<Double>(L.Val, &L.adc.One, &L));
02229 return *(new ADvari<Double>(R));
02230 }
02231
02232 template<typename Double>
02233 ADvari<Double>&
02234 min(const ADvari<Double> &L, const ADvari<Double> &R) {
02235 const ADvari<Double> &x = L.Val <= R.Val ? L : R;
02236 return *(new ADvar1<Double>(x.Val, &x.adc.One, &x));
02237 }
02238
02239 template<typename Double>
02240 ADvari<Double>&
02241 min(Double L, const ADvari<Double> &R) {
02242 if (L <= R.Val)
02243 return *(new ADvari<Double>(L));
02244 return *(new ADvar1<Double>(R.Val, &R.adc.One, &R));
02245 }
02246
02247 template<typename Double>
02248 ADvari<Double>&
02249 min(const ADvari<Double> &L, Double R) {
02250 if (L.Val <= R)
02251 return *(new ADvar1<Double>(L.Val, &L.adc.One, &L));
02252 return *(new ADvari<Double>(R));
02253 }
02254
02255 template<typename Double>
02256 ADvari<Double>&
02257 cos(const ADvari<Double> &v) {
02258 return *(new ADvar1s<Double>(std::cos(v.Val), -std::sin(v.Val), &v));
02259 }
02260
02261 template<typename Double>
02262 ADvari<Double>&
02263 cosh(const ADvari<Double> &v) {
02264 return *(new ADvar1s<Double>(std::cosh(v.Val), std::sinh(v.Val), &v));
02265 }
02266
02267 template<typename Double>
02268 ADvari<Double>&
02269 exp(const ADvari<Double> &v) {
02270 #if RAD_REINIT > 0
02271 Double t = std::exp(v.Val);
02272 return *(new ADvar1s<Double>(t, t, &v));
02273 #else
02274 ADvar1<Double>* rcv = new ADvar1<Double>(std::exp(v.Val), &v);
02275 rcv->d.a = &rcv->Val;
02276 rcv->d.b = rcv;
02277 return *rcv;
02278 #endif
02279 }
02280
02281 template<typename Double>
02282 ADvari<Double>&
02283 log(const ADvari<Double> &v) {
02284 Double x = v.Val;
02285 return *(new ADvar1s<Double>(std::log(x), 1. / x, &v));
02286 }
02287
02288 template<typename Double>
02289 ADvari<Double>&
02290 log10(const ADvari<Double> &v) {
02291 static double num = 1. / std::log(10.);
02292 Double x = v.Val;
02293 return *(new ADvar1s<Double>(std::log10(x), num / x, &v));
02294 }
02295
02296 template<typename Double>
02297 ADvari<Double>&
02298 pow(const ADvari<Double> &L, const ADvari<Double> &R) {
02299 Double x = L.Val, y = R.Val, t = std::pow(x,y);
02300 return *(new ADvar2q<Double>(t, y*t/x, t*std::log(x), &L, &R));
02301 }
02302
02303 template<typename Double>
02304 ADvari<Double>&
02305 pow(Double x, const ADvari<Double> &R) {
02306 Double t = std::pow(x,R.Val);
02307 return *(new ADvar1s<Double>(t, t*std::log(x), &R));
02308 }
02309
02310 template<typename Double>
02311 ADvari<Double>&
02312 pow(const ADvari<Double> &L, Double y) {
02313 Double x = L.Val, t = std::pow(x,y);
02314 return *(new ADvar1s<Double>(t, y*t/x, &L));
02315 }
02316
02317 template<typename Double>
02318 ADvari<Double>&
02319 sin(const ADvari<Double> &v) {
02320 return *(new ADvar1s<Double>(std::sin(v.Val), std::cos(v.Val), &v));
02321 }
02322
02323 template<typename Double>
02324 ADvari<Double>&
02325 sinh(const ADvari<Double> &v) {
02326 return *(new ADvar1s<Double>(std::sinh(v.Val), std::cosh(v.Val), &v));
02327 }
02328
02329 template<typename Double>
02330 ADvari<Double>&
02331 sqrt(const ADvari<Double> &v) {
02332 Double t = std::sqrt(v.Val);
02333 return *(new ADvar1s<Double>(t, 0.5/t, &v));
02334 }
02335
02336 template<typename Double>
02337 ADvari<Double>&
02338 tan(const ADvari<Double> &v) {
02339 Double t = std::cos(v.Val);
02340 return *(new ADvar1s<Double>(std::tan(v.Val), 1./(t*t), &v));
02341 }
02342
02343 template<typename Double>
02344 ADvari<Double>&
02345 tanh(const ADvari<Double> &v) {
02346 Double t = 1. / std::cosh(v.Val);
02347 return *(new ADvar1s<Double>(std::tanh(v.Val), t*t, &v));
02348 }
02349
02350 template<typename Double>
02351 ADvari<Double>&
02352 abs(const ADvari<Double> &v) {
02353 Double t, p;
02354 p = 1;
02355 if ((t = v.Val) < 0) {
02356 t = -t;
02357 p = -p;
02358 }
02359 return *(new ADvar1s<Double>(t, p, &v));
02360 }
02361
02362 template<typename Double>
02363 ADvari<Double>&
02364 fabs(const ADvari<Double> &v) {
02365
02366
02367 Double t, p;
02368 p = 1;
02369 if ((t = v.Val) < 0) {
02370 t = -t;
02371 p = -p;
02372 }
02373 return *(new ADvar1s<Double>(t, p, &v));
02374 }
02375
02376 template<typename Double>
02377 ADvari<Double>&
02378 ADf1(Double f, Double g, const ADvari<Double> &x) {
02379 return *(new ADvar1s<Double>(f, g, &x));
02380 }
02381
02382 template<typename Double>
02383 inline ADvari<Double>&
02384 ADf1(Double f, Double g, const IndepADvar<Double> &x) {
02385 return *(new ADvar1s<Double>(f, g, x.cv));
02386 }
02387
02388 template<typename Double>
02389 ADvari<Double>&
02390 ADf2(Double f, Double gx, Double gy, const ADvari<Double> &x, const ADvari<Double> &y) {
02391 return *(new ADvar2q<Double>(f, gx, gy, &x, &y));
02392 }
02393
02394 template<typename Double>
02395 ADvari<Double>&
02396 ADf2(Double f, Double gx, Double gy, const ADvari<Double> &x, const IndepADvar<Double> &y) {
02397 return *(new ADvar2q<Double>(f, gx, gy, &x, y.cv));
02398 }
02399
02400 template<typename Double>
02401 ADvari<Double>&
02402 ADf2(Double f, Double gx, Double gy, const IndepADvar<Double> &x, const ADvari<Double> &y) {
02403 return *(new ADvar2q<Double>(f, gx, gy, x.cv, &y));
02404 }
02405
02406 template<typename Double>
02407 ADvari<Double>&
02408 ADf2(Double f, Double gx, Double gy, const IndepADvar<Double> &x, const IndepADvar<Double> &y) {
02409 return *(new ADvar2q<Double>(f, gx, gy, x.cv, y.cv));
02410 }
02411
02412 template<typename Double>
02413 ADvari<Double>&
02414 ADfn(Double f, int n, const IndepADvar<Double> *x, const Double *g) {
02415 return *(new ADvarn<Double>(f, n, x, g));
02416 }
02417
02418 template<typename Double>
02419 inline ADvari<Double>&
02420 ADfn(Double f, int n, const ADvar<Double> *x, const Double *g) {
02421 return ADfn<Double>(f, n, (IndepADvar<Double>*)x, g);
02422 }
02423
02424 template<typename Double>
02425 inline Double
02426 val(const ADvari<Double> &x) {
02427 return x.Val;
02428 }
02429
02430 #undef RAD_ACA
02431 #define A (ADvari<Double>*)
02432 #ifdef RAD_Const_WARN
02433 #define C(x) (((x)->opno < 0) ? RAD_Const_Warn(x) : 0, *A x)
02434 #else
02435 #define C(x) *A x
02436 #endif
02437 #define T template<typename Double> inline
02438 #define F ADvari<Double>&
02439 #define Ai const ADvari<Double>&
02440 #define AI const IndepADvar<Double>&
02441 #define D Double
02442 #define T2(r,f) \
02443 T r f(Ai L, AI R) { RAD_cvchk(R) return f(L, C(R.cv)); }\
02444 T r f(AI L, Ai R) { RAD_cvchk(L) return f(C(L.cv), R); }\
02445 T r f(AI L, AI R) { RAD_cvchk(L) RAD_cvchk(R) return f(C(L.cv), C(R.cv)); }\
02446 T r f(AI L, D R) { RAD_cvchk(L) return f(C(L.cv), R); }\
02447 T r f(Ai L, Dtype R) { return f(L, (D)R); }\
02448 T r f(AI L, Dtype R) { RAD_cvchk(L) return f(C(L.cv), (D)R); }\
02449 T r f(Ai L, long R) { return f(L, (D)R); }\
02450 T r f(AI L, long R) { RAD_cvchk(L) return f(C(L.cv), (D)R); }\
02451 T r f(Ai L, int R) { return f(L, (D)R); }\
02452 T r f(AI L, int R) { RAD_cvchk(L) return f(C(L.cv), (D)R); }\
02453 T r f(D L, AI R) { RAD_cvchk(R) return f(L, C(R.cv)); }\
02454 T r f(Dtype L, Ai R) { return f((D)L, R); }\
02455 T r f(Dtype L, AI R) { RAD_cvchk(R) return f((D)L, C(R.cv)); }\
02456 T r f(long L, Ai R) { return f((D)L, R); }\
02457 T r f(long L, AI R) { RAD_cvchk(R) return f((D)L, C(R.cv)); }\
02458 T r f(int L, Ai R) { return f((D)L, R); }\
02459 T r f(int L, AI R) { RAD_cvchk(R) return f((D)L, C(R.cv)); }
02460
02461 T2(F, operator+)
02462 T2(F, operator-)
02463 T2(F, operator*)
02464 T2(F, operator/)
02465 T2(F, atan2)
02466 T2(F, pow)
02467 T2(F, max)
02468 T2(F, min)
02469 T2(int, operator<)
02470 T2(int, operator<=)
02471 T2(int, operator==)
02472 T2(int, operator!=)
02473 T2(int, operator>=)
02474 T2(int, operator>)
02475
02476 #undef T2
02477 #undef D
02478
02479 #define T1(f)\
02480 T F f(AI x) { RAD_cvchk(x) return f(C(x.cv)); }
02481
02482 T1(operator+)
02483 T1(operator-)
02484 T1(abs)
02485 T1(acos)
02486 T1(acosh)
02487 T1(asin)
02488 T1(asinh)
02489 T1(atan)
02490 T1(atanh)
02491 T1(cos)
02492 T1(cosh)
02493 T1(exp)
02494 T1(log)
02495 T1(log10)
02496 T1(sin)
02497 T1(sinh)
02498 T1(sqrt)
02499 T1(tan)
02500 T1(tanh)
02501 T1(fabs)
02502
02503 T F copy(AI x)
02504 {
02505 RAD_cvchk(x)
02506 return *(new ADvar1<Double>(x.cv->Val, &ADcontext<Double>::One, (ADvari<Double>*)x.cv));
02507 }
02508
02509 T F copy(Ai x)
02510 { return *(new ADvar1<Double>(x.Val, &ADcontext<Double>::One, (ADvari<Double>*)&x)); }
02511
02512 #undef RAD_cvchk
02513 #undef T1
02514 #undef AI
02515 #undef Ai
02516 #undef F
02517 #undef T
02518 #undef A
02519 #undef C
02520 #undef Ttype
02521 #undef Dtype
02522
02523 }
02524 }
02525
02526 #undef SNS
02527 #undef RAD_REINIT_2
02528 #undef Allow_noderiv
02529
02530 #endif