1 # ifndef CPPAD_LOCAL_ZMUL_OP_HPP
2 # define CPPAD_LOCAL_ZMUL_OP_HPP
3
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9 Eclipse Public License Version 1.0.
10
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14
15 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
16 /*!
17 \file mul_op.hpp
18 Forward and reverse mode calculations for z = azmul(x, y).
19 */
20
21 // --------------------------- Zmulvv -----------------------------------------
22 /*!
23 Compute forward mode Taylor coefficients for result of op = ZmulvvOp.
24
25 The C++ source code corresponding to this operation is
26 \verbatim
27 z = azmul(x, y)
28 \endverbatim
29 In the documentation below,
30 this operations is for the case where both x and y are variables
31 and the argument \a parameter is not used.
32
33 \copydetails CppAD::local::forward_binary_op
34 */
35
36 template <class Base>
forward_zmulvv_op(size_t p,size_t q,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)37 inline void forward_zmulvv_op(
38 size_t p ,
39 size_t q ,
40 size_t i_z ,
41 const addr_t* arg ,
42 const Base* parameter ,
43 size_t cap_order ,
44 Base* taylor )
45 {
46 // check assumptions
47 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );
48 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
49 CPPAD_ASSERT_UNKNOWN( q < cap_order );
50 CPPAD_ASSERT_UNKNOWN( p <= q );
51
52 // Taylor coefficients corresponding to arguments and result
53 Base* x = taylor + arg[0] * cap_order;
54 Base* y = taylor + arg[1] * cap_order;
55 Base* z = taylor + i_z * cap_order;
56
57 size_t k;
58 for(size_t d = p; d <= q; d++)
59 { z[d] = Base(0.0);
60 for(k = 0; k <= d; k++)
61 z[d] += azmul(x[d-k], y[k]);
62 }
63 }
64 /*!
65 Multiple directions forward mode Taylor coefficients for op = ZmulvvOp.
66
67 The C++ source code corresponding to this operation is
68 \verbatim
69 z = azmul(x, y)
70 \endverbatim
71 In the documentation below,
72 this operations is for the case where both x and y are variables
73 and the argument \a parameter is not used.
74
75 \copydetails CppAD::local::forward_binary_op_dir
76 */
77
78 template <class Base>
forward_zmulvv_op_dir(size_t q,size_t r,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)79 inline void forward_zmulvv_op_dir(
80 size_t q ,
81 size_t r ,
82 size_t i_z ,
83 const addr_t* arg ,
84 const Base* parameter ,
85 size_t cap_order ,
86 Base* taylor )
87 {
88 // check assumptions
89 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );
90 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
91 CPPAD_ASSERT_UNKNOWN( 0 < q );
92 CPPAD_ASSERT_UNKNOWN( q < cap_order );
93
94 // Taylor coefficients corresponding to arguments and result
95 size_t num_taylor_per_var = (cap_order-1) * r + 1;
96 Base* x = taylor + arg[0] * num_taylor_per_var;
97 Base* y = taylor + arg[1] * num_taylor_per_var;
98 Base* z = taylor + i_z * num_taylor_per_var;
99
100 size_t k, ell, m;
101 for(ell = 0; ell < r; ell++)
102 { m = (q-1)*r + ell + 1;
103 z[m] = azmul(x[0], y[m]) + azmul(x[m], y[0]);
104 for(k = 1; k < q; k++)
105 z[m] += azmul(x[(q-k-1)*r + ell + 1], y[(k-1)*r + ell + 1]);
106 }
107 }
108
109 /*!
110 Compute zero order forward mode Taylor coefficients for result of op = ZmulvvOp.
111
112 The C++ source code corresponding to this operation is
113 \verbatim
114 z = azmul(x, y)
115 \endverbatim
116 In the documentation below,
117 this operations is for the case where both x and y are variables
118 and the argument \a parameter is not used.
119
120 \copydetails CppAD::local::forward_binary_op_0
121 */
122
123 template <class Base>
forward_zmulvv_op_0(size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)124 inline void forward_zmulvv_op_0(
125 size_t i_z ,
126 const addr_t* arg ,
127 const Base* parameter ,
128 size_t cap_order ,
129 Base* taylor )
130 {
131 // check assumptions
132 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );
133 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
134
135 // Taylor coefficients corresponding to arguments and result
136 Base* x = taylor + arg[0] * cap_order;
137 Base* y = taylor + arg[1] * cap_order;
138 Base* z = taylor + i_z * cap_order;
139
140 z[0] = azmul(x[0], y[0]);
141 }
142
143 /*!
144 Compute reverse mode partial derivatives for result of op = ZmulvvOp.
145
146 The C++ source code corresponding to this operation is
147 \verbatim
148 z = azmul(x, y)
149 \endverbatim
150 In the documentation below,
151 this operations is for the case where both x and y are variables
152 and the argument \a parameter is not used.
153
154 \copydetails CppAD::local::reverse_binary_op
155 */
156
157 template <class Base>
reverse_zmulvv_op(size_t d,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,const Base * taylor,size_t nc_partial,Base * partial)158 inline void reverse_zmulvv_op(
159 size_t d ,
160 size_t i_z ,
161 const addr_t* arg ,
162 const Base* parameter ,
163 size_t cap_order ,
164 const Base* taylor ,
165 size_t nc_partial ,
166 Base* partial )
167 {
168 // check assumptions
169 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvvOp) == 2 );
170 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvvOp) == 1 );
171 CPPAD_ASSERT_UNKNOWN( d < cap_order );
172 CPPAD_ASSERT_UNKNOWN( d < nc_partial );
173
174 // Arguments
175 const Base* x = taylor + arg[0] * cap_order;
176 const Base* y = taylor + arg[1] * cap_order;
177
178 // Partial derivatives corresponding to arguments and result
179 Base* px = partial + arg[0] * nc_partial;
180 Base* py = partial + arg[1] * nc_partial;
181 Base* pz = partial + i_z * nc_partial;
182
183 // number of indices to access
184 size_t j = d + 1;
185 size_t k;
186 while(j)
187 { --j;
188 for(k = 0; k <= j; k++)
189 {
190 px[j-k] += azmul(pz[j], y[k]);
191 py[k] += azmul(pz[j], x[j-k]);
192 }
193 }
194 }
195 // --------------------------- Zmulpv -----------------------------------------
196 /*!
197 Compute forward mode Taylor coefficients for result of op = ZmulpvOp.
198
199 The C++ source code corresponding to this operation is
200 \verbatim
201 z = azmul(x, y)
202 \endverbatim
203 In the documentation below,
204 this operations is for the case where x is a parameter and y is a variable.
205
206 \copydetails CppAD::local::forward_binary_op
207 */
208
209 template <class Base>
forward_zmulpv_op(size_t p,size_t q,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)210 inline void forward_zmulpv_op(
211 size_t p ,
212 size_t q ,
213 size_t i_z ,
214 const addr_t* arg ,
215 const Base* parameter ,
216 size_t cap_order ,
217 Base* taylor )
218 {
219 // check assumptions
220 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );
221 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );
222 CPPAD_ASSERT_UNKNOWN( q < cap_order );
223 CPPAD_ASSERT_UNKNOWN( p <= q );
224
225 // Taylor coefficients corresponding to arguments and result
226 Base* y = taylor + arg[1] * cap_order;
227 Base* z = taylor + i_z * cap_order;
228
229 // Paraemter value
230 Base x = parameter[ arg[0] ];
231
232 for(size_t d = p; d <= q; d++)
233 z[d] = azmul(x, y[d]);
234 }
235 /*!
236 Multiple directions forward mode Taylor coefficients for op = ZmulpvOp.
237
238 The C++ source code corresponding to this operation is
239 \verbatim
240 z = azmul(x, y)
241 \endverbatim
242 In the documentation below,
243 this operations is for the case where x is a parameter and y is a variable.
244
245 \copydetails CppAD::local::forward_binary_op_dir
246 */
247
248 template <class Base>
forward_zmulpv_op_dir(size_t q,size_t r,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)249 inline void forward_zmulpv_op_dir(
250 size_t q ,
251 size_t r ,
252 size_t i_z ,
253 const addr_t* arg ,
254 const Base* parameter ,
255 size_t cap_order ,
256 Base* taylor )
257 {
258 // check assumptions
259 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );
260 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );
261 CPPAD_ASSERT_UNKNOWN( 0 < q );
262 CPPAD_ASSERT_UNKNOWN( q < cap_order );
263
264 // Taylor coefficients corresponding to arguments and result
265 size_t num_taylor_per_var = (cap_order-1) * r + 1;
266 size_t m = (q-1) * r + 1;
267 Base* y = taylor + arg[1] * num_taylor_per_var + m;
268 Base* z = taylor + i_z * num_taylor_per_var + m;
269
270 // Paraemter value
271 Base x = parameter[ arg[0] ];
272
273 for(size_t ell = 0; ell < r; ell++)
274 z[ell] = azmul(x, y[ell]);
275 }
276 /*!
277 Compute zero order forward mode Taylor coefficient for result of op = ZmulpvOp.
278
279 The C++ source code corresponding to this operation is
280 \verbatim
281 z = azmul(x, y)
282 \endverbatim
283 In the documentation below,
284 this operations is for the case where x is a parameter and y is a variable.
285
286 \copydetails CppAD::local::forward_binary_op_0
287 */
288
289 template <class Base>
forward_zmulpv_op_0(size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)290 inline void forward_zmulpv_op_0(
291 size_t i_z ,
292 const addr_t* arg ,
293 const Base* parameter ,
294 size_t cap_order ,
295 Base* taylor )
296 {
297 // check assumptions
298 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );
299 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );
300
301 // Paraemter value
302 Base x = parameter[ arg[0] ];
303
304 // Taylor coefficients corresponding to arguments and result
305 Base* y = taylor + arg[1] * cap_order;
306 Base* z = taylor + i_z * cap_order;
307
308 z[0] = azmul(x, y[0]);
309 }
310
311 /*!
312 Compute reverse mode partial derivative for result of op = ZmulpvOp.
313
314 The C++ source code corresponding to this operation is
315 \verbatim
316 z = azmul(x, y)
317 \endverbatim
318 In the documentation below,
319 this operations is for the case where x is a parameter and y is a variable.
320
321 \copydetails CppAD::local::reverse_binary_op
322 */
323
324 template <class Base>
reverse_zmulpv_op(size_t d,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,const Base * taylor,size_t nc_partial,Base * partial)325 inline void reverse_zmulpv_op(
326 size_t d ,
327 size_t i_z ,
328 const addr_t* arg ,
329 const Base* parameter ,
330 size_t cap_order ,
331 const Base* taylor ,
332 size_t nc_partial ,
333 Base* partial )
334 {
335 // check assumptions
336 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulpvOp) == 2 );
337 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulpvOp) == 1 );
338 CPPAD_ASSERT_UNKNOWN( d < cap_order );
339 CPPAD_ASSERT_UNKNOWN( d < nc_partial );
340
341 // Arguments
342 Base x = parameter[ arg[0] ];
343
344 // Partial derivatives corresponding to arguments and result
345 Base* py = partial + arg[1] * nc_partial;
346 Base* pz = partial + i_z * nc_partial;
347
348 // number of indices to access
349 size_t j = d + 1;
350 while(j)
351 { --j;
352 py[j] += azmul(pz[j], x);
353 }
354 }
355 // --------------------------- Zmulvp -----------------------------------------
356 /*!
357 Compute forward mode Taylor coefficients for result of op = ZmulvpOp.
358
359 The C++ source code corresponding to this operation is
360 \verbatim
361 z = azmul(x, y)
362 \endverbatim
363 In the documentation below,
364 this operations is for the case where x is a parameter and y is a variable.
365
366 \copydetails CppAD::local::forward_binary_op
367 */
368
369 template <class Base>
forward_zmulvp_op(size_t p,size_t q,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)370 inline void forward_zmulvp_op(
371 size_t p ,
372 size_t q ,
373 size_t i_z ,
374 const addr_t* arg ,
375 const Base* parameter ,
376 size_t cap_order ,
377 Base* taylor )
378 {
379 // check assumptions
380 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );
381 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
382 CPPAD_ASSERT_UNKNOWN( q < cap_order );
383 CPPAD_ASSERT_UNKNOWN( p <= q );
384
385 // Taylor coefficients corresponding to arguments and result
386 Base* x = taylor + arg[0] * cap_order;
387 Base* z = taylor + i_z * cap_order;
388
389 // Paraemter value
390 Base y = parameter[ arg[1] ];
391
392 for(size_t d = p; d <= q; d++)
393 z[d] = azmul(x[d], y);
394 }
395 /*!
396 Multiple directions forward mode Taylor coefficients for op = ZmulvpOp.
397
398 The C++ source code corresponding to this operation is
399 \verbatim
400 z = azmul(x, y)
401 \endverbatim
402 In the documentation below,
403 this operations is for the case where x is a parameter and y is a variable.
404
405 \copydetails CppAD::local::forward_binary_op_dir
406 */
407
408 template <class Base>
forward_zmulvp_op_dir(size_t q,size_t r,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)409 inline void forward_zmulvp_op_dir(
410 size_t q ,
411 size_t r ,
412 size_t i_z ,
413 const addr_t* arg ,
414 const Base* parameter ,
415 size_t cap_order ,
416 Base* taylor )
417 {
418 // check assumptions
419 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );
420 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
421 CPPAD_ASSERT_UNKNOWN( 0 < q );
422 CPPAD_ASSERT_UNKNOWN( q < cap_order );
423
424 // Taylor coefficients corresponding to arguments and result
425 size_t num_taylor_per_var = (cap_order-1) * r + 1;
426 size_t m = (q-1) * r + 1;
427 Base* x = taylor + arg[0] * num_taylor_per_var + m;
428 Base* z = taylor + i_z * num_taylor_per_var + m;
429
430 // Paraemter value
431 Base y = parameter[ arg[1] ];
432
433 for(size_t ell = 0; ell < r; ell++)
434 z[ell] = azmul(x[ell], y);
435 }
436 /*!
437 Compute zero order forward mode Taylor coefficient for result of op = ZmulvpOp.
438
439 The C++ source code corresponding to this operation is
440 \verbatim
441 z = azmul(x, y)
442 \endverbatim
443 In the documentation below,
444 this operations is for the case where x is a parameter and y is a variable.
445
446 \copydetails CppAD::local::forward_binary_op_0
447 */
448
449 template <class Base>
forward_zmulvp_op_0(size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,Base * taylor)450 inline void forward_zmulvp_op_0(
451 size_t i_z ,
452 const addr_t* arg ,
453 const Base* parameter ,
454 size_t cap_order ,
455 Base* taylor )
456 {
457 // check assumptions
458 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );
459 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
460
461 // Paraemter value
462 Base y = parameter[ arg[1] ];
463
464 // Taylor coefficients corresponding to arguments and result
465 Base* x = taylor + arg[0] * cap_order;
466 Base* z = taylor + i_z * cap_order;
467
468 z[0] = azmul(x[0], y);
469 }
470
471 /*!
472 Compute reverse mode partial derivative for result of op = ZmulvpOp.
473
474 The C++ source code corresponding to this operation is
475 \verbatim
476 z = azmul(x, y)
477 \endverbatim
478 In the documentation below,
479 this operations is for the case where x is a parameter and y is a variable.
480
481 \copydetails CppAD::local::reverse_binary_op
482 */
483
484 template <class Base>
reverse_zmulvp_op(size_t d,size_t i_z,const addr_t * arg,const Base * parameter,size_t cap_order,const Base * taylor,size_t nc_partial,Base * partial)485 inline void reverse_zmulvp_op(
486 size_t d ,
487 size_t i_z ,
488 const addr_t* arg ,
489 const Base* parameter ,
490 size_t cap_order ,
491 const Base* taylor ,
492 size_t nc_partial ,
493 Base* partial )
494 {
495 // check assumptions
496 CPPAD_ASSERT_UNKNOWN( NumArg(ZmulvpOp) == 2 );
497 CPPAD_ASSERT_UNKNOWN( NumRes(ZmulvpOp) == 1 );
498 CPPAD_ASSERT_UNKNOWN( d < cap_order );
499 CPPAD_ASSERT_UNKNOWN( d < nc_partial );
500
501 // Arguments
502 Base y = parameter[ arg[1] ];
503
504 // Partial derivatives corresponding to arguments and result
505 Base* px = partial + arg[0] * nc_partial;
506 Base* pz = partial + i_z * nc_partial;
507
508 // number of indices to access
509 size_t j = d + 1;
510 while(j)
511 { --j;
512 px[j] += azmul(pz[j], y);
513 }
514 }
515
516 } } // END_CPPAD_LOCAL_NAMESPACE
517 # endif
518