CppAD: A C++ Algorithmic Differentiation Package
20130102
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_COS_OP_INCLUDED 00003 # define CPPAD_COS_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 cos_op_hpp cos_op.hpp 00020 \{ 00021 \file cos_op.hpp 00022 Forward and reverse mode calculations for z = cos(x). 00023 */ 00024 00025 00026 /*! 00027 Compute forward mode Taylor coefficient for result of op = CosOp. 00028 00029 The C++ source code corresponding to this operation is 00030 \verbatim 00031 z = cos(x) 00032 \endverbatim 00033 The auxillary result is 00034 \verbatim 00035 y = sin(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_cos_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(CosOp) == 1 ); 00052 CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 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* c = taylor + i_z * nc_taylor; 00059 Base* s = c - nc_taylor; 00060 00061 00062 // rest of this routine is identical for the following cases: 00063 // forward_sin_op, forward_cos_op, forward_sinh_op, forward_cosh_op. 00064 size_t k; 00065 if( j == 0 ) 00066 { s[j] = sin( x[0] ); 00067 c[j] = cos( x[0] ); 00068 } 00069 else 00070 { 00071 s[j] = Base(0); 00072 c[j] = Base(0); 00073 for(k = 1; k <= j; k++) 00074 { s[j] += Base(k) * x[k] * c[j-k]; 00075 c[j] -= Base(k) * x[k] * s[j-k]; 00076 } 00077 s[j] /= Base(j); 00078 c[j] /= Base(j); 00079 } 00080 } 00081 00082 /*! 00083 Compute zero order forward mode Taylor coefficient for result of op = CosOp. 00084 00085 The C++ source code corresponding to this operation is 00086 \verbatim 00087 z = cos(x) 00088 \endverbatim 00089 The auxillary result is 00090 \verbatim 00091 y = sin(x) 00092 \endverbatim 00093 The value of y is computed along with the value of z. 00094 00095 \copydetails forward_unary2_op_0 00096 */ 00097 template <class Base> 00098 inline void forward_cos_op_0( 00099 size_t i_z , 00100 size_t i_x , 00101 size_t nc_taylor , 00102 Base* taylor ) 00103 { 00104 // check assumptions 00105 CPPAD_ASSERT_UNKNOWN( NumArg(CosOp) == 1 ); 00106 CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 2 ); 00107 CPPAD_ASSERT_UNKNOWN( i_x + 1 < i_z ); 00108 CPPAD_ASSERT_UNKNOWN( 0 < nc_taylor ); 00109 00110 // Taylor coefficients corresponding to argument and result 00111 Base* x = taylor + i_x * nc_taylor; 00112 Base* c = taylor + i_z * nc_taylor; // called z in documentation 00113 Base* s = c - nc_taylor; // called y in documentation 00114 00115 c[0] = cos( x[0] ); 00116 s[0] = sin( x[0] ); 00117 } 00118 /*! 00119 Compute reverse mode partial derivatives for result of op = CosOp. 00120 00121 The C++ source code corresponding to this operation is 00122 \verbatim 00123 z = cos(x) 00124 \endverbatim 00125 The auxillary result is 00126 \verbatim 00127 y = sin(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_cos_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(CosOp) == 1 ); 00146 CPPAD_ASSERT_UNKNOWN( NumRes(CosOp) == 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* c = taylor + i_z * nc_taylor; // called z in doc 00157 Base* pc = partial + i_z * nc_partial; 00158 00159 // Taylor coefficients and partials corresponding to auxillary result 00160 const Base* s = c - nc_taylor; // called y in documentation 00161 Base* ps = pc - nc_partial; 00162 00163 00164 // rest of this routine is identical for the following cases: 00165 // reverse_sin_op, reverse_cos_op, reverse_sinh_op, reverse_cosh_op. 00166 size_t j = d; 00167 size_t k; 00168 while(j) 00169 { 00170 ps[j] /= Base(j); 00171 pc[j] /= Base(j); 00172 for(k = 1; k <= j; k++) 00173 { 00174 px[k] += ps[j] * Base(k) * c[j-k]; 00175 px[k] -= pc[j] * Base(k) * s[j-k]; 00176 00177 ps[j-k] -= pc[j] * Base(k) * x[k]; 00178 pc[j-k] += ps[j] * Base(k) * x[k]; 00179 00180 } 00181 --j; 00182 } 00183 px[0] += ps[0] * c[0]; 00184 px[0] -= pc[0] * s[0]; 00185 } 00186 00187 /*! \} */ 00188 CPPAD_END_NAMESPACE 00189 # endif