Sacado_rad2.hpp

Go to the documentation of this file.
00001 // @HEADER
00002 // ***********************************************************************
00003 //
00004 //                           Sacado Package
00005 //                 Copyright (2007) 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 // Extension of the RAD package (Reverse Automatic Differentiation) --
00031 // a package specialized for function and gradient evaluations -- to
00032 // Hessian-vector products.
00033 // This variant is for Hessian-vector products of "double" variables, and
00034 // Sacado::Rad2d::ADvar should be equivalent to Sacado::Rad2::ADvar<double>,
00035 // but this nontemplated code may easier to understand.  It relies on ops
00036 // implemented in Sacado_radops2.cpp.
00037 // Written in 2007 by David M. Gay at Sandia National Labs, Albuquerque, NM.
00038 
00039 #ifndef SACADO_RAD2_H
00040 #define SACADO_RAD2_H
00041 
00042 #include <stddef.h>
00043 #include <cmath>
00044 #include <math.h>
00045 
00046 #ifndef SACADO_NO_NAMESPACE
00047 namespace Sacado {
00048 namespace Rad2d { // "2" for 2nd derivatives, "d" for "double"
00049 #endif
00050 
00051 // -DNO_USING_STDCC is needed, e.g., with Sun CC 5.7
00052 #ifndef RAD_NO_USING_STDCC
00053   // Bring math functions into scope
00054   using std::exp;
00055   using std::log;
00056   using std::log10;
00057   using std::sqrt;
00058   using std::cos;
00059   using std::sin;
00060   using std::tan;
00061   using std::acos;
00062   using std::asin;
00063   using std::atan;
00064   using std::cosh;
00065   using std::sinh;
00066   using std::tanh;
00067   using std::abs;
00068   using std::fabs;
00069   using std::atan2;
00070   using std::pow;
00071 #endif //NO_USING_STDCC
00072 
00073  class ADvar;
00074  class ADvari;
00075  class ADvar1;
00076  class ADvar2;
00077  class ConstADvar;
00078  class Derp;
00079  class IndepADvar;
00080 
00081  struct
00082 ADmemblock {  // We get memory in ADmemblock chunks and never give it back,
00083     // but reuse it once computations start anew after call(s) on
00084     // ADcontext::Gradcomp() or ADcontext::Weighted_Gradcomp().
00085   ADmemblock *next;
00086   double memblk[2000];
00087   };
00088 
00089  struct
00090 ADvari_block {
00091   enum { Gulp = 1021 };
00092   ADvari_block *next, *prev;
00093   ADvari **limit;
00094   ADvari *pADvari[Gulp];
00095   };
00096 
00097  class
00098 ADcontext { // A singleton class: one instance in radops.c
00099   ADmemblock *Busy, *Free;
00100   char *Mbase;
00101   size_t Mleft;
00102   ADvari **Ailimit, **Ainext;
00103   ADvari_block *Aibusy, *Aifree;
00104   ADmemblock First;
00105   ADvari_block AiFirst;
00106   void *new_ADmemblock(size_t);
00107   void new_ADvari_block();
00108  public:
00109   ADcontext();
00110   void *Memalloc(size_t len);
00111   static void Gradcomp();
00112   static void Hvprod(int, ADvar**, double*, double*);
00113   static void Weighted_Gradcomp(int, ADvar**, double*);
00114   inline void ADvari_record(ADvari *x) {
00115     if (Ainext >= Ailimit)
00116       new_ADvari_block();
00117     *Ainext++ = x;
00118     }
00119   };
00120 
00121 inline void *ADcontext::Memalloc(size_t len) {
00122     if (Mleft >= len)
00123       return Mbase + (Mleft -= len);
00124     return new_ADmemblock(len);
00125     }
00126 
00127  class
00128 CADcontext: public ADcontext {
00129  protected:
00130   bool fpval_implies_const;
00131  public:
00132   friend class ADvar;
00133   CADcontext(): ADcontext() { fpval_implies_const = false; }
00134   static const double One, negOne;
00135   };
00136 
00137  class
00138 Derp {    // one derivative-propagation operation
00139  public:
00140   friend class ADvarn;
00141   static Derp *LastDerp;
00142   Derp *next;
00143   const double *a;
00144   const ADvari *b;
00145   mutable ADvari *c;
00146   void *operator new(size_t);
00147   void operator delete(void*) {} /*Should never be called.*/
00148   inline Derp(){};
00149   Derp(const ADvari *);
00150   Derp(const double *, const ADvari *);
00151   Derp(const double *, const ADvari *, const ADvari *);
00152   /* c->aval += a * b->aval; */
00153   };
00154 
00155 inline Derp::Derp(const ADvari *c1): c((ADvari*)c1) {
00156     next = LastDerp;
00157     LastDerp = this;
00158     }
00159 
00160 inline Derp::Derp(const double *a1, const ADvari *c1):
00161     a(a1), c((ADvari*)c1) {
00162     next = LastDerp;
00163     LastDerp = this;
00164     }
00165 
00166 inline Derp::Derp(const double *a1, const ADvari *b1, const ADvari *c1):
00167     a(a1), b(b1), c((ADvari*)c1) {
00168     next = LastDerp;
00169     LastDerp = this;
00170     }
00171 
00172  enum Advari_Opclass {
00173   Hv_const,
00174   Hv_copy,
00175   Hv_binary,
00176   Hv_unary,
00177   Hv_negate,
00178   Hv_plusLR,
00179   Hv_minusLR,
00180   Hv_timesL,
00181   Hv_timesLR,
00182   Hv_quotLR,
00183   Hv_nary
00184   };
00185 
00186  extern ADvari& ADf1(double f, double g, double h, const ADvari &x);
00187  extern ADvari& ADf2(double f, double gx, double gy, double hxx,
00188       double hxy, double hyy, const ADvari &x, const ADvari &y);
00189  extern ADvari& ADfn(double f, int n, const ADvar *x, const double *g, const double *h);
00190 
00191  class
00192 ADvari {  // implementation of an ADvar
00193  public:
00194   static ADcontext adc;
00195   Advari_Opclass opclass;
00196   double Val;   // result of this operation
00197   mutable double aval;  // adjoint -- partial of final result w.r.t. this Val
00198   mutable double dO;  // deriv of op w.r.t. t in x + t*p
00199   mutable double aO;  // adjoint (in Hv computation) of op
00200   mutable double adO; // adjoint (in Hv computation) of dO
00201   void *operator new(size_t len) { return ADvari::adc.Memalloc(len); }
00202   void operator delete(void*) {} /*Should never be called.*/
00203   inline ADvari(Advari_Opclass oc, double t):
00204     opclass(oc), Val(t), aval(0.), dO(0.)
00205     { if (oc != Hv_const) ADvari::adc.ADvari_record(this); }
00206   inline ADvari(Advari_Opclass oc, double t, double ta):
00207     opclass(oc), Val(t), aval(ta), dO(0.)
00208     { if (oc != Hv_const) ADvari::adc.ADvari_record(this); }
00209  private:
00210   inline ADvari(): Val(0.), aval(0.), dO(0.) {} // prevent construction without value (?)
00211  public:
00212   friend class ConstADvari;
00213 #ifdef RAD_AUTO_AD_Const
00214   friend class ADcontext;
00215   friend class ADvar1;
00216   friend class ADvar;
00217   friend class ConstADvar;
00218   friend class IndepADvar;
00219  private:
00220   ADvari *Next;
00221   static ADvari *First_ADvari, **Last_ADvari;
00222  protected:
00223   IndepADvar *padv;
00224  public:
00225   ADvari(const IndepADvar *, double);
00226 #endif
00227 #define F friend
00228 #define R ADvari&
00229 #define Ai const ADvari&
00230 #define T1(r,f) F r f(Ai);
00231 #define T2(r,f) \
00232 F r f(Ai,Ai); \
00233 F r f(double,Ai); \
00234 F r f(Ai,double);
00235   T1(R,operator+)
00236   T2(R,operator+)
00237   T1(R,operator-)
00238   T2(R,operator-)
00239   T2(R,operator*)
00240   T2(R,operator/)
00241   T1(R,abs)
00242   T1(R,acos)
00243   T1(R,acosh)
00244   T1(R,asin)
00245   T1(R,asinh)
00246   T1(R,atan)
00247   T1(R,atanh)
00248   T2(R,atan2)
00249   T2(R,max)
00250   T2(R,min)
00251   T1(R,cos)
00252   T1(R,cosh)
00253   T1(R,exp)
00254   T1(R,log)
00255   T1(R,log10)
00256   T2(R,pow)
00257   T1(R,sin)
00258   T1(R,sinh)
00259   T1(R,sqrt)
00260   T1(R,tan)
00261   T1(R,tanh)
00262   T1(R,fabs)
00263   T1(R,copy)
00264   T2(int,operator<)
00265   T2(int,operator<=)
00266   T2(int,operator==)
00267   T2(int,operator!=)
00268   T2(int,operator>=)
00269   T2(int,operator>)
00270 #undef T2
00271 #undef T1
00272 #undef Ai
00273 #undef R
00274 #undef F
00275 
00276   friend ADvari& ADf1(double f, double g, double h, const ADvari &x);
00277   friend ADvari& ADf2(double f, double gx, double gy, double hxx,
00278       double hxy, double hyy, const ADvari &x, const ADvari &y);
00279   friend ADvari& ADfn(double f, int n, const ADvar *x, const double *g, const double *h);
00280   };
00281 
00282  inline void* Derp::operator new(size_t len) { return ADvari::adc.Memalloc(len); }
00283 
00284 
00285  class
00286 ADvar1: public ADvari { // simplest unary ops
00287  public:
00288   Derp d;
00289   ADvar1(Advari_Opclass oc, double val1, const double *a1, const ADvari *c1):
00290     ADvari(oc,val1), d(a1,this,c1) {}
00291 #ifdef RAD_AUTO_AD_Const
00292   ADvar1(const IndepADvar *, const IndepADvar &);
00293   ADvar1(const IndepADvar *, const ADvari &);
00294 #endif
00295   };
00296 
00297  class
00298 ConstADvari: public ADvari {
00299  private:
00300   ConstADvari *prevcad;
00301   ConstADvari() {}; // prevent construction without value (?)
00302   static ConstADvari *lastcad;
00303  public:
00304   static CADcontext cadc;
00305   inline void *operator new(size_t len) { return ConstADvari::cadc.Memalloc(len); }
00306   inline ConstADvari(double t): ADvari(Hv_copy, t) { prevcad = lastcad; lastcad = this; }
00307   static void aval_reset(void);
00308   };
00309 
00310  class
00311 IndepADvar
00312 {
00313  private:
00314   inline IndepADvar& operator=(const IndepADvar &x) {
00315     /* private to prevent assignment */
00316 #ifdef RAD_AUTO_AD_Const
00317     if (cv)
00318       cv->padv = 0;
00319     cv = new ADvar1(this,x);
00320     return *this;
00321 #else
00322 #ifdef RAD_EQ_ALIAS
00323     cv = x.cv;
00324     return *this;
00325 #else
00326     return ADvar_operatoreq(this,*x.cv);
00327 #endif
00328 #endif /* RAD_AUTO_AD_Const */
00329     }
00330  protected:
00331   static void AD_Const(const IndepADvar&);
00332   ADvari *cv;
00333  public:
00334   typedef double value_type;
00335   friend class ADvar;
00336   friend class ADvar1;
00337   friend class ADvarn;
00338   friend class ADcontext;
00339   IndepADvar(double);
00340   IndepADvar(int);
00341   IndepADvar(long);
00342   IndepADvar& operator=(double);
00343 #ifdef RAD_AUTO_AD_Const
00344   inline IndepADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1(this, x) : 0; };
00345   inline IndepADvar() { cv = 0; }
00346   inline ~IndepADvar() {
00347       if (cv)
00348         cv->padv = 0;
00349     }
00350 #else
00351   inline IndepADvar() {
00352 #ifndef RAD_EQ_ALIAS
00353     cv = 0;
00354 #endif
00355     }
00356   inline ~IndepADvar() {}
00357   friend IndepADvar& ADvar_operatoreq(IndepADvar*, const ADvari&);
00358 #endif
00359 
00360   friend void AD_Const(const IndepADvar&);
00361 
00362   inline operator ADvari&() { return *cv; }
00363   inline operator ADvari&() const { return *(ADvari*)cv; }
00364 
00365   inline double val() const { return cv->Val; }
00366   inline double adj() const { return cv->aval; }
00367   static inline void Gradcomp() { ADcontext::Gradcomp(); }
00368   static inline void Hvprod(int n, ADvar **vp, double *v, double *hv)
00369         { ADcontext::Hvprod(n, vp, v, hv); }
00370   static inline void aval_reset() { ConstADvari::aval_reset(); }
00371   static inline void Weighted_Gradcomp(int n, ADvar **v, double *w)
00372         { ADcontext::Weighted_Gradcomp(n, v, w); }
00373 
00374 
00375 #define Ai const ADvari&
00376 #define AI const IndepADvar&
00377 #define T2(r,f) \
00378  r f(AI,AI);\
00379  r f(Ai,AI);\
00380  r f(AI,Ai);\
00381  r f(double,AI);\
00382  r f(AI,double);
00383 #define T1(f) friend ADvari& f(AI);
00384 
00385 #define F friend ADvari&
00386 T2(F, operator+)
00387 T2(F, operator-)
00388 T2(F, operator*)
00389 T2(F, operator/)
00390 T2(F, atan2)
00391 T2(F, max)
00392 T2(F, min)
00393 T2(F, pow)
00394 #undef F
00395 #define F friend int
00396 T2(F, operator<)
00397 T2(F, operator<=)
00398 T2(F, operator==)
00399 T2(F, operator!=)
00400 T2(F, operator>=)
00401 T2(F, operator>)
00402 
00403 T1(operator+)
00404 T1(operator-)
00405 T1(abs)
00406 T1(acos)
00407 T1(acosh)
00408 T1(asin)
00409 T1(asinh)
00410 T1(atan)
00411 T1(atanh)
00412 T1(cos)
00413 T1(cosh)
00414 T1(exp)
00415 T1(log)
00416 T1(log10)
00417 T1(sin)
00418 T1(sinh)
00419 T1(sqrt)
00420 T1(tan)
00421 T1(tanh)
00422 T1(fabs)
00423 T1(copy)
00424 
00425 #undef T1
00426 #undef T2
00427 #undef F
00428 #undef Ai
00429 #undef AI
00430 
00431   };
00432 
00433  class
00434 ADvar: public IndepADvar {    // an "active" variable
00435   void ADvar_ctr(double d);
00436  public:
00437   inline ADvar() { /* cv = 0; */ }
00438   inline ADvar(double d) { ADvar_ctr(d); }
00439   inline ADvar(int i) { ADvar_ctr((double)i); }
00440   inline ADvar(long i)  { ADvar_ctr((double)i); }
00441   inline ~ADvar() {}
00442 #ifdef RAD_AUTO_AD_Const
00443   friend class ADvar1;
00444   inline ADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1(this, x) : 0; }
00445   inline ADvar(ADvari &x) { cv = &x; x.padv = this; }
00446   inline ADvar& operator=(const IndepADvar &x) {
00447     if (cv)
00448       cv->padv = 0;
00449     cv = new ADvar1(this,x);
00450     return *this;
00451     }
00452   inline ADvar& operator=(const ADvari &x) {
00453     if (cv)
00454       cv->padv = 0;
00455     cv = new ADvar1(this, x);
00456     return *this;
00457     }
00458 #else
00459   friend ADvar& ADvar_operatoreq(ADvar*, const ADvari&);
00460 #ifdef RAD_EQ_ALIAS
00461   /* allow aliasing v and w after "v = w;" */
00462   inline ADvar(const IndepADvar &x) { cv = x.cv; }
00463   inline ADvar(const ADvari &x) { cv = (ADvari*)&x; }
00464   inline ADvar& operator=(const ADvari &x) { cv = (ADvari*)&x;   return *this; }
00465   inline ADvar& operator=(const IndepADvar &x)  { cv = (ADvari*)x.cv; return *this; }
00466 #else
00467   ADvar(const IndepADvar &x) { cv = x.cv ?
00468     new ADvar1(Hv_copy, x.cv->Val, &CADcontext::One, x.cv) : 0; }
00469   ADvar(const ADvari &x) { cv = new ADvar1(Hv_copy, x.Val, &CADcontext::One, &x); }
00470   inline ADvar& operator=(const ADvari &x) { return ADvar_operatoreq(this,x); }
00471   inline ADvar& operator=(const IndepADvar &x)    { return ADvar_operatoreq(this,*x.cv); }
00472 #endif /* RAD_EQ_ALIAS */
00473 #endif /* RAD_AUTO_AD_Const */
00474   ADvar& operator=(double);
00475   ADvar& operator+=(const ADvari&);
00476   ADvar& operator+=(double);
00477   ADvar& operator-=(const ADvari&);
00478   ADvar& operator-=(double);
00479   ADvar& operator*=(const ADvari&);
00480   ADvar& operator*=(double);
00481   ADvar& operator/=(const ADvari&);
00482   ADvar& operator/=(double);
00483   inline static bool get_fpval_implies_const(void)
00484     { return ConstADvari::cadc.fpval_implies_const; }
00485   inline static void set_fpval_implies_const(bool newval)
00486     { ConstADvari::cadc.fpval_implies_const = newval; }
00487   inline static bool setget_fpval_implies_const(bool newval) {
00488     bool oldval = ConstADvari::cadc.fpval_implies_const;
00489     ConstADvari::cadc.fpval_implies_const = newval;
00490     return oldval;
00491     }
00492   static inline void Gradcomp() { ADcontext::Gradcomp(); }
00493   static inline void Hvprod(int n, ADvar **vp, double *v, double *hv)
00494         { ADcontext::Hvprod(n, vp, v, hv); }
00495   static inline void aval_reset() { ConstADvari::aval_reset(); }
00496   static inline void Weighted_Gradcomp(int n, ADvar **v, double *w)
00497         { ADcontext::Weighted_Gradcomp(n, v, w); }
00498   };
00499 
00500  inline void AD_Const(const IndepADvar&v) { IndepADvar::AD_Const(v); }
00501 
00502  class
00503 ConstADvar: public ADvar {
00504  private: // disable op=
00505   ConstADvar& operator+=(const ADvari&);
00506   ConstADvar& operator+=(double);
00507   ConstADvar& operator-=(const ADvari&);
00508   ConstADvar& operator-=(double);
00509   ConstADvar& operator*=(const ADvari&);
00510   ConstADvar& operator*=(double);
00511   ConstADvar& operator/=(const ADvari&);
00512   ConstADvar& operator/=(double);
00513   void ConstADvar_ctr(double);
00514  public:
00515   inline ConstADvar(double d) { ConstADvar_ctr(d); }
00516   inline ConstADvar(int i)  { ConstADvar_ctr((double)i); }
00517   inline ConstADvar(long i) { ConstADvar_ctr((double)i); }
00518   ConstADvar(const ADvari &x);
00519 #ifdef RAD_AUTO_AD_Const
00520   ConstADvar(const IndepADvar &x) { cv = new ADvar1(this,x); }
00521 #endif
00522   inline ~ConstADvar(){}
00523 #ifdef RAD_NO_CONST_UPDATE
00524  private:
00525 #endif
00526   ConstADvar();
00527   inline ConstADvar& operator=(double d) { cv->Val = d; return *this; }
00528   inline ConstADvar& operator=(const IndepADvar& d) { cv->Val = d.val(); return *this; }
00529  };
00530 
00531  class
00532 ADvar1s: public ADvar1 { // unary ops with partials
00533  public:
00534   double pL;  // deriv of op w.r.t. left operand L
00535   ADvar1s(double val1, double d1, const ADvari *c1):
00536     ADvar1(Hv_timesL,val1,&pL,c1), pL(d1) {}
00537   };
00538 
00539  class
00540 ADvar1g: public ADvar1 { // unary ops with partials
00541  public:
00542   double pL;  // deriv of op w.r.t. left operand L
00543   double pL2; // partial of op w.r.t. L,L
00544   ADvar1g(double val1, double d1, double d2, const ADvari *c1):
00545     ADvar1(Hv_unary,val1,&pL,c1), pL(d1), pL2(d2) {}
00546   };
00547 
00548  class
00549 ADvar2: public ADvari { // basic binary ops
00550  public:
00551   Derp dL, dR;
00552   ADvar2(Advari_Opclass oc, double val1, const ADvari *Lcv, const double *Lc,
00553       const ADvari *Rcv, const double *Rc): ADvari(oc,val1) {
00554     dR.next = Derp::LastDerp;
00555     dL.next = &dR;
00556     Derp::LastDerp = &dL;
00557     dL.a = Lc;
00558     dL.c = (ADvari*)Lcv;
00559     dR.a = Rc;
00560     dR.c = (ADvari*)Rcv;
00561     dL.b = dR.b = this;
00562     }
00563   };
00564 
00565  class
00566 ADvar2q: public ADvar2 { // binary ops with partials
00567  public:
00568   double pL;  // deriv of op w.r.t. left operand L
00569   double pR;  // deriv of op w.r.t. right operand R
00570   double pLR; // second partial w.r.t. L,R
00571   double pR2; // second partial w.r.t. R,R
00572   ADvar2q(double val1, double Lp, double Rp, double LR, double R2,
00573     const ADvari *Lcv, const ADvari *Rcv);
00574   };
00575 
00576  class
00577 ADvar2g: public ADvar2 { // general binary ops with partials
00578  public:
00579   double pL;  // deriv of op w.r.t. left operand L
00580   double pR;  // deriv of op w.r.t. right operand R
00581   double pL2; // second partial w.r.t. L,L
00582   double pLR; // second partial w.r.t. L,R
00583   double pR2; // second partial w.r.t. R,R
00584   ADvar2g(double val1, double Lp, double Rp, double L2, double LR, double R2,
00585     const ADvari *Lcv, const ADvari *Rcv);
00586   };
00587 
00588  class
00589 ADvarn: public ADvari { // n-ary ops with partials g and 2nd partials h (lower triangle, rowwise)
00590  public:
00591   int n;
00592   double *G, *H;
00593   Derp *D;
00594   ADvarn(double val1, int n1, const ADvar *x, const double *g, const double *h);
00595   };
00596 
00597 inline ADvari &operator+(ADvari &T) { return T; }
00598 inline ADvari &operator+(const ADvari &T) { return (ADvari&) T; }
00599 
00600 inline int operator<(const ADvari &L, const ADvari &R) { return L.Val < R.Val; }
00601 inline int operator<(const ADvari &L, double R) { return L.Val < R; }
00602 inline int operator<(double L, const ADvari &R) { return L < R.Val; }
00603 
00604 inline int operator<=(const ADvari &L, const ADvari &R) { return L.Val <= R.Val; }
00605 inline int operator<=(const ADvari &L, double R) { return L.Val <= R; }
00606 inline int operator<=(double L, const ADvari &R) { return L <= R.Val; }
00607 
00608 inline int operator==(const ADvari &L, const ADvari &R) { return L.Val == R.Val; }
00609 inline int operator==(const ADvari &L, double R) { return L.Val == R; }
00610 inline int operator==(double L, const ADvari &R) { return L == R.Val; }
00611 
00612 inline int operator!=(const ADvari &L, const ADvari &R) { return L.Val != R.Val; }
00613 inline int operator!=(const ADvari &L, double R) { return L.Val != R; }
00614 inline int operator!=(double L, const ADvari &R) { return L != R.Val; }
00615 
00616 inline int operator>=(const ADvari &L, const ADvari &R) { return L.Val >= R.Val; }
00617 inline int operator>=(const ADvari &L, double R) { return L.Val >= R; }
00618 inline int operator>=(double L, const ADvari &R) { return L >= R.Val; }
00619 
00620 inline int operator>(const ADvari &L, const ADvari &R) { return L.Val > R.Val; }
00621 inline int operator>(const ADvari &L, double R) { return L.Val > R; }
00622 inline int operator>(double L, const ADvari &R) { return L > R.Val; }
00623 
00624 inline ADvari& copy(const IndepADvar &x)
00625 { return *(new ADvar1(Hv_copy, x.cv->Val, &CADcontext::One, x.cv)); }
00626 
00627 inline ADvari& copy(const ADvari &x)
00628 { return *(new ADvar1(Hv_copy, x.Val, &CADcontext::One, &x)); }
00629 
00630 inline ADvari& abs(const ADvari &x)
00631 { return fabs(x); }
00632 
00633 #define A (ADvari*)
00634 #define T inline
00635 #define F ADvari&
00636 #define Ai const ADvari&
00637 #define AI const IndepADvar&
00638 #define D double
00639 #define T2(r,f) \
00640  T r f(Ai L, AI R) { return f(L, *A R.cv); }\
00641  T r f(AI L, Ai R) { return f(*A L.cv, R); }\
00642  T r f(AI L, AI R) { return f(*A L.cv, *A R.cv); }\
00643  T r f(AI L, D R) { return f(*A L.cv, R); }\
00644  T r f(D L, AI R) { return f(L, *A R.cv); }
00645 
00646 T2(F, operator+)
00647 T2(F, operator-)
00648 T2(F, operator*)
00649 T2(F, operator/)
00650 T2(F, atan2)
00651 T2(F, pow)
00652 T2(F, max)
00653 T2(F, min)
00654 T2(int, operator<)
00655 T2(int, operator<=)
00656 T2(int, operator==)
00657 T2(int, operator!=)
00658 T2(int, operator>=)
00659 T2(int, operator>)
00660 
00661 #undef T2
00662 #undef D
00663 
00664 #define T1(f)\
00665  T F f(AI x) { return f(*A x.cv); }
00666 
00667 T1(operator+)
00668 T1(operator-)
00669 T1(abs)
00670 T1(acos)
00671 T1(acosh)
00672 T1(asin)
00673 T1(asinh)
00674 T1(atan)
00675 T1(atanh)
00676 T1(cos)
00677 T1(cosh)
00678 T1(exp)
00679 T1(log)
00680 T1(log10)
00681 T1(sin)
00682 T1(sinh)
00683 T1(sqrt)
00684 T1(tan)
00685 T1(tanh)
00686 T1(fabs)
00687 
00688 #undef T1
00689 #undef AI
00690 #undef Ai
00691 #undef F
00692 #undef T
00693 #undef A
00694 
00695 #ifndef SACADO_NO_NAMESPACE
00696 } // namespace Rad2d
00697 } // namespace Sacado
00698 #endif // SACADO_NAMESPACE
00699 #endif // SACADO_RAD2_H

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