Sacado Package Browser (Single Doxygen Collection) Version of the Day
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(int);
00112   static inline void Gradcomp() { Gradcomp(1); }
00113   static void Hvprod(int, ADvar**, double*, double*);
00114   static void Weighted_Gradcomp(int, ADvar**, double*);
00115   inline void ADvari_record(ADvari *x) {
00116     if (Ainext >= Ailimit)
00117       new_ADvari_block();
00118     *Ainext++ = x;
00119     }
00120   };
00121 
00122 inline void *ADcontext::Memalloc(size_t len) {
00123     if (Mleft >= len)
00124       return Mbase + (Mleft -= len);
00125     return new_ADmemblock(len);
00126     }
00127 
00128  class
00129 CADcontext: public ADcontext {
00130  protected:
00131   bool fpval_implies_const;
00132  public:
00133   friend class ADvar;
00134   CADcontext(): ADcontext() { fpval_implies_const = false; }
00135   static const double One, negOne;
00136   };
00137 
00138  class
00139 Derp {    // one derivative-propagation operation
00140  public:
00141   friend class ADvarn;
00142   static Derp *LastDerp;
00143   Derp *next;
00144   const double *a;
00145   const ADvari *b;
00146   mutable ADvari *c;
00147   void *operator new(size_t);
00148   void operator delete(void*) {} /*Should never be called.*/
00149   inline Derp(){};
00150   Derp(const ADvari *);
00151   Derp(const double *, const ADvari *);
00152   Derp(const double *, const ADvari *, const ADvari *);
00153   /* c->aval += a * b->aval; */
00154   };
00155 
00156 inline Derp::Derp(const ADvari *c1): c((ADvari*)c1) {
00157     next = LastDerp;
00158     LastDerp = this;
00159     }
00160 
00161 inline Derp::Derp(const double *a1, const ADvari *c1):
00162     a(a1), c((ADvari*)c1) {
00163     next = LastDerp;
00164     LastDerp = this;
00165     }
00166 
00167 inline Derp::Derp(const double *a1, const ADvari *b1, const ADvari *c1):
00168     a(a1), b(b1), c((ADvari*)c1) {
00169     next = LastDerp;
00170     LastDerp = this;
00171     }
00172 
00173  enum Advari_Opclass {
00174   Hv_const,
00175   Hv_copy,
00176   Hv_binary,
00177   Hv_unary,
00178   Hv_negate,
00179   Hv_plusLR,
00180   Hv_minusLR,
00181   Hv_timesL,
00182   Hv_timesLR,
00183   Hv_quotLR,
00184   Hv_nary
00185   };
00186 
00187  extern ADvari& ADf1(double f, double g, double h, const ADvari &x);
00188  extern ADvari& ADf2(double f, double gx, double gy, double hxx,
00189       double hxy, double hyy, const ADvari &x, const ADvari &y);
00190  extern ADvari& ADfn(double f, int n, const ADvar *x, const double *g, const double *h);
00191 
00192  class
00193 ADvari {  // implementation of an ADvar
00194  public:
00195   static ADcontext adc;
00196   Advari_Opclass opclass;
00197   double Val;   // result of this operation
00198   mutable double aval;  // adjoint -- partial of final result w.r.t. this Val
00199   mutable double dO;  // deriv of op w.r.t. t in x + t*p
00200   mutable double aO;  // adjoint (in Hv computation) of op
00201   mutable double adO; // adjoint (in Hv computation) of dO
00202   void *operator new(size_t len) { return ADvari::adc.Memalloc(len); }
00203   void operator delete(void*) {} /*Should never be called.*/
00204   inline ADvari(Advari_Opclass oc, double t):
00205     opclass(oc), Val(t), aval(0.), dO(0.)
00206     { if (oc != Hv_const) ADvari::adc.ADvari_record(this); }
00207   inline ADvari(Advari_Opclass oc, double t, double ta):
00208     opclass(oc), Val(t), aval(ta), dO(0.)
00209     { if (oc != Hv_const) ADvari::adc.ADvari_record(this); }
00210  private:
00211   inline ADvari(): Val(0.), aval(0.), dO(0.) {} // prevent construction without value (?)
00212  public:
00213   friend class ConstADvari;
00214 #ifdef RAD_AUTO_AD_Const
00215   friend class ADcontext;
00216   friend class ADvar1;
00217   friend class ADvar;
00218   friend class ConstADvar;
00219   friend class IndepADvar;
00220  private:
00221   ADvari *Next;
00222   static ADvari *First_ADvari, **Last_ADvari;
00223  protected:
00224   IndepADvar *padv;
00225  public:
00226   ADvari(const IndepADvar *, double);
00227 #endif
00228 #define F friend
00229 #define R ADvari&
00230 #define Ai const ADvari&
00231 #define T1(r,f) F r f(Ai);
00232 #define T2(r,f) \
00233 F r f(Ai,Ai); \
00234 F r f(double,Ai); \
00235 F r f(Ai,double);
00236   T1(R,operator+)
00237   T2(R,operator+)
00238   T1(R,operator-)
00239   T2(R,operator-)
00240   T2(R,operator*)
00241   T2(R,operator/)
00242   T1(R,abs)
00243   T1(R,acos)
00244   T1(R,acosh)
00245   T1(R,asin)
00246   T1(R,asinh)
00247   T1(R,atan)
00248   T1(R,atanh)
00249   T2(R,atan2)
00250   T2(R,max)
00251   T2(R,min)
00252   T1(R,cos)
00253   T1(R,cosh)
00254   T1(R,exp)
00255   T1(R,log)
00256   T1(R,log10)
00257   T2(R,pow)
00258   T1(R,sin)
00259   T1(R,sinh)
00260   T1(R,sqrt)
00261   T1(R,tan)
00262   T1(R,tanh)
00263   T1(R,fabs)
00264   T1(R,copy)
00265   T2(int,operator<)
00266   T2(int,operator<=)
00267   T2(int,operator==)
00268   T2(int,operator!=)
00269   T2(int,operator>=)
00270   T2(int,operator>)
00271 #undef T2
00272 #undef T1
00273 #undef Ai
00274 #undef R
00275 #undef F
00276 
00277   friend ADvari& ADf1(double f, double g, double h, const ADvari &x);
00278   friend ADvari& ADf2(double f, double gx, double gy, double hxx,
00279       double hxy, double hyy, const ADvari &x, const ADvari &y);
00280   friend ADvari& ADfn(double f, int n, const ADvar *x, const double *g, const double *h);
00281   };
00282 
00283  inline void* Derp::operator new(size_t len) { return ADvari::adc.Memalloc(len); }
00284 
00285 
00286  class
00287 ADvar1: public ADvari { // simplest unary ops
00288  public:
00289   Derp d;
00290   ADvar1(Advari_Opclass oc, double val1, const double *a1, const ADvari *c1):
00291     ADvari(oc,val1), d(a1,this,c1) {}
00292 #ifdef RAD_AUTO_AD_Const
00293   ADvar1(const IndepADvar *, const IndepADvar &);
00294   ADvar1(const IndepADvar *, const ADvari &);
00295 #endif
00296   };
00297 
00298  class
00299 ConstADvari: public ADvari {
00300  private:
00301   ConstADvari *prevcad;
00302   ConstADvari() {}; // prevent construction without value (?)
00303   static ConstADvari *lastcad;
00304  public:
00305   static CADcontext cadc;
00306   inline void *operator new(size_t len) { return ConstADvari::cadc.Memalloc(len); }
00307   inline ConstADvari(double t): ADvari(Hv_copy, t) { prevcad = lastcad; lastcad = this; }
00308   static void aval_reset(void);
00309   };
00310 
00311  class
00312 IndepADvar
00313 {
00314  private:
00315   inline IndepADvar& operator=(const IndepADvar &x) {
00316     /* private to prevent assignment */
00317 #ifdef RAD_AUTO_AD_Const
00318     if (cv)
00319       cv->padv = 0;
00320     cv = new ADvar1(this,x);
00321     return *this;
00322 #else
00323 #ifdef RAD_EQ_ALIAS
00324     cv = x.cv;
00325     return *this;
00326 #else
00327     return ADvar_operatoreq(this,*x.cv);
00328 #endif
00329 #endif /* RAD_AUTO_AD_Const */
00330     }
00331  protected:
00332   static void AD_Const(const IndepADvar&);
00333   ADvari *cv;
00334  public:
00335   typedef double value_type;
00336   friend class ADvar;
00337   friend class ADvar1;
00338   friend class ADvarn;
00339   friend class ADcontext;
00340   IndepADvar(double);
00341   IndepADvar(int);
00342   IndepADvar(long);
00343   IndepADvar& operator=(double);
00344 #ifdef RAD_AUTO_AD_Const
00345   inline IndepADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1(this, x) : 0; };
00346   inline IndepADvar() { cv = 0; }
00347   inline ~IndepADvar() {
00348       if (cv)
00349         cv->padv = 0;
00350     }
00351 #else
00352   inline IndepADvar() {
00353 #ifndef RAD_EQ_ALIAS
00354     cv = 0;
00355 #endif
00356     }
00357   inline ~IndepADvar() {}
00358   friend IndepADvar& ADvar_operatoreq(IndepADvar*, const ADvari&);
00359 #endif
00360 
00361   friend void AD_Const(const IndepADvar&);
00362 
00363   inline operator ADvari&() { return *cv; }
00364   inline operator ADvari&() const { return *(ADvari*)cv; }
00365 
00366   inline double val() const { return cv->Val; }
00367   inline double adj() const { return cv->aval; }
00368   static inline void Gradcomp(int wantgrad)
00369         { ADcontext::Gradcomp(wantgrad); }
00370   static inline void Gradcomp()
00371         { ADcontext::Gradcomp(1); }
00372   static inline void Hvprod(int n, ADvar **vp, double *v, double *hv)
00373         { ADcontext::Hvprod(n, vp, v, hv); }
00374   static inline void aval_reset() { ConstADvari::aval_reset(); }
00375   static inline void Weighted_Gradcomp(int n, ADvar **v, double *w)
00376         { ADcontext::Weighted_Gradcomp(n, v, w); }
00377 
00378 
00379 #define Ai const ADvari&
00380 #define AI const IndepADvar&
00381 #define T2(r,f) \
00382  r f(AI,AI);\
00383  r f(Ai,AI);\
00384  r f(AI,Ai);\
00385  r f(double,AI);\
00386  r f(AI,double);
00387 #define T1(f) friend ADvari& f(AI);
00388 
00389 #define F friend ADvari&
00390 T2(F, operator+)
00391 T2(F, operator-)
00392 T2(F, operator*)
00393 T2(F, operator/)
00394 T2(F, atan2)
00395 T2(F, max)
00396 T2(F, min)
00397 T2(F, pow)
00398 #undef F
00399 #define F friend int
00400 T2(F, operator<)
00401 T2(F, operator<=)
00402 T2(F, operator==)
00403 T2(F, operator!=)
00404 T2(F, operator>=)
00405 T2(F, operator>)
00406 
00407 T1(operator+)
00408 T1(operator-)
00409 T1(abs)
00410 T1(acos)
00411 T1(acosh)
00412 T1(asin)
00413 T1(asinh)
00414 T1(atan)
00415 T1(atanh)
00416 T1(cos)
00417 T1(cosh)
00418 T1(exp)
00419 T1(log)
00420 T1(log10)
00421 T1(sin)
00422 T1(sinh)
00423 T1(sqrt)
00424 T1(tan)
00425 T1(tanh)
00426 T1(fabs)
00427 T1(copy)
00428 
00429 #undef T1
00430 #undef T2
00431 #undef F
00432 #undef Ai
00433 #undef AI
00434 
00435   };
00436 
00437  class
00438 ADvar: public IndepADvar {    // an "active" variable
00439   void ADvar_ctr(double d);
00440  public:
00441   inline ADvar() { /* cv = 0; */ }
00442   inline ADvar(double d) { ADvar_ctr(d); }
00443   inline ADvar(int i) { ADvar_ctr((double)i); }
00444   inline ADvar(long i)  { ADvar_ctr((double)i); }
00445   inline ~ADvar() {}
00446 #ifdef RAD_AUTO_AD_Const
00447   friend class ADvar1;
00448   inline ADvar(const IndepADvar &x) { cv = x.cv ? new ADvar1(this, x) : 0; }
00449   inline ADvar(ADvari &x) { cv = &x; x.padv = this; }
00450   inline ADvar& operator=(const IndepADvar &x) {
00451     if (cv)
00452       cv->padv = 0;
00453     cv = new ADvar1(this,x);
00454     return *this;
00455     }
00456   inline ADvar& operator=(const ADvari &x) {
00457     if (cv)
00458       cv->padv = 0;
00459     cv = new ADvar1(this, x);
00460     return *this;
00461     }
00462 #else
00463   friend ADvar& ADvar_operatoreq(ADvar*, const ADvari&);
00464 #ifdef RAD_EQ_ALIAS
00465   /* allow aliasing v and w after "v = w;" */
00466   inline ADvar(const IndepADvar &x) { cv = x.cv; }
00467   inline ADvar(const ADvari &x) { cv = (ADvari*)&x; }
00468   inline ADvar& operator=(const ADvari &x) { cv = (ADvari*)&x;   return *this; }
00469   inline ADvar& operator=(const IndepADvar &x)  { cv = (ADvari*)x.cv; return *this; }
00470 #else
00471   ADvar(const IndepADvar &x) { cv = x.cv ?
00472     new ADvar1(Hv_copy, x.cv->Val, &CADcontext::One, x.cv) : 0; }
00473   ADvar(const ADvari &x) { cv = new ADvar1(Hv_copy, x.Val, &CADcontext::One, &x); }
00474   inline ADvar& operator=(const ADvari &x) { return ADvar_operatoreq(this,x); }
00475   inline ADvar& operator=(const IndepADvar &x)    { return ADvar_operatoreq(this,*x.cv); }
00476 #endif /* RAD_EQ_ALIAS */
00477 #endif /* RAD_AUTO_AD_Const */
00478   ADvar& operator=(double);
00479   ADvar& operator+=(const ADvari&);
00480   ADvar& operator+=(double);
00481   ADvar& operator-=(const ADvari&);
00482   ADvar& operator-=(double);
00483   ADvar& operator*=(const ADvari&);
00484   ADvar& operator*=(double);
00485   ADvar& operator/=(const ADvari&);
00486   ADvar& operator/=(double);
00487   inline static bool get_fpval_implies_const(void)
00488     { return ConstADvari::cadc.fpval_implies_const; }
00489   inline static void set_fpval_implies_const(bool newval)
00490     { ConstADvari::cadc.fpval_implies_const = newval; }
00491   inline static bool setget_fpval_implies_const(bool newval) {
00492     bool oldval = ConstADvari::cadc.fpval_implies_const;
00493     ConstADvari::cadc.fpval_implies_const = newval;
00494     return oldval;
00495     }
00496   static inline void Gradcomp(int wantgrad)
00497         { ADcontext::Gradcomp(wantgrad); }
00498   static inline void Gradcomp()
00499         { ADcontext::Gradcomp(1); }
00500   static inline void Hvprod(int n, ADvar **vp, double *v, double *hv)
00501         { ADcontext::Hvprod(n, vp, v, hv); }
00502   static inline void aval_reset() { ConstADvari::aval_reset(); }
00503   static inline void Weighted_Gradcomp(int n, ADvar **v, double *w)
00504         { ADcontext::Weighted_Gradcomp(n, v, w); }
00505   };
00506 
00507  inline void AD_Const(const IndepADvar&v) { IndepADvar::AD_Const(v); }
00508 
00509  class
00510 ConstADvar: public ADvar {
00511  private: // disable op=
00512   ConstADvar& operator+=(const ADvari&);
00513   ConstADvar& operator+=(double);
00514   ConstADvar& operator-=(const ADvari&);
00515   ConstADvar& operator-=(double);
00516   ConstADvar& operator*=(const ADvari&);
00517   ConstADvar& operator*=(double);
00518   ConstADvar& operator/=(const ADvari&);
00519   ConstADvar& operator/=(double);
00520   void ConstADvar_ctr(double);
00521  public:
00522   inline ConstADvar(double d) { ConstADvar_ctr(d); }
00523   inline ConstADvar(int i)  { ConstADvar_ctr((double)i); }
00524   inline ConstADvar(long i) { ConstADvar_ctr((double)i); }
00525   ConstADvar(const ADvari &x);
00526 #ifdef RAD_AUTO_AD_Const
00527   ConstADvar(const IndepADvar &x) { cv = new ADvar1(this,x); }
00528 #endif
00529   inline ~ConstADvar(){}
00530 #ifdef RAD_NO_CONST_UPDATE
00531  private:
00532 #endif
00533   ConstADvar();
00534   inline ConstADvar& operator=(double d) { cv->Val = d; return *this; }
00535   inline ConstADvar& operator=(const IndepADvar& d) { cv->Val = d.val(); return *this; }
00536  };
00537 
00538  class
00539 ADvar1s: public ADvar1 { // unary ops with partials
00540  public:
00541   double pL;  // deriv of op w.r.t. left operand L
00542   ADvar1s(double val1, double d1, const ADvari *c1):
00543     ADvar1(Hv_timesL,val1,&pL,c1), pL(d1) {}
00544   };
00545 
00546  class
00547 ADvar1g: public ADvar1 { // unary ops with partials
00548  public:
00549   double pL;  // deriv of op w.r.t. left operand L
00550   double pL2; // partial of op w.r.t. L,L
00551   ADvar1g(double val1, double d1, double d2, const ADvari *c1):
00552     ADvar1(Hv_unary,val1,&pL,c1), pL(d1), pL2(d2) {}
00553   };
00554 
00555  class
00556 ADvar2: public ADvari { // basic binary ops
00557  public:
00558   Derp dL, dR;
00559   ADvar2(Advari_Opclass oc, double val1, const ADvari *Lcv, const double *Lc,
00560       const ADvari *Rcv, const double *Rc): ADvari(oc,val1) {
00561     dR.next = Derp::LastDerp;
00562     dL.next = &dR;
00563     Derp::LastDerp = &dL;
00564     dL.a = Lc;
00565     dL.c = (ADvari*)Lcv;
00566     dR.a = Rc;
00567     dR.c = (ADvari*)Rcv;
00568     dL.b = dR.b = this;
00569     }
00570   };
00571 
00572  class
00573 ADvar2q: public ADvar2 { // binary ops with partials
00574  public:
00575   double pL;  // deriv of op w.r.t. left operand L
00576   double pR;  // deriv of op w.r.t. right operand R
00577   double pLR; // second partial w.r.t. L,R
00578   double pR2; // second partial w.r.t. R,R
00579   ADvar2q(double val1, double Lp, double Rp, double LR, double R2,
00580     const ADvari *Lcv, const ADvari *Rcv);
00581   };
00582 
00583  class
00584 ADvar2g: public ADvar2 { // general binary ops with partials
00585  public:
00586   double pL;  // deriv of op w.r.t. left operand L
00587   double pR;  // deriv of op w.r.t. right operand R
00588   double pL2; // second partial w.r.t. L,L
00589   double pLR; // second partial w.r.t. L,R
00590   double pR2; // second partial w.r.t. R,R
00591   ADvar2g(double val1, double Lp, double Rp, double L2, double LR, double R2,
00592     const ADvari *Lcv, const ADvari *Rcv);
00593   };
00594 
00595  class
00596 ADvarn: public ADvari { // n-ary ops with partials g and 2nd partials h (lower triangle, rowwise)
00597  public:
00598   int n;
00599   double *G, *H;
00600   Derp *D;
00601   ADvarn(double val1, int n1, const ADvar *x, const double *g, const double *h);
00602   };
00603 
00604 inline ADvari &operator+(ADvari &T) { return T; }
00605 inline ADvari &operator+(const ADvari &T) { return (ADvari&) T; }
00606 
00607 inline int operator<(const ADvari &L, const ADvari &R) { return L.Val < R.Val; }
00608 inline int operator<(const ADvari &L, double R) { return L.Val < R; }
00609 inline int operator<(double L, const ADvari &R) { return L < R.Val; }
00610 
00611 inline int operator<=(const ADvari &L, const ADvari &R) { return L.Val <= R.Val; }
00612 inline int operator<=(const ADvari &L, double R) { return L.Val <= R; }
00613 inline int operator<=(double L, const ADvari &R) { return L <= R.Val; }
00614 
00615 inline int operator==(const ADvari &L, const ADvari &R) { return L.Val == R.Val; }
00616 inline int operator==(const ADvari &L, double R) { return L.Val == R; }
00617 inline int operator==(double L, const ADvari &R) { return L == R.Val; }
00618 
00619 inline int operator!=(const ADvari &L, const ADvari &R) { return L.Val != R.Val; }
00620 inline int operator!=(const ADvari &L, double R) { return L.Val != R; }
00621 inline int operator!=(double L, const ADvari &R) { return L != R.Val; }
00622 
00623 inline int operator>=(const ADvari &L, const ADvari &R) { return L.Val >= R.Val; }
00624 inline int operator>=(const ADvari &L, double R) { return L.Val >= R; }
00625 inline int operator>=(double L, const ADvari &R) { return L >= R.Val; }
00626 
00627 inline int operator>(const ADvari &L, const ADvari &R) { return L.Val > R.Val; }
00628 inline int operator>(const ADvari &L, double R) { return L.Val > R; }
00629 inline int operator>(double L, const ADvari &R) { return L > R.Val; }
00630 
00631 inline ADvari& copy(const IndepADvar &x)
00632 { return *(new ADvar1(Hv_copy, x.cv->Val, &CADcontext::One, x.cv)); }
00633 
00634 inline ADvari& copy(const ADvari &x)
00635 { return *(new ADvar1(Hv_copy, x.Val, &CADcontext::One, &x)); }
00636 
00637 inline ADvari& abs(const ADvari &x)
00638 { return fabs(x); }
00639 
00640 #define A (ADvari*)
00641 #define T inline
00642 #define F ADvari&
00643 #define Ai const ADvari&
00644 #define AI const IndepADvar&
00645 #define D double
00646 #define T2(r,f) \
00647  T r f(Ai L, AI R) { return f(L, *A R.cv); }\
00648  T r f(AI L, Ai R) { return f(*A L.cv, R); }\
00649  T r f(AI L, AI R) { return f(*A L.cv, *A R.cv); }\
00650  T r f(AI L, D R) { return f(*A L.cv, R); }\
00651  T r f(D L, AI R) { return f(L, *A R.cv); }
00652 
00653 T2(F, operator+)
00654 T2(F, operator-)
00655 T2(F, operator*)
00656 T2(F, operator/)
00657 T2(F, atan2)
00658 T2(F, pow)
00659 T2(F, max)
00660 T2(F, min)
00661 T2(int, operator<)
00662 T2(int, operator<=)
00663 T2(int, operator==)
00664 T2(int, operator!=)
00665 T2(int, operator>=)
00666 T2(int, operator>)
00667 
00668 #undef T2
00669 #undef D
00670 
00671 #define T1(f)\
00672  T F f(AI x) { return f(*A x.cv); }
00673 
00674 T1(operator+)
00675 T1(operator-)
00676 T1(abs)
00677 T1(acos)
00678 T1(acosh)
00679 T1(asin)
00680 T1(asinh)
00681 T1(atan)
00682 T1(atanh)
00683 T1(cos)
00684 T1(cosh)
00685 T1(exp)
00686 T1(log)
00687 T1(log10)
00688 T1(sin)
00689 T1(sinh)
00690 T1(sqrt)
00691 T1(tan)
00692 T1(tanh)
00693 T1(fabs)
00694 
00695 #undef T1
00696 #undef AI
00697 #undef Ai
00698 #undef F
00699 #undef T
00700 #undef A
00701 
00702 #ifndef SACADO_NO_NAMESPACE
00703 } // namespace Rad2d
00704 } // namespace Sacado
00705 #endif // SACADO_NAMESPACE
00706 #endif // SACADO_RAD2_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines