Sacado_trad.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Sacado Package
00005 //                 Copyright (2006) Sandia Corporation
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
00025 // (etphipp@sandia.gov).
00026 //
00027 // ***********************************************************************
00028 // @HEADER
00029 
00030 // TRAD package (Templated Reverse Automatic Differentiation) --
00031 // a package specialized for function and gradient evaluations.
00032 // Written in 2004 and 2005 by David M. Gay at Sandia National Labs,
00033 // Albuquerque, NM.
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 // RAD_ALLOW_WANTDERIV adds little overhead, so for simplicity
00046 // we make it the default, which can be cancelled by compiling
00047 // with -DRAD_DISALLOW_WANTDERIV:
00048 
00049 #undef RAD_ALLOW_WANTDERIV
00050 #ifndef RAD_DISALLOW_WANTDERIV
00051 #define RAD_ALLOW_WANTDERIV
00052 #endif
00053 
00054 // Adjust names to avoid confusion when different source files
00055 // are compiled with different RAD_REINIT settings.
00056 
00057 #define RAD_REINIT_0(x) /*nothing*/
00058 #define RAD_REINIT_1(x) /*nothing*/
00059 #define RAD_REINIT_2(x) /*nothing*/
00060 #define RAD_cvchk(x)  /*nothing*/
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) /*nothing*/
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*);// outside any namespace for
00118           // ease in setting breakpoints
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>  // must come before namespace Sacado
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 /*RAD_DEBUG_BLOCKKEEP > 0*/
00163 #endif /*RAD_DEBUG_BLOCKKEEP*/
00164 #endif /*RAD_AUTO_AD_Const*/
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 {  // We get memory in ADmemblock chunks and never give it back,
00198     // but reuse it once computations start anew after call(s) on
00199     // ADcontext::Gradcomp() or ADcontext::Weighted_Gradcomp().
00200   ADmemblock *next;
00201   Double memblk[1000];
00202   };
00203 
00204  template<typename Double> class
00205 ADcontext { // A singleton class: one instance in radops.c
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> {  // for possibly constant ADvar values
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 {    // one derivative-propagation operation
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   /* c->aval += a * b->aval; */
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 // Now we use #define to overcome bad design in the C++ templating system
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 {  // implementation of an ADvar
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; // result of this operation
00418   mutable Double aval;  // adjoint -- partial of final result w.r.t. this Val
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*) {} /*Should never be called.*/
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> { // simplest unary ops
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() {}; // prevent construction without value (?)
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> {   // an independent ADvar
00642  protected:
00643   static void AD_Const(const IndepADvar&);
00644   mutable ADvari<Double> *cv;
00645  private:
00646   IndepADvar& operator=(IndepADvar&x) {
00647     /* private to prevent assignment */
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   /* We use #define to deal with bizarre templating rules that apparently */
00747   /* require us to spell the some conversion explicitly */
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> {  // an "active" variable
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() { /* cv = 0; */ }
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   /* allow aliasing v and w after "v = w;" */
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 /* RAD_EQ_ALIAS */
00910 #endif /* RAD_AUTO_AD_Const */
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: // disable op=
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> { // unary ops with partial "a"
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> { // basic binary ops
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> { // binary ops with partials "a", "b"
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> { // n-ary ops with partials "a"
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 /**** radops ****/
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 /* !RAD_DEBUG_BLOCKKEEP */
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 /*RAD_DEBUG_BLOCKKEEP*/
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 /*RAD_AUTO_AD_Const*/
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 /*RAD_AUTO_AD_Const*/
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 /* !RAD_AUTO_AD_Const */
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 /* RAD_AUTO_AD_Const */
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 /*nothing*/
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) { // Synonym for "abs"
02365         // "fabs" is not the best choice of name,
02366         // but this name is used at Sandia.
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 } /* namespace Rad */
02524 } /* namespace Sacado */
02525 
02526 #undef SNS
02527 #undef RAD_REINIT_2
02528 #undef Allow_noderiv
02529 
02530 #endif /* SACADO_TRAD_H */

Generated on Tue Oct 20 12:55:07 2009 for Sacado Package Browser (Single Doxygen Collection) by doxygen 1.4.7