CppAD: A C++ Algorithmic Differentiation Package 20110419
|
00001 /* $Id$ */ 00002 # ifndef CPPAD_MUL_OP_INCLUDED 00003 # define CPPAD_MUL_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 CPPAD_BEGIN_NAMESPACE 00017 /*! 00018 \file mul_op.hpp 00019 Forward and reverse mode calculations for z = x * y. 00020 */ 00021 00022 // --------------------------- Mulvv ----------------------------------------- 00023 /*! 00024 Compute forward mode Taylor coefficients for result of op = MulvvOp. 00025 00026 The C++ source code corresponding to this operation is 00027 \verbatim 00028 z = x * y 00029 \endverbatim 00030 In the documentation below, 00031 this operations is for the case where both x and y are variables 00032 and the argument \a parameter is not used. 00033 00034 \copydetails forward_binary_op 00035 */ 00036 00037 template <class Base> 00038 inline void forward_mulvv_op( 00039 size_t d , 00040 size_t i_z , 00041 const size_t* arg , 00042 const Base* parameter , 00043 size_t nc_taylor , 00044 Base* taylor ) 00045 { 00046 // check assumptions 00047 CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); 00048 CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); 00049 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00050 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00051 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00052 00053 // Taylor coefficients corresponding to arguments and result 00054 Base* x = taylor + arg[0] * nc_taylor; 00055 Base* y = taylor + arg[1] * nc_taylor; 00056 Base* z = taylor + i_z * nc_taylor; 00057 00058 size_t k; 00059 z[d] = Base(0); 00060 for(k = 0; k <= d; k++) 00061 z[d] += x[d-k] * y[k]; 00062 } 00063 00064 /*! 00065 Compute zero order forward mode Taylor coefficients for result of op = MulvvOp. 00066 00067 The C++ source code corresponding to this operation is 00068 \verbatim 00069 z = x * y 00070 \endverbatim 00071 In the documentation below, 00072 this operations is for the case where both x and y are variables 00073 and the argument \a parameter is not used. 00074 00075 \copydetails forward_binary_op_0 00076 */ 00077 00078 template <class Base> 00079 inline void forward_mulvv_op_0( 00080 size_t i_z , 00081 const size_t* arg , 00082 const Base* parameter , 00083 size_t nc_taylor , 00084 Base* taylor ) 00085 { 00086 // check assumptions 00087 CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); 00088 CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); 00089 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00090 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00091 00092 // Taylor coefficients corresponding to arguments and result 00093 Base* x = taylor + arg[0] * nc_taylor; 00094 Base* y = taylor + arg[1] * nc_taylor; 00095 Base* z = taylor + i_z * nc_taylor; 00096 00097 z[0] = x[0] * y[0]; 00098 } 00099 00100 /*! 00101 Compute reverse mode partial derivatives for result of op = MulvvOp. 00102 00103 The C++ source code corresponding to this operation is 00104 \verbatim 00105 z = x * y 00106 \endverbatim 00107 In the documentation below, 00108 this operations is for the case where both x and y are variables 00109 and the argument \a parameter is not used. 00110 00111 \copydetails reverse_binary_op 00112 */ 00113 00114 template <class Base> 00115 inline void reverse_mulvv_op( 00116 size_t d , 00117 size_t i_z , 00118 const size_t* arg , 00119 const Base* parameter , 00120 size_t nc_taylor , 00121 const Base* taylor , 00122 size_t nc_partial , 00123 Base* partial ) 00124 { 00125 // check assumptions 00126 CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); 00127 CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); 00128 CPPAD_ASSERT_UNKNOWN( arg[0] < i_z ); 00129 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00130 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00131 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00132 00133 // Arguments 00134 const Base* x = taylor + arg[0] * nc_taylor; 00135 const Base* y = taylor + arg[1] * nc_taylor; 00136 00137 // Partial derivatives corresponding to arguments and result 00138 Base* px = partial + arg[0] * nc_partial; 00139 Base* py = partial + arg[1] * nc_partial; 00140 Base* pz = partial + i_z * nc_partial; 00141 00142 00143 // number of indices to access 00144 size_t j = d + 1; 00145 size_t k; 00146 while(j) 00147 { --j; 00148 for(k = 0; k <= j; k++) 00149 { 00150 px[j-k] += pz[j] * y[k]; 00151 py[k] += pz[j] * x[j-k]; 00152 } 00153 } 00154 } 00155 // --------------------------- Mulpv ----------------------------------------- 00156 /*! 00157 Compute forward mode Taylor coefficients for result of op = MulpvOp. 00158 00159 The C++ source code corresponding to this operation is 00160 \verbatim 00161 z = x * y 00162 \endverbatim 00163 In the documentation below, 00164 this operations is for the case where x is a parameter and y is a variable. 00165 00166 \copydetails forward_binary_op 00167 */ 00168 00169 template <class Base> 00170 inline void forward_mulpv_op( 00171 size_t d , 00172 size_t i_z , 00173 const size_t* arg , 00174 const Base* parameter , 00175 size_t nc_taylor , 00176 Base* taylor ) 00177 { 00178 // check assumptions 00179 CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); 00180 CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); 00181 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00182 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00183 00184 // Taylor coefficients corresponding to arguments and result 00185 Base* y = taylor + arg[1] * nc_taylor; 00186 Base* z = taylor + i_z * nc_taylor; 00187 00188 // Paraemter value 00189 Base x = parameter[ arg[0] ]; 00190 00191 z[d] = x * y[d]; 00192 } 00193 /*! 00194 Compute zero order forward mode Taylor coefficient for result of op = MulpvOp. 00195 00196 The C++ source code corresponding to this operation is 00197 \verbatim 00198 z = x * y 00199 \endverbatim 00200 In the documentation below, 00201 this operations is for the case where x is a parameter and y is a variable. 00202 00203 \copydetails forward_binary_op_0 00204 */ 00205 00206 template <class Base> 00207 inline void forward_mulpv_op_0( 00208 size_t i_z , 00209 const size_t* arg , 00210 const Base* parameter , 00211 size_t nc_taylor , 00212 Base* taylor ) 00213 { 00214 // check assumptions 00215 CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 ); 00216 CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 ); 00217 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00218 00219 // Paraemter value 00220 Base x = parameter[ arg[0] ]; 00221 00222 // Taylor coefficients corresponding to arguments and result 00223 Base* y = taylor + arg[1] * nc_taylor; 00224 Base* z = taylor + i_z * nc_taylor; 00225 00226 z[0] = x * y[0]; 00227 } 00228 00229 /*! 00230 Compute reverse mode partial derivative for result of op = MulpvOp. 00231 00232 The C++ source code corresponding to this operation is 00233 \verbatim 00234 z = x * y 00235 \endverbatim 00236 In the documentation below, 00237 this operations is for the case where x is a parameter and y is a variable. 00238 00239 \copydetails reverse_binary_op 00240 */ 00241 00242 template <class Base> 00243 inline void reverse_mulpv_op( 00244 size_t d , 00245 size_t i_z , 00246 const size_t* arg , 00247 const Base* parameter , 00248 size_t nc_taylor , 00249 const Base* taylor , 00250 size_t nc_partial , 00251 Base* partial ) 00252 { 00253 // check assumptions 00254 CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 ); 00255 CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 ); 00256 CPPAD_ASSERT_UNKNOWN( arg[1] < i_z ); 00257 CPPAD_ASSERT_UNKNOWN( d < nc_taylor ); 00258 CPPAD_ASSERT_UNKNOWN( d < nc_partial ); 00259 00260 // Arguments 00261 Base x = parameter[ arg[0] ]; 00262 00263 // Partial derivatives corresponding to arguments and result 00264 Base* py = partial + arg[1] * nc_partial; 00265 Base* pz = partial + i_z * nc_partial; 00266 00267 // number of indices to access 00268 size_t j = d + 1; 00269 while(j) 00270 { --j; 00271 py[j] += pz[j] * x; 00272 } 00273 } 00274 00275 00276 CPPAD_END_NAMESPACE 00277 # endif