CppAD: A C++ Algorithmic Differentiation Package  20130918
tan_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_TAN_OP_INCLUDED
00003 # define CPPAD_TAN_OP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00018 /*!
00019 \file tan_op.hpp
00020 Forward and reverse mode calculations for z = tan(x).
00021 */
00022 
00023 
00024 /*!
00025 Compute forward mode Taylor coefficient for result of op = TanOp.
00026 
00027 The C++ source code corresponding to this operation is
00028 \verbatim
00029      z = tan(x)
00030 \endverbatim
00031 The auxillary result is
00032 \verbatim
00033      y = tan(x)^2
00034 \endverbatim
00035 The value of y, and its derivatives, are computed along with the value
00036 and derivatives of z.
00037 
00038 \copydetails forward_unary2_op
00039 */
00040 template <class Base>
00041 inline void forward_tan_op(
00042      size_t p           ,
00043      size_t q           ,
00044      size_t i_z         ,
00045      size_t i_x         ,
00046      size_t nc_taylor   , 
00047      Base*  taylor      )
00048 {    
00049      // check assumptions
00050      CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
00051      CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
00052      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00053      CPPAD_ASSERT_UNKNOWN( q < nc_taylor );
00054      CPPAD_ASSERT_UNKNOWN( p <= q );
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* y = z      -       nc_taylor;
00060 
00061      size_t k;
00062      if( p == 0 )
00063      {    z[0] = tan( x[0] );
00064           y[0] = z[0] * z[0];
00065           p++;
00066      }
00067      for(size_t j = p; j <= q; j++)
00068      {    Base base_j = static_cast<Base>(j);
00069 
00070           z[j] = x[j];
00071           for(k = 1; k <= j; k++)
00072                z[j] += Base(k) * x[k] * y[j-k] / base_j;
00073 
00074           y[j] = z[0] * z[j];
00075           for(k = 1; k <= j; k++)
00076                y[j] += z[k] * z[j-k];
00077      }
00078 }
00079 
00080 
00081 /*!
00082 Compute zero order forward mode Taylor coefficient for result of op = TanOp.
00083 
00084 The C++ source code corresponding to this operation is
00085 \verbatim
00086      z = tan(x)
00087 \endverbatim
00088 The auxillary result is
00089 \verbatim
00090      y = cos(x)
00091 \endverbatim
00092 The value of y is computed along with the value of z.
00093 
00094 \copydetails forward_unary2_op_0
00095 */
00096 template <class Base>
00097 inline void forward_tan_op_0(
00098      size_t i_z         ,
00099      size_t i_x         ,
00100      size_t nc_taylor   , 
00101      Base*  taylor      )
00102 {
00103      // check assumptions
00104      CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
00105      CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
00106      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00107      CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor );
00108 
00109      // Taylor coefficients corresponding to argument and result
00110      Base* x = taylor + i_x * nc_taylor;
00111      Base* z = taylor + i_z * nc_taylor;  // called z in documentation
00112      Base* y = z      -       nc_taylor;  // called y in documentation
00113 
00114      z[0] = tan( x[0] );
00115      y[0] = z[0] * z[0];
00116 }
00117 
00118 /*!
00119 Compute reverse mode partial derivatives for result of op = TanOp.
00120 
00121 The C++ source code corresponding to this operation is
00122 \verbatim
00123      z = tan(x)
00124 \endverbatim
00125 The auxillary result is
00126 \verbatim
00127      y = cos(x)
00128 \endverbatim
00129 The value of y is computed along with the value of z.
00130 
00131 \copydetails reverse_unary2_op
00132 */
00133 
00134 template <class Base>
00135 inline void reverse_tan_op(
00136      size_t      d            ,
00137      size_t      i_z          ,
00138      size_t      i_x          ,
00139      size_t      nc_taylor    , 
00140      const Base* taylor       ,
00141      size_t      nc_partial   ,
00142      Base*       partial      )
00143 {
00144      // check assumptions
00145      CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 );
00146      CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 );
00147      CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00148      CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
00149      CPPAD_ASSERT_UNKNOWN( d < nc_partial );
00150 
00151      // Taylor coefficients and partials corresponding to argument
00152      const Base* x  = taylor  + i_x * nc_taylor;
00153      Base* px       = partial + i_x * nc_partial;
00154 
00155      // Taylor coefficients and partials corresponding to first result
00156      const Base* z  = taylor  + i_z * nc_taylor; // called z in doc
00157      Base* pz       = partial + i_z * nc_partial;
00158 
00159      // Taylor coefficients and partials corresponding to auxillary result
00160      const Base* y  = z  - nc_taylor; // called y in documentation
00161      Base* py       = pz - nc_partial;
00162 
00163      size_t j = d;
00164      size_t k;
00165      Base base_two(2);
00166      while(j)
00167      {
00168           px[j]   += pz[j];
00169           pz[j]   /= Base(j);
00170           for(k = 1; k <= j; k++)
00171           {    px[k]   += pz[j] * y[j-k] * Base(k);
00172                py[j-k] += pz[j] * x[k] * Base(k);
00173           }
00174           for(k = 0; k < j; k++)
00175                pz[k] += py[j-1] * z[j-k-1] * base_two;
00176      
00177           --j;
00178      }
00179      px[0] += pz[0] * (Base(1) + y[0]);
00180 }
00181 
00182 } // END_CPPAD_NAMESPACE
00183 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines