source: trunk/cppad/local/mul_op.hpp @ 3301

Last change on this file since 3301 was 3301, checked in by bradbell, 6 years ago

merge in multiple forward direcitons from branches/forward_dir

  • Property svn:keywords set to Id
File size: 9.8 KB
Line 
1/* $Id: mul_op.hpp 3301 2014-05-24 05:20:21Z bradbell $ */
2# ifndef CPPAD_MUL_OP_INCLUDED
3# define CPPAD_MUL_OP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16namespace CppAD { // BEGIN_CPPAD_NAMESPACE
17/*!
18\file mul_op.hpp
19Forward and reverse mode calculations for z = x * y.
20*/
21
22// --------------------------- Mulvv -----------------------------------------
23/*!
24Compute forward mode Taylor coefficients for result of op = MulvvOp.
25
26The C++ source code corresponding to this operation is
27\verbatim
28        z = x * y
29\endverbatim
30In the documentation below,
31this operations is for the case where both x and y are variables
32and the argument \a parameter is not used.
33
34\copydetails forward_binary_op
35*/
36
37template <class Base>
38inline void forward_mulvv_op(
39        size_t        p           , 
40        size_t        q           , 
41        size_t        i_z         ,
42        const addr_t* arg         ,
43        const Base*   parameter   ,
44        size_t        cap_order   ,
45        Base*         taylor      )
46{
47        // check assumptions
48        CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );
49        CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );
50        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
51        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
52        CPPAD_ASSERT_UNKNOWN( q < cap_order );
53        CPPAD_ASSERT_UNKNOWN( p <= q );
54
55        // Taylor coefficients corresponding to arguments and result
56        Base* x = taylor + arg[0] * cap_order;
57        Base* y = taylor + arg[1] * cap_order;
58        Base* z = taylor + i_z    * cap_order;
59
60        size_t k;
61        for(size_t d = p; d <= q; d++)
62        {       z[d] = Base(0);
63                for(k = 0; k <= d; k++)
64                        z[d] += x[d-k] * y[k];
65        }
66}
67/*!
68Multiple directions forward mode Taylor coefficients for op = MulvvOp.
69
70The C++ source code corresponding to this operation is
71\verbatim
72        z = x * y
73\endverbatim
74In the documentation below,
75this operations is for the case where both x and y are variables
76and the argument \a parameter is not used.
77
78\copydetails forward_binary_op_dir
79*/
80
81template <class Base>
82inline void forward_mulvv_op_dir(
83        size_t        q           , 
84        size_t        r           , 
85        size_t        i_z         ,
86        const addr_t* arg         ,
87        const Base*   parameter   ,
88        size_t        cap_order   ,
89        Base*         taylor      )
90{
91        // check assumptions
92        CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );
93        CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );
94        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
95        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
96        CPPAD_ASSERT_UNKNOWN( 0 < q );
97        CPPAD_ASSERT_UNKNOWN( q < cap_order );
98
99        // Taylor coefficients corresponding to arguments and result
100        size_t num_taylor_per_var = (cap_order-1) * r + 1;
101        Base* x = taylor + arg[0] * num_taylor_per_var;
102        Base* y = taylor + arg[1] * num_taylor_per_var;
103        Base* z = taylor +    i_z * num_taylor_per_var;
104
105        size_t k, ell, m;
106        for(ell = 0; ell < r; ell++)
107        {       m = (q-1)*r + ell + 1;
108                z[m] = x[0] * y[m] + x[m] * y[0]; 
109                for(k = 1; k < q; k++)
110                        z[m] += x[(q-k-1)*r + ell + 1] * y[(k-1)*r + ell + 1];
111        }
112}
113
114/*!
115Compute zero order forward mode Taylor coefficients for result of op = MulvvOp.
116
117The C++ source code corresponding to this operation is
118\verbatim
119        z = x * y
120\endverbatim
121In the documentation below,
122this operations is for the case where both x and y are variables
123and the argument \a parameter is not used.
124
125\copydetails forward_binary_op_0
126*/
127
128template <class Base>
129inline void forward_mulvv_op_0(
130        size_t        i_z         ,
131        const addr_t* arg         ,
132        const Base*   parameter   ,
133        size_t        cap_order   ,
134        Base*         taylor      )
135{
136        // check assumptions
137        CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );
138        CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );
139        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
140        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
141
142        // Taylor coefficients corresponding to arguments and result
143        Base* x = taylor + arg[0] * cap_order;
144        Base* y = taylor + arg[1] * cap_order;
145        Base* z = taylor + i_z    * cap_order;
146
147        z[0] = x[0] * y[0];
148}
149
150/*!
151Compute reverse mode partial derivatives for result of op = MulvvOp.
152
153The C++ source code corresponding to this operation is
154\verbatim
155        z = x * y
156\endverbatim
157In the documentation below,
158this operations is for the case where both x and y are variables
159and the argument \a parameter is not used.
160
161\copydetails reverse_binary_op
162*/
163
164template <class Base>
165inline void reverse_mulvv_op(
166        size_t        d           , 
167        size_t        i_z         ,
168        const addr_t* arg         ,
169        const Base*   parameter   ,
170        size_t        cap_order   ,
171        const Base*   taylor      ,
172        size_t        nc_partial  ,
173        Base*         partial     )
174{
175        // check assumptions
176        CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );
177        CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );
178        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
179        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
180        CPPAD_ASSERT_UNKNOWN( d < cap_order );
181        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
182
183        // Arguments
184        const Base* x  = taylor + arg[0] * cap_order;
185        const Base* y  = taylor + arg[1] * cap_order;
186
187        // Partial derivatives corresponding to arguments and result
188        Base* px = partial + arg[0] * nc_partial;
189        Base* py = partial + arg[1] * nc_partial;
190        Base* pz = partial + i_z    * nc_partial;
191
192
193        // number of indices to access
194        size_t j = d + 1;
195        size_t k;
196        while(j)
197        {       --j;
198                for(k = 0; k <= j; k++)
199                {       
200                        px[j-k] += pz[j] * y[k];
201                        py[k]   += pz[j] * x[j-k];
202                }
203        }
204}
205// --------------------------- Mulpv -----------------------------------------
206/*!
207Compute forward mode Taylor coefficients for result of op = MulpvOp.
208
209The C++ source code corresponding to this operation is
210\verbatim
211        z = x * y
212\endverbatim
213In the documentation below,
214this operations is for the case where x is a parameter and y is a variable.
215
216\copydetails forward_binary_op
217*/
218
219template <class Base>
220inline void forward_mulpv_op(
221        size_t        p           , 
222        size_t        q           , 
223        size_t        i_z         ,
224        const addr_t* arg         ,
225        const Base*   parameter   ,
226        size_t        cap_order   ,
227        Base*         taylor      )
228{
229        // check assumptions
230        CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );
231        CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );
232        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
233        CPPAD_ASSERT_UNKNOWN( q < cap_order );
234        CPPAD_ASSERT_UNKNOWN( p <= q );
235
236        // Taylor coefficients corresponding to arguments and result
237        Base* y = taylor + arg[1] * cap_order;
238        Base* z = taylor + i_z    * cap_order;
239
240        // Paraemter value
241        Base x = parameter[ arg[0] ];
242
243        for(size_t d = p; d <= q; d++)
244                z[d] = x * y[d];
245}
246/*!
247Multiple directions forward mode Taylor coefficients for op = MulpvOp.
248
249The C++ source code corresponding to this operation is
250\verbatim
251        z = x * y
252\endverbatim
253In the documentation below,
254this operations is for the case where x is a parameter and y is a variable.
255
256\copydetails forward_binary_op_dir
257*/
258
259template <class Base>
260inline void forward_mulpv_op_dir(
261        size_t        q           , 
262        size_t        r           , 
263        size_t        i_z         ,
264        const addr_t* arg         ,
265        const Base*   parameter   ,
266        size_t        cap_order   ,
267        Base*         taylor      )
268{
269        // check assumptions
270        CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );
271        CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );
272        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
273        CPPAD_ASSERT_UNKNOWN( 0 < q );
274        CPPAD_ASSERT_UNKNOWN( q < cap_order );
275
276        // Taylor coefficients corresponding to arguments and result
277        size_t num_taylor_per_var = (cap_order-1) * r + 1;
278        size_t m                  = (q-1) * r + 1;
279        Base* y = taylor + arg[1] * num_taylor_per_var + m;
280        Base* z = taylor + i_z    * num_taylor_per_var + m;
281
282        // Paraemter value
283        Base x = parameter[ arg[0] ];
284
285        for(size_t ell = 0; ell < r; ell++)
286                z[ell] = x * y[ell];
287}
288/*!
289Compute zero order forward mode Taylor coefficient for result of op = MulpvOp.
290
291The C++ source code corresponding to this operation is
292\verbatim
293        z = x * y
294\endverbatim
295In the documentation below,
296this operations is for the case where x is a parameter and y is a variable.
297
298\copydetails forward_binary_op_0
299*/
300
301template <class Base>
302inline void forward_mulpv_op_0(
303        size_t        i_z         ,
304        const addr_t* arg         ,
305        const Base*   parameter   ,
306        size_t        cap_order   ,
307        Base*         taylor      )
308{
309        // check assumptions
310        CPPAD_ASSERT_UNKNOWN( NumArg(MulpvOp) == 2 );
311        CPPAD_ASSERT_UNKNOWN( NumRes(MulpvOp) == 1 );
312        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
313
314        // Paraemter value
315        Base x = parameter[ arg[0] ];
316
317        // Taylor coefficients corresponding to arguments and result
318        Base* y = taylor + arg[1] * cap_order;
319        Base* z = taylor + i_z    * cap_order;
320
321        z[0] = x * y[0];
322}
323
324/*!
325Compute reverse mode partial derivative for result of op = MulpvOp.
326
327The C++ source code corresponding to this operation is
328\verbatim
329        z = x * y
330\endverbatim
331In the documentation below,
332this operations is for the case where x is a parameter and y is a variable.
333
334\copydetails reverse_binary_op
335*/
336
337template <class Base>
338inline void reverse_mulpv_op(
339        size_t        d           , 
340        size_t        i_z         ,
341        const addr_t* arg         ,
342        const Base*   parameter   ,
343        size_t        cap_order   ,
344        const Base*   taylor      ,
345        size_t        nc_partial  ,
346        Base*         partial     )
347{
348        // check assumptions
349        CPPAD_ASSERT_UNKNOWN( NumArg(MulvvOp) == 2 );
350        CPPAD_ASSERT_UNKNOWN( NumRes(MulvvOp) == 1 );
351        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
352        CPPAD_ASSERT_UNKNOWN( d < cap_order );
353        CPPAD_ASSERT_UNKNOWN( d < nc_partial );
354
355        // Arguments
356        Base x  = parameter[ arg[0] ];
357
358        // Partial derivatives corresponding to arguments and result
359        Base* py = partial + arg[1] * nc_partial;
360        Base* pz = partial + i_z    * nc_partial;
361
362        // number of indices to access
363        size_t j = d + 1;
364        while(j)
365        {       --j;
366                py[j] += pz[j] * x;
367        }
368}
369
370
371} // END_CPPAD_NAMESPACE
372# endif
Note: See TracBrowser for help on using the repository browser.