CppAD: A C++ Algorithmic Differentiation Package 20110419
sinh_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_SINH_OP_INCLUDED
00003 # define CPPAD_SINH_OP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-10 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Common 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 \file sinh_op.hpp
00020 Forward and reverse mode calculations for z = sinh(x).
00021 */
00022 
00023 
00024 /*!
00025 Compute forward mode Taylor coefficient for result of op = SinhOp.
00026 
00027 The C++ source code corresponding to this operation is
00028 \verbatim
00029         z = sinh(x)
00030 \endverbatim
00031 The auxillary result is
00032 \verbatim
00033         y = cosh(x)
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_sinh_op(
00042         size_t j           ,
00043         size_t i_z         ,
00044         size_t i_x         ,
00045         size_t nc_taylor   , 
00046         Base*  taylor      )
00047 {       
00048         // check assumptions
00049         CPPAD_ASSERT_UNKNOWN( NumArg(SinhOp) == 1 );
00050         CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 2 );
00051         CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00052         CPPAD_ASSERT_UNKNOWN( j < nc_taylor );
00053 
00054         // Taylor coefficients corresponding to argument and result
00055         Base* x = taylor + i_x * nc_taylor;
00056         Base* s = taylor + i_z * nc_taylor;
00057         Base* c = s      -       nc_taylor;
00058 
00059 
00060         // rest of this routine is identical for the following cases:
00061         // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op.
00062         size_t k;
00063         if( j == 0 )
00064         {       s[j] = sinh( x[0] );
00065                 c[j] = cosh( x[0] );
00066         }
00067         else
00068         {
00069                 s[j] = Base(0);
00070                 c[j] = Base(0);
00071                 for(k = 1; k <= j; k++)
00072                 {       s[j] += Base(k) * x[k] * c[j-k];
00073                         c[j] += Base(k) * x[k] * s[j-k];
00074                 }
00075                 s[j] /= Base(j);
00076                 c[j] /= Base(j);
00077         }
00078 }
00079 
00080 /*!
00081 Compute zero order forward mode Taylor coefficient for result of op = SinhOp.
00082 
00083 The C++ source code corresponding to this operation is
00084 \verbatim
00085         z = sinh(x)
00086 \endverbatim
00087 The auxillary result is
00088 \verbatim
00089         y = cosh(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_sinh_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(SinhOp) == 1 );
00104         CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 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* s = taylor + i_z * nc_taylor;  // called z in documentation
00111         Base* c = s      -       nc_taylor;  // called y in documentation
00112 
00113         s[0] = sinh( x[0] );
00114         c[0] = cosh( x[0] );
00115 }
00116 /*!
00117 Compute reverse mode partial derivatives for result of op = SinhOp.
00118 
00119 The C++ source code corresponding to this operation is
00120 \verbatim
00121         z = sinh(x)
00122 \endverbatim
00123 The auxillary result is
00124 \verbatim
00125         y = cosh(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_sinh_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(SinhOp) == 1 );
00144         CPPAD_ASSERT_UNKNOWN( NumRes(SinhOp) == 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* s  = taylor  + i_z * nc_taylor; // called z in doc
00155         Base* ps       = partial + i_z * nc_partial;
00156 
00157         // Taylor coefficients and partials corresponding to auxillary result
00158         const Base* c  = s  - nc_taylor; // called y in documentation
00159         Base* pc       = ps - nc_partial;
00160 
00161         // rest of this routine is identical for the following cases:
00162         // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.
00163         size_t j = d;
00164         size_t k;
00165         while(j)
00166         {
00167                 ps[j]   /= Base(j);
00168                 pc[j]   /= Base(j);
00169                 for(k = 1; k <= j; k++)
00170                 {
00171                         px[k]   += ps[j] * Base(k) * c[j-k];
00172                         px[k]   += pc[j] * Base(k) * s[j-k];
00173         
00174                         ps[j-k] += pc[j] * Base(k) * x[k];
00175                         pc[j-k] += ps[j] * Base(k) * x[k];
00176 
00177                 }
00178                 --j;
00179         }
00180         px[0] += ps[0] * c[0];
00181         px[0] += pc[0] * s[0];
00182 }
00183 
00184 CPPAD_END_NAMESPACE
00185 # endif