CppAD: A C++ Algorithmic Differentiation Package 20110419
cosh_op.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_COSH_OP_INCLUDED
00003 # define CPPAD_COSH_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 cosh_op.hpp
00020 Forward and reverse mode calculations for z = cosh(x).
00021 */
00022 
00023 
00024 /*!
00025 Compute forward mode Taylor coefficient for result of op = CoshOp.
00026 
00027 The C++ source code corresponding to this operation is
00028 \verbatim
00029         z = cosh(x)
00030 \endverbatim
00031 The auxillary result is
00032 \verbatim
00033         y = sinh(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_cosh_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(CoshOp) == 1 );
00050         CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 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* c = taylor + i_z * nc_taylor;
00057         Base* s = c      -       nc_taylor;
00058 
00059         // rest of this routine is identical for the following cases:
00060         // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op.
00061         size_t k;
00062         if( j == 0 )
00063         {       s[j] = sinh( x[0] );
00064                 c[j] = cosh( x[0] );
00065         }
00066         else
00067         {
00068                 s[j] = Base(0);
00069                 c[j] = Base(0);
00070                 for(k = 1; k <= j; k++)
00071                 {       s[j] += Base(k) * x[k] * c[j-k];
00072                         c[j] += Base(k) * x[k] * s[j-k];
00073                 }
00074                 s[j] /= Base(j);
00075                 c[j] /= Base(j);
00076         }
00077 }
00078 
00079 /*!
00080 Compute zero order forward mode Taylor coefficient for result of op = CoshOp.
00081 
00082 The C++ source code corresponding to this operation is
00083 \verbatim
00084         z = cosh(x)
00085 \endverbatim
00086 The auxillary result is
00087 \verbatim
00088         y = sinh(x)
00089 \endverbatim
00090 The value of y is computed along with the value of z.
00091 
00092 \copydetails forward_unary2_op_0
00093 */
00094 template <class Base>
00095 inline void forward_cosh_op_0(
00096         size_t i_z         ,
00097         size_t i_x         ,
00098         size_t nc_taylor   , 
00099         Base*  taylor      )
00100 {
00101         // check assumptions
00102         CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );
00103         CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );
00104         CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00105         CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor );
00106 
00107         // Taylor coefficients corresponding to argument and result
00108         Base* x = taylor + i_x * nc_taylor;
00109         Base* c = taylor + i_z * nc_taylor;  // called z in documentation
00110         Base* s = c      -       nc_taylor;  // called y in documentation
00111 
00112         c[0] = cosh( x[0] );
00113         s[0] = sinh( x[0] );
00114 }
00115 /*!
00116 Compute reverse mode partial derivatives for result of op = CoshOp.
00117 
00118 The C++ source code corresponding to this operation is
00119 \verbatim
00120         z = cosh(x)
00121 \endverbatim
00122 The auxillary result is
00123 \verbatim
00124         y = sinh(x)
00125 \endverbatim
00126 The value of y is computed along with the value of z.
00127 
00128 \copydetails reverse_unary2_op
00129 */
00130 
00131 template <class Base>
00132 inline void reverse_cosh_op(
00133         size_t      d            ,
00134         size_t      i_z          ,
00135         size_t      i_x          ,
00136         size_t      nc_taylor    , 
00137         const Base* taylor       ,
00138         size_t      nc_partial   ,
00139         Base*       partial      )
00140 {
00141         // check assumptions
00142         CPPAD_ASSERT_UNKNOWN( NumArg(CoshOp) == 1 );
00143         CPPAD_ASSERT_UNKNOWN( NumRes(CoshOp) == 2 );
00144         CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z );
00145         CPPAD_ASSERT_UNKNOWN( d < nc_taylor );
00146         CPPAD_ASSERT_UNKNOWN( d < nc_partial );
00147 
00148         // Taylor coefficients and partials corresponding to argument
00149         const Base* x  = taylor  + i_x * nc_taylor;
00150         Base* px       = partial + i_x * nc_partial;
00151 
00152         // Taylor coefficients and partials corresponding to first result
00153         const Base* c  = taylor  + i_z * nc_taylor; // called z in doc
00154         Base* pc       = partial + i_z * nc_partial;
00155 
00156         // Taylor coefficients and partials corresponding to auxillary result
00157         const Base* s  = c  - nc_taylor; // called y in documentation
00158         Base* ps       = pc - nc_partial;
00159 
00160         // rest of this routine is identical for the following cases:
00161         // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op.
00162         size_t j = d;
00163         size_t k;
00164         while(j)
00165         {
00166                 ps[j]   /= Base(j);
00167                 pc[j]   /= Base(j);
00168                 for(k = 1; k <= j; k++)
00169                 {
00170                         px[k]   += ps[j] * Base(k) * c[j-k];
00171                         px[k]   += pc[j] * Base(k) * s[j-k];
00172         
00173                         ps[j-k] += pc[j] * Base(k) * x[k];
00174                         pc[j-k] += ps[j] * Base(k) * x[k];
00175 
00176                 }
00177                 --j;
00178         }
00179         px[0] += ps[0] * c[0];
00180         px[0] += pc[0] * s[0];
00181 }
00182 
00183 CPPAD_END_NAMESPACE
00184 # endif