CppAD: A C++ Algorithmic Differentiation Package 20110419
mul_op.hpp
Go to the documentation of this file.
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