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 {
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> {  // for possibly constant ADvar values
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 {    // one derivative-propagation operation
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   /* c->aval += a * b->aval; */
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 // Now we use #define to overcome bad design in the C++ templating system
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 {  // implementation of an ADvar
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; // result of this operation
00422   mutable Double aval;  // adjoint -- partial of final result w.r.t. this Val
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*) {} /*Should never be called.*/
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> { // simplest unary ops
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() {}; // prevent construction without value (?)
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> {   // an independent ADvar
00644  protected:
00645   static void AD_Const(const IndepADvar&);
00646   mutable ADvari<Double> *cv;
00647  private:
00648   IndepADvar& operator=(IndepADvar&x) {
00649     /* private to prevent assignment */
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   /* We use #define to deal with bizarre templating rules that apparently */
00751   /* require us to spell the some conversion explicitly */
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> {  // an "active" variable
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() { /* cv = 0; */ }
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   /* allow aliasing v and w after "v = w;" */
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 /* RAD_EQ_ALIAS */
00918 #endif /* RAD_AUTO_AD_Const */
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: // disable op=
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> { // unary ops with partial "a"
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> { // basic binary ops
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> { // binary ops with partials "a", "b"
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> { // n-ary ops with partials "a"
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 /**** radops ****/
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 /*RAD_AUTO_AD_Const*/
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 /* !RAD_DEBUG_BLOCKKEEP */
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 /*RAD_DEBUG_BLOCKKEEP*/
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 /* !RAD_AUTO_AD_Const */
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 /* RAD_AUTO_AD_Const */
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 /*nothing*/
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) { // Synonym for "abs"
02340         // "fabs" is not the best choice of name,
02341         // but this name is used at Sandia.
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 } /* namespace Rad */
02499 } /* namespace Sacado */
02500 
02501 #undef SNS
02502 #undef RAD_REINIT_2
02503 #undef Allow_noderiv
02504 
02505 #endif /* SACADO_TRAD_H */

Generated on Wed May 12 21:59:06 2010 for Sacado Package Browser (Single Doxygen Collection) by  doxygen 1.4.7