CppAD: A C++ Algorithmic Differentiation Package  20171217
pow_op.hpp
Go to the documentation of this file.
3
4 /* --------------------------------------------------------------------------
6
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.
13 -------------------------------------------------------------------------- */
14
16 /*!
17 \file pow_op.hpp
18 Forward and reverse mode calculations for z = pow(x, y).
19 */
20
21 // --------------------------- Powvv -----------------------------------------
22 /*!
23 Compute forward mode Taylor coefficients for result of op = PowvvOp.
24
25 In the documentation below,
26 this operations is for the case where both x and y are variables
27 and the argument \a parameter is not used.
28
30 */
31
32 template <class Base>
33 inline void forward_powvv_op(
34  size_t p ,
35  size_t q ,
36  size_t i_z ,
38  const Base* parameter ,
39  size_t cap_order ,
40  Base* taylor )
41 {
42  // convert from final result to first result
43  i_z -= 2; // 2 = NumRes(PowvvOp) - 1;
44
45  // check assumptions
48  CPPAD_ASSERT_UNKNOWN( q < cap_order );
49  CPPAD_ASSERT_UNKNOWN( p <= q );
51
52  // z_0 = log(x)
53  forward_log_op(p, q, i_z, arg[0], cap_order, taylor);
54
55  // z_1 = z_0 * y
59  forward_mulvv_op(p, q, i_z+1, adr, parameter, cap_order, taylor);
60
61  // z_2 = exp(z_1)
62  // final result for zero order case is exactly the same as for Base
63  if( p == 0 )
64  { // Taylor coefficients corresponding to arguments and result
65  Base* x = taylor + arg[0] * cap_order;
66  Base* y = taylor + arg[1] * cap_order;
67  Base* z_2 = taylor + (i_z+2) * cap_order;
68
69  z_2[0] = pow(x[0], y[0]);
70  p++;
71  }
72  if( p <= q )
73  forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor);
74 }
75 /*!
76 Multiple directions forward mode Taylor coefficients for op = PowvvOp.
77
78 The C++ source code corresponding to this operation is
79 \verbatim
80  z = pow(x, y)
81 \endverbatim
82 In the documentation below,
83 this operations is for the case where x is a variable and y is a parameter.
84
86 */
87
88 template <class Base>
90  size_t q ,
91  size_t r ,
92  size_t i_z ,
94  const Base* parameter ,
95  size_t cap_order ,
96  Base* taylor )
97 {
98  // convert from final result to first result
99  i_z -= 2; // 2 = NumRes(PowvvOp) - 1
100
101  // check assumptions
104  CPPAD_ASSERT_UNKNOWN( 0 < q );
105  CPPAD_ASSERT_UNKNOWN( q < cap_order );
107
108  // z_0 = log(x)
109  forward_log_op_dir(q, r, i_z, arg[0], cap_order, taylor);
110
111  // z_1 = y * z_0
115  forward_mulvv_op_dir(q, r, i_z+1, adr, parameter, cap_order, taylor);
116
117  // z_2 = exp(z_1)
118  forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor);
119 }
120 /*!
121 Compute zero order forward mode Taylor coefficients for result of op = PowvvOp.
122
123 The C++ source code corresponding to this operation is
124 \verbatim
125  z = pow(x, y)
126 \endverbatim
127 In the documentation below,
128 this operations is for the case where both x and y are variables
129 and the argument \a parameter is not used.
130
132 */
133
134 template <class Base>
135 inline void forward_powvv_op_0(
136  size_t i_z ,
138  const Base* parameter ,
139  size_t cap_order ,
140  Base* taylor )
141 {
142  // convert from final result to first result
143  i_z -= 2; // NumRes(PowvvOp) - 1;
144
145  // check assumptions
148
149  // Taylor coefficients corresponding to arguments and result
150  Base* x = taylor + arg[0] * cap_order;
151  Base* y = taylor + arg[1] * cap_order;
152  Base* z_0 = taylor + i_z * cap_order;
153  Base* z_1 = z_0 + cap_order;
154  Base* z_2 = z_1 + cap_order;
155
156  z_0[0] = log( x[0] );
157  z_1[0] = z_0[0] * y[0];
158  z_2[0] = pow(x[0], y[0]);
159
160 }
161
162 /*!
163 Compute reverse mode partial derivatives for result of op = PowvvOp.
164
165 The C++ source code corresponding to this operation is
166 \verbatim
167  z = pow(x, y)
168 \endverbatim
169 In the documentation below,
170 this operations is for the case where both x and y are variables
171 and the argument \a parameter is not used.
172
174 */
175
176 template <class Base>
177 inline void reverse_powvv_op(
178  size_t d ,
179  size_t i_z ,
181  const Base* parameter ,
182  size_t cap_order ,
183  const Base* taylor ,
184  size_t nc_partial ,
185  Base* partial )
186 {
187  // convert from final result to first result
188  i_z -= 2; // NumRes(PowvvOp) - 1;
189
190  // check assumptions
193  CPPAD_ASSERT_UNKNOWN( d < cap_order );
194  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
196
197  // z_2 = exp(z_1)
199  d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial
200  );
201
202  // z_1 = z_0 * y
207  d, i_z+1, adr, parameter, cap_order, taylor, nc_partial, partial
208  );
209
210  // z_0 = log(x)
212  d, i_z, arg[0], cap_order, taylor, nc_partial, partial
213  );
214 }
215
216 // --------------------------- Powpv -----------------------------------------
217 /*!
218 Compute forward mode Taylor coefficients for result of op = PowpvOp.
219
220 The C++ source code corresponding to this operation is
221 \verbatim
222  z = pow(x, y)
223 \endverbatim
224 In the documentation below,
225 this operations is for the case where x is a parameter and y is a variable.
226
228 */
229
230 template <class Base>
231 inline void forward_powpv_op(
232  size_t p ,
233  size_t q ,
234  size_t i_z ,
236  const Base* parameter ,
237  size_t cap_order ,
238  Base* taylor )
239 {
240  // convert from final result to first result
241  i_z -= 2; // 2 = NumRes(PowpvOp) - 1;
242
243  // check assumptions
246  CPPAD_ASSERT_UNKNOWN( q < cap_order );
247  CPPAD_ASSERT_UNKNOWN( p <= q );
248
249  // Taylor coefficients corresponding to arguments and result
250  Base* z_0 = taylor + i_z * cap_order;
251
252  // z_0 = log(x)
253  Base x = parameter[ arg[0] ];
254  size_t d;
255  for(d = p; d <= q; d++)
256  { if( d == 0 )
257  z_0[d] = log(x);
258  else z_0[d] = Base(0.0);
259  }
260
261  // 2DO: remove requirement that i_z * cap_order <= max addr_t value
263  std::numeric_limits<addr_t>::max() >= i_z * cap_order,
265  "This is due to a kludge in the pow operation and should be fixed."
266  );
267
268  // z_1 = z_0 * y
270  // offset of z_i in taylor (as if it were a parameter); i.e., log(x)
272  // offset of y in taylor (as a variable)
274
275  // Trick: use taylor both for the parameter vector and variable values
276  forward_mulpv_op(p, q, i_z+1, adr, taylor, cap_order, taylor);
277
278  // z_2 = exp(z_1)
279  // zero order case exactly same as Base type operation
280  if( p == 0 )
281  { Base* y = taylor + arg[1] * cap_order;
282  Base* z_2 = taylor + (i_z+2) * cap_order;
283  z_2[0] = pow(x, y[0]);
284  p++;
285  }
286  if( p <= q )
287  forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor);
288 }
289 /*!
290 Multiple directions forward mode Taylor coefficients for op = PowpvOp.
291
292 The C++ source code corresponding to this operation is
293 \verbatim
294  z = pow(x, y)
295 \endverbatim
296 In the documentation below,
297 this operations is for the case where x is a parameter and y is a variable.
298
300 */
301
302 template <class Base>
304  size_t q ,
305  size_t r ,
306  size_t i_z ,
308  const Base* parameter ,
309  size_t cap_order ,
310  Base* taylor )
311 {
312  // convert from final result to first result
313  i_z -= 2; // 2 = NumRes(PowpvOp) - 1;
314
315  // check assumptions
318  CPPAD_ASSERT_UNKNOWN( 0 < q );
319  CPPAD_ASSERT_UNKNOWN( q < cap_order );
320
321  // Taylor coefficients corresponding to arguments and result
322  size_t num_taylor_per_var = (cap_order-1) * r + 1;
323  Base* z_0 = taylor + i_z * num_taylor_per_var;
324
325  // z_0 = log(x)
326  size_t m = (q-1) * r + 1;
327  for(size_t ell = 0; ell < r; ell++)
328  z_0[m+ell] = Base(0.0);
329
330  // 2DO: remove requirement i_z * num_taylor_per_var <= max addr_t value
332  std::numeric_limits<addr_t>::max() >= i_z * num_taylor_per_var,
334  "This is due to a kludge in the pow operation and should be fixed."
335  );
336
337  // z_1 = z_0 * y
339  // offset of z_0 in taylor (as if it were a parameter); i.e., log(x)
341  // ofset of y in taylor (as a variable)
343
344  // Trick: use taylor both for the parameter vector and variable values
345  forward_mulpv_op_dir(q, r, i_z+1, adr, taylor, cap_order, taylor);
346
347  // z_2 = exp(z_1)
348  forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor);
349 }
350 /*!
351 Compute zero order forward mode Taylor coefficient for result of op = PowpvOp.
352
353 The C++ source code corresponding to this operation is
354 \verbatim
355  z = pow(x, y)
356 \endverbatim
357 In the documentation below,
358 this operations is for the case where x is a parameter and y is a variable.
359
361 */
362
363 template <class Base>
364 inline void forward_powpv_op_0(
365  size_t i_z ,
367  const Base* parameter ,
368  size_t cap_order ,
369  Base* taylor )
370 {
371  // convert from final result to first result
372  i_z -= 2; // NumRes(PowpvOp) - 1;
373
374  // check assumptions
377
378  // Paraemter value
379  Base x = parameter[ arg[0] ];
380
381  // Taylor coefficients corresponding to arguments and result
382  Base* y = taylor + arg[1] * cap_order;
383  Base* z_0 = taylor + i_z * cap_order;
384  Base* z_1 = z_0 + cap_order;
385  Base* z_2 = z_1 + cap_order;
386
387  // z_0 = log(x)
388  z_0[0] = log(x);
389
390  // z_1 = z_0 * y
391  z_1[0] = z_0[0] * y[0];
392
393  // z_2 = exp(z_1)
394  // zero order case exactly same as Base type operation
395  z_2[0] = pow(x, y[0]);
396 }
397
398 /*!
399 Compute reverse mode partial derivative for result of op = PowpvOp.
400
401 The C++ source code corresponding to this operation is
402 \verbatim
403  z = pow(x, y)
404 \endverbatim
405 In the documentation below,
406 this operations is for the case where x is a parameter and y is a variable.
407
409 */
410
411 template <class Base>
412 inline void reverse_powpv_op(
413  size_t d ,
414  size_t i_z ,
416  const Base* parameter ,
417  size_t cap_order ,
418  const Base* taylor ,
419  size_t nc_partial ,
420  Base* partial )
421 {
422  // convert from final result to first result
423  i_z -= 2; // NumRes(PowpvOp) - 1;
424
425  // check assumptions
428  CPPAD_ASSERT_UNKNOWN( d < cap_order );
429  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
430
431  // z_2 = exp(z_1)
433  d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial
434  );
435
436  // 2DO: remove requirement that i_z * cap_order <= max addr_t value
438  std::numeric_limits<addr_t>::max() >= i_z * cap_order,
440  "This is due to a kludge in the pow operation and should be fixed."
441  );
442
443  // z_1 = z_0 * y
445  adr[0] = addr_t( i_z * cap_order ); // offset of z_0[0] in taylor
446  adr[1] = arg[1]; // index of y in taylor and partial
447  // use taylor both for parameter and variable values
449  d, i_z+1, adr, taylor, cap_order, taylor, nc_partial, partial
450  );
451
452  // z_0 = log(x)
453  // x is a parameter
454 }
455
456 // --------------------------- Powvp -----------------------------------------
457 /*!
458 Compute forward mode Taylor coefficients for result of op = PowvpOp.
459
460 The C++ source code corresponding to this operation is
461 \verbatim
462  z = pow(x, y)
463 \endverbatim
464 In the documentation below,
465 this operations is for the case where x is a variable and y is a parameter.
466
468 */
469
470 template <class Base>
471 inline void forward_powvp_op(
472  size_t p ,
473  size_t q ,
474  size_t i_z ,
476  const Base* parameter ,
477  size_t cap_order ,
478  Base* taylor )
479 {
480  // convert from final result to first result
481  i_z -= 2; // 2 = NumRes(PowvpOp) - 1
482
483  // check assumptions
486  CPPAD_ASSERT_UNKNOWN( q < cap_order );
487  CPPAD_ASSERT_UNKNOWN( p <= q );
489
490  // z_0 = log(x)
491  forward_log_op(p, q, i_z, arg[0], cap_order, taylor);
492
493  // z_1 = y * z_0
497  forward_mulpv_op(p, q, i_z+1, adr, parameter, cap_order, taylor);
498
499  // z_2 = exp(z_1)
500  // zero order case exactly same as Base type operation
501  if( p == 0 )
502  { Base* z_2 = taylor + (i_z+2) * cap_order;
503  Base* x = taylor + arg[0] * cap_order;
504  Base y = parameter[ arg[1] ];
505  z_2[0] = pow(x[0], y);
506  p++;
507  }
508  if( p <= q )
509  forward_exp_op(p, q, i_z+2, i_z+1, cap_order, taylor);
510 }
511 /*!
512 Multiple directions forward mode Taylor coefficients for op = PowvpOp.
513
514 The C++ source code corresponding to this operation is
515 \verbatim
516  z = pow(x, y)
517 \endverbatim
518 In the documentation below,
519 this operations is for the case where x is a variable and y is a parameter.
520
522 */
523
524 template <class Base>
526  size_t q ,
527  size_t r ,
528  size_t i_z ,
530  const Base* parameter ,
531  size_t cap_order ,
532  Base* taylor )
533 {
534  // convert from final result to first result
535  i_z -= 2; // 2 = NumRes(PowvpOp) - 1
536
537  // check assumptions
540  CPPAD_ASSERT_UNKNOWN( 0 < q );
541  CPPAD_ASSERT_UNKNOWN( q < cap_order );
543
544  // z_0 = log(x)
545  forward_log_op_dir(q, r, i_z, arg[0], cap_order, taylor);
546
547  // z_1 = y * z_0
551  forward_mulpv_op_dir(q, r, i_z+1, adr, parameter, cap_order, taylor);
552
553  // z_2 = exp(z_1)
554  forward_exp_op_dir(q, r, i_z+2, i_z+1, cap_order, taylor);
555 }
556
557 /*!
558 Compute zero order forward mode Taylor coefficients for result of op = PowvpOp.
559
560 The C++ source code corresponding to this operation is
561 \verbatim
562  z = pow(x, y)
563 \endverbatim
564 In the documentation below,
565 this operations is for the case where x is a variable and y is a parameter.
566
568 */
569
570 template <class Base>
571 inline void forward_powvp_op_0(
572  size_t i_z ,
574  const Base* parameter ,
575  size_t cap_order ,
576  Base* taylor )
577 {
578  // convert from final result to first result
579  i_z -= 2; // NumRes(PowvpOp) - 1;
580
581  // check assumptions
584
585  // Paraemter value
586  Base y = parameter[ arg[1] ];
587
588  // Taylor coefficients corresponding to arguments and result
589  Base* x = taylor + arg[0] * cap_order;
590  Base* z_0 = taylor + i_z * cap_order;
591  Base* z_1 = z_0 + cap_order;
592  Base* z_2 = z_1 + cap_order;
593
594  // z_0 = log(x)
595  z_0[0] = log(x[0]);
596
597  // z_1 = z_0 * y
598  z_1[0] = z_0[0] * y;
599
600  // z_2 = exp(z_1)
601  // zero order case exactly same as Base type operation
602  z_2[0] = pow(x[0], y);
603 }
604
605 /*!
606 Compute reverse mode partial derivative for result of op = PowvpOp.
607
608 The C++ source code corresponding to this operation is
609 \verbatim
610  z = pow(x, y)
611 \endverbatim
612 In the documentation below,
613 this operations is for the case where x is a variable and y is a parameter.
614
616 */
617
618 template <class Base>
619 inline void reverse_powvp_op(
620  size_t d ,
621  size_t i_z ,
623  const Base* parameter ,
624  size_t cap_order ,
625  const Base* taylor ,
626  size_t nc_partial ,
627  Base* partial )
628 {
629  // convert from final result to first result
630  i_z -= 2; // NumRes(PowvpOp) - 1;
631
632  // check assumptions
635  CPPAD_ASSERT_UNKNOWN( d < cap_order );
636  CPPAD_ASSERT_UNKNOWN( d < nc_partial );
638
639  // z_2 = exp(z_1)
641  d, i_z+2, i_z+1, cap_order, taylor, nc_partial, partial
642  );
643
644  // z_1 = y * z_0
649  d, i_z+1, adr, parameter, cap_order, taylor, nc_partial, partial
650  );
651
652  // z_0 = log(x)
654  d, i_z, arg[0], cap_order, taylor, nc_partial, partial
655  );
656 }
657
659 # endif
Check that exp is true, if not print msg and terminate execution.
void reverse_mulvv_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)
Compute reverse mode partial derivatives for result of op = MulvvOp.
Definition: mul_op.hpp:158
void forward_powvp_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)
Multiple directions forward mode Taylor coefficients for op = PowvpOp.
Definition: pow_op.hpp:525
void forward_powpv_op_0(size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute zero order forward mode Taylor coefficient for result of op = PowpvOp.
Definition: pow_op.hpp:364
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
void reverse_powvv_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)
Compute reverse mode partial derivatives for result of op = PowvvOp.
Definition: pow_op.hpp:177
void forward_powvp_op(size_t p, size_t q, size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for result of op = PowvpOp.
Definition: pow_op.hpp:471
void reverse_mulpv_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)
Compute reverse mode partial derivative for result of op = MulpvOp.
Definition: mul_op.hpp:326
void reverse_exp_op(size_t d, size_t i_z, size_t i_x, size_t cap_order, const Base *taylor, size_t nc_partial, Base *partial)
Reverse mode partial derivatives for result of op = ExpOp.
Definition: exp_op.hpp:146
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
void reverse_powpv_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)
Compute reverse mode partial derivative for result of op = PowpvOp.
Definition: pow_op.hpp:412
void forward_log_op(size_t p, size_t q, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficient for result of op = LogOp.
Definition: log_op.hpp:32
void forward_powvv_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)
Multiple directions forward mode Taylor coefficients for op = PowvvOp.
Definition: pow_op.hpp:89
void forward_exp_op_dir(size_t q, size_t r, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Multiple direction forward mode Taylor coefficient for op = ExpOp.
Definition: exp_op.hpp:78
Type pow(const Type &x, const int &n)
Definition: pow_int.hpp:116
void forward_mulvv_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)
Multiple directions forward mode Taylor coefficients for op = MulvvOp.
Definition: mul_op.hpp:79
void reverse_powvp_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)
Compute reverse mode partial derivative for result of op = PowvpOp.
Definition: pow_op.hpp:619
void forward_mulvv_op(size_t p, size_t q, size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for result of op = MulvvOp.
Definition: mul_op.hpp:37
void forward_mulpv_op(size_t p, size_t q, size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for result of op = MulpvOp.
Definition: mul_op.hpp:211
void forward_powvp_op_0(size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute zero order forward mode Taylor coefficients for result of op = PowvpOp.
Definition: pow_op.hpp:571
Check that exp is true, if not terminate execution.
void forward_log_op_dir(size_t q, size_t r, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Muiltiple directions Taylor coefficient for op = LogOp.
Definition: log_op.hpp:84
void forward_mulpv_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)
Multiple directions forward mode Taylor coefficients for op = MulpvOp.
Definition: mul_op.hpp:250
void forward_powpv_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)
Multiple directions forward mode Taylor coefficients for op = PowpvOp.
Definition: pow_op.hpp:303
void forward_powvv_op_0(size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute zero order forward mode Taylor coefficients for result of op = PowvvOp.
Definition: pow_op.hpp:135
void forward_powvv_op(size_t p, size_t q, size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for result of op = PowvvOp.
Definition: pow_op.hpp:33
void reverse_log_op(size_t d, size_t i_z, size_t i_x, size_t cap_order, const Base *taylor, size_t nc_partial, Base *partial)
Compute reverse mode partial derivatives for result of op = LogOp.
Definition: log_op.hpp:155
void forward_exp_op(size_t p, size_t q, size_t i_z, size_t i_x, size_t cap_order, Base *taylor)
Forward mode Taylor coefficient for result of op = ExpOp.
Definition: exp_op.hpp:34
void forward_powpv_op(size_t p, size_t q, size_t i_z, const addr_t *arg, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for result of op = PowpvOp.
Definition: pow_op.hpp:231