CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_TAN_OP_INCLUDED 00003 # define CPPAD_TAN_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 tan_op_hpp tan_op.hpp 00020 \{ 00021 \file tan_op.hpp 00022 Forward and reverse mode calculations for z = tan(x). 00023 */ 00024 00025 00026 /*! 00027 Compute forward mode Taylor coefficient for result of op = TanOp. 00028 00029 The C++ source code corresponding to this operation is 00030 \verbatim 00031 z = tan(x) 00032 \endverbatim 00033 The auxillary result is 00034 \verbatim 00035 y = tan(x)^2 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_tan_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(TanOp) == 1 ); 00052 CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 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* y = z - nc_taylor; 00060 00061 size_t k; 00062 if( j == 0 ) 00063 { z[j] = tan( x[0] ); 00064 y[j] = z[j] * z[j]; 00065 } 00066 else 00067 { Base base_j = static_cast<Base>(j); 00068 00069 z[j] = x[j]; 00070 for(k = 1; k <= j; k++) 00071 z[j] += Base(k) * x[k] * y[j-k] / base_j; 00072 00073 y[j] = z[0] * z[j]; 00074 for(k = 1; k <= j; k++) 00075 y[j] += z[k] * z[j-k]; 00076 } 00077 } 00078 00079 00080 /*! 00081 Compute zero order forward mode Taylor coefficient for result of op = TanOp. 00082 00083 The C++ source code corresponding to this operation is 00084 \verbatim 00085 z = tan(x) 00086 \endverbatim 00087 The auxillary result is 00088 \verbatim 00089 y = cos(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_tan_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(TanOp) == 1 ); 00104 CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 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; // called z in documentation 00111 Base* y = z - nc_taylor; // called y in documentation 00112 00113 z[0] = tan( x[0] ); 00114 y[0] = z[0] * z[0]; 00115 } 00116 00117 /*! 00118 Compute reverse mode partial derivatives for result of op = TanOp. 00119 00120 The C++ source code corresponding to this operation is 00121 \verbatim 00122 z = tan(x) 00123 \endverbatim 00124 The auxillary result is 00125 \verbatim 00126 y = cos(x) 00127 \endverbatim 00128 The value of y is computed along with the value of z. 00129 00130 \copydetails reverse_unary2_op 00131 */ 00132 00133 template <class Base> 00134 inline void reverse_tan_op( 00135 size_t d , 00136 size_t i_z , 00137 size_t i_x , 00138 size_t nc_taylor , 00139 const Base* taylor , 00140 size_t nc_partial , 00141 Base* partial ) 00142 { 00143 // check assumptions 00144 CPPAD_ASSERT_UNKNOWN( NumArg(TanOp) == 1 ); 00145 CPPAD_ASSERT_UNKNOWN( NumRes(TanOp) == 2 ); 00146 CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z ); 00147 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00148 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00149 00150 // Taylor coefficients and partials corresponding to argument 00151 const Base* x = taylor + i_x * nc_taylor; 00152 Base* px = partial + i_x * nc_partial; 00153 00154 // Taylor coefficients and partials corresponding to first result 00155 const Base* z = taylor + i_z * nc_taylor; // called z in doc 00156 Base* pz = partial + i_z * nc_partial; 00157 00158 // Taylor coefficients and partials corresponding to auxillary result 00159 const Base* y = z - nc_taylor; // called y in documentation 00160 Base* py = pz - nc_partial; 00161 00162 size_t j = d; 00163 size_t k; 00164 Base base_two(2); 00165 while(j) 00166 { 00167 px[j] += pz[j]; 00168 pz[j] /= Base(j); 00169 for(k = 1; k <= j; k++) 00170 { px[k] += pz[j] * y[j-k] * Base(k); 00171 py[j-k] += pz[j] * x[k] * Base(k); 00172 } 00173 for(k = 0; k < j; k++) 00174 pz[k] += py[j-1] * z[j-k-1] * base_two; 00175 00176 --j; 00177 } 00178 px[0] += pz[0] * (Base(1) + y[0]); 00179 } 00180 00181 /*! \} */ 00182 CPPAD_END_NAMESPACE 00183 # endif