CppAD: A C++ Algorithmic Differentiation Package  20130102
atan_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_ATAN_OP_INCLUDED
00003 # define CPPAD_ATAN_OP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 
00017 CPPAD_BEGIN_NAMESPACE
00018 /*!
00019 \defgroup atan_op_hpp atan_op.hpp
00020 \{
00021 \file atan_op.hpp
00022 Forward and reverse mode calculations for z = atan(x).
00023 */
00024 
00025 
00026 /*!
00027 Forward mode Taylor coefficient for result of op = AtanOp.
00028 
00029 The C++ source code corresponding to this operation is
00030 \verbatim
00031      z = atan(x)
00032 \endverbatim
00033 The auxillary result is
00034 \verbatim
00035      y = 1 + x * x
00036 \endverbatim
00037 The value of y, and its derivatives, are computed along with the value
00038 and derivatives of z.
00039 
00040 \copydetails forward_unary2_op
00041 */
00042 template <class Base>
00043 inline void forward_atan_op(
00044      size_t j           ,
00045      size_t i_z         ,
00046      size_t i_x         ,
00047      size_t nc_taylor   , 
00048      Base*  taylor      )
00049 {    
00050      // check assumptions
00051      CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );
00052      CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );
00053      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00054      CPPAD_ASSERT_UNKNOWN( j < nc_taylor );
00055 
00056      // Taylor coefficients corresponding to argument and result
00057      Base* x = taylor + i_x * nc_taylor;
00058      Base* z = taylor + i_z * nc_taylor;
00059      Base* b = z      -       nc_taylor;  // called y in documentation
00060 
00061      size_t k;
00062      if( j == 0 )
00063      {    z[j] = atan( x[0] );
00064           b[j] = Base(1) + x[0] * x[0];
00065      }
00066      else
00067      {
00068           b[j] = Base(2) * x[0] * x[j];
00069           z[j] = Base(0);
00070           for(k = 1; k < j; k++)
00071           {    b[j] += x[k] * x[j-k];
00072                z[j] -= Base(k) * z[k] * b[j-k];
00073           }
00074           z[j] /= Base(j);
00075           z[j] += x[j];
00076           z[j] /= b[0];
00077      }
00078 }
00079 
00080 /*!
00081 Zero order forward mode Taylor coefficient for result of op = AtanOp.
00082 
00083 The C++ source code corresponding to this operation is
00084 \verbatim
00085      z = atan(x)
00086 \endverbatim
00087 The auxillary result is
00088 \verbatim
00089      y = 1 + x * x
00090 \endverbatim
00091 The value of y is computed along with the value of z.
00092 
00093 \copydetails forward_unary2_op_0
00094 */
00095 template <class Base>
00096 inline void forward_atan_op_0(
00097      size_t i_z         ,
00098      size_t i_x         ,
00099      size_t nc_taylor   , 
00100      Base*  taylor      )
00101 {
00102      // check assumptions
00103      CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );
00104      CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );
00105      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00106      CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor );
00107 
00108      // Taylor coefficients corresponding to argument and result
00109      Base* x = taylor + i_x * nc_taylor;
00110      Base* z = taylor + i_z * nc_taylor;
00111      Base* b = z      -       nc_taylor; // called y in documentation
00112 
00113      z[0] = atan( x[0] );
00114      b[0] = Base(1) + x[0] * x[0];
00115 }
00116 /*!
00117 Reverse mode partial derivatives for result of op = AtanOp.
00118 
00119 The C++ source code corresponding to this operation is
00120 \verbatim
00121      z = atan(x)
00122 \endverbatim
00123 The auxillary result is
00124 \verbatim
00125      y = 1 + x * x
00126 \endverbatim
00127 The value of y is computed along with the value of z.
00128 
00129 \copydetails reverse_unary2_op
00130 */
00131 
00132 template <class Base>
00133 inline void reverse_atan_op(
00134      size_t      d            ,
00135      size_t      i_z          ,
00136      size_t      i_x          ,
00137      size_t      nc_taylor    , 
00138      const Base* taylor       ,
00139      size_t      nc_partial   ,
00140      Base*       partial      )
00141 {
00142      // check assumptions
00143      CPPAD_ASSERT_UNKNOWN( NumArg(AtanOp) == 1 );
00144      CPPAD_ASSERT_UNKNOWN( NumRes(AtanOp) == 2 );
00145      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00146      CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
00147      CPPAD_ASSERT_UNKNOWN( d < nc_partial );
00148 
00149      // Taylor coefficients and partials corresponding to argument
00150      const Base* x  = taylor  + i_x * nc_taylor;
00151      Base* px       = partial + i_x * nc_partial;
00152 
00153      // Taylor coefficients and partials corresponding to first result
00154      const Base* z  = taylor  + i_z * nc_taylor;
00155      Base* pz       = partial + i_z * nc_partial;
00156 
00157      // Taylor coefficients and partials corresponding to auxillary result
00158      const Base* b  = z  - nc_taylor; // called y in documentation
00159      Base* pb       = pz - nc_partial;
00160 
00161      // number of indices to access
00162      size_t j = d;
00163      size_t k;
00164      while(j)
00165      {    // scale partials w.r.t z[j] and b[j]
00166           pz[j] /= b[0];
00167           pb[j] *= Base(2);
00168 
00169           pb[0] -= pz[j] * z[j]; 
00170           px[j] += pz[j] + pb[j] * x[0];
00171           px[0] += pb[j] * x[j];
00172 
00173           // more scaling of partials w.r.t z[j]
00174           pz[j] /= Base(j);
00175 
00176           for(k = 1; k < j; k++)
00177           {    pb[j-k] -= pz[j] * Base(k) * z[k];
00178                pz[k]   -= pz[j] * Base(k) * b[j-k];
00179                px[k]   += pb[j] * x[j-k];
00180           }
00181           --j;
00182      }
00183      px[0] += pz[0] / b[0] + pb[0] * Base(2) * x[0];
00184 }
00185 
00186 /*! \} */
00187 CPPAD_END_NAMESPACE
00188 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines