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

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