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