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