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