CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
cond_op.hpp
Go to the documentation of this file.
1 // $Id: cond_op.hpp 3845 2016-11-19 01:50:47Z bradbell $
2 # ifndef CPPAD_LOCAL_COND_OP_HPP
3 # define CPPAD_LOCAL_COND_OP_HPP
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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 cond_op.hpp
18 Forward, reverse, and sparse operations for conditional expressions.
19 */
20 
21 /*!
22 Shared documentation for conditional expressions (not called).
23 
24 <!-- define conditional_exp_op -->
25 The C++ source code coresponding to this operation is
26 \verbatim
27  z = CondExpRel(y_0, y_1, y_2, y_3)
28 \endverbatim
29 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
30 
31 \tparam Base
32 base type for the operator; i.e., this operation was recorded
33 using AD< \a Base > and computations by this routine are done using type
34 \a Base.
35 
36 \param i_z
37 is the AD variable index corresponding to the variable z.
38 
39 \param arg
40 \n
41 \a arg[0]
42 is static cast to size_t from the enum type
43 \verbatim
44  enum CompareOp {
45  CompareLt,
46  CompareLe,
47  CompareEq,
48  CompareGe,
49  CompareGt,
50  CompareNe
51  }
52 \endverbatim
53 for this operation.
54 Note that arg[0] cannot be equal to CompareNe.
55 \n
56 \n
57 \a arg[1] & 1
58 \n
59 If this is zero, y_0 is a parameter. Otherwise it is a variable.
60 \n
61 \n
62 \a arg[1] & 2
63 \n
64 If this is zero, y_1 is a parameter. Otherwise it is a variable.
65 \n
66 \n
67 \a arg[1] & 4
68 \n
69 If this is zero, y_2 is a parameter. Otherwise it is a variable.
70 \n
71 \n
72 \a arg[1] & 8
73 \n
74 If this is zero, y_3 is a parameter. Otherwise it is a variable.
75 \n
76 \n
77 \a arg[2 + j ] for j = 0, 1, 2, 3
78 \n
79 is the index corresponding to y_j.
80 
81 \param num_par
82 is the total number of values in the vector \a parameter.
83 
84 \param parameter
85 For j = 0, 1, 2, 3,
86 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
87 
88 \param cap_order
89 number of columns in the matrix containing the Taylor coefficients.
90 
91 \par Checked Assertions
92 \li NumArg(CExpOp) == 6
93 \li NumRes(CExpOp) == 1
94 \li arg[0] < static_cast<size_t> ( CompareNe )
95 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
96 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
97 <!-- end conditional_exp_op -->
98 */
99 template <class Base>
100 inline void conditional_exp_op(
101  size_t i_z ,
102  const addr_t* arg ,
103  size_t num_par ,
104  const Base* parameter ,
105  size_t cap_order )
106 { // This routine is only for documentation, it should never be used
107  CPPAD_ASSERT_UNKNOWN( false );
108 }
109 
110 /*!
111 Shared documentation for conditional expression sparse operations (not called).
112 
113 <!-- define sparse_conditional_exp_op -->
114 The C++ source code coresponding to this operation is
115 \verbatim
116  z = CondExpRel(y_0, y_1, y_2, y_3)
117 \endverbatim
118 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
119 
120 \tparam Vector_set
121 is the type used for vectors of sets. It can be either
122 sparse_pack or sparse_list.
123 
124 \param i_z
125 is the AD variable index corresponding to the variable z.
126 
127 \param arg
128 \n
129 \a arg[0]
130 is static cast to size_t from the enum type
131 \verbatim
132  enum CompareOp {
133  CompareLt,
134  CompareLe,
135  CompareEq,
136  CompareGe,
137  CompareGt,
138  CompareNe
139  }
140 \endverbatim
141 for this operation.
142 Note that arg[0] cannot be equal to CompareNe.
143 \n
144 \n
145 \a arg[1] & 1
146 \n
147 If this is zero, y_0 is a parameter. Otherwise it is a variable.
148 \n
149 \n
150 \a arg[1] & 2
151 \n
152 If this is zero, y_1 is a parameter. Otherwise it is a variable.
153 \n
154 \n
155 \a arg[1] & 4
156 \n
157 If this is zero, y_2 is a parameter. Otherwise it is a variable.
158 \n
159 \n
160 \a arg[1] & 8
161 \n
162 If this is zero, y_3 is a parameter. Otherwise it is a variable.
163 \n
164 \n
165 \a arg[2 + j ] for j = 0, 1, 2, 3
166 \n
167 is the index corresponding to y_j.
168 
169 \param num_par
170 is the total number of values in the vector \a parameter.
171 
172 \par Checked Assertions
173 \li NumArg(CExpOp) == 6
174 \li NumRes(CExpOp) == 1
175 \li arg[0] < static_cast<size_t> ( CompareNe )
176 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
177 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
178 <!-- end sparse_conditional_exp_op -->
179 */
180 template <class Vector_set>
182  size_t i_z ,
183  const addr_t* arg ,
184  size_t num_par )
185 { // This routine is only for documentation, it should never be used
186  CPPAD_ASSERT_UNKNOWN( false );
187 }
188 
189 /*!
190 Compute forward mode Taylor coefficients for op = CExpOp.
191 
192 <!-- replace conditional_exp_op -->
193 The C++ source code coresponding to this operation is
194 \verbatim
195  z = CondExpRel(y_0, y_1, y_2, y_3)
196 \endverbatim
197 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
198 
199 \tparam Base
200 base type for the operator; i.e., this operation was recorded
201 using AD< \a Base > and computations by this routine are done using type
202 \a Base.
203 
204 \param i_z
205 is the AD variable index corresponding to the variable z.
206 
207 \param arg
208 \n
209 \a arg[0]
210 is static cast to size_t from the enum type
211 \verbatim
212  enum CompareOp {
213  CompareLt,
214  CompareLe,
215  CompareEq,
216  CompareGe,
217  CompareGt,
218  CompareNe
219  }
220 \endverbatim
221 for this operation.
222 Note that arg[0] cannot be equal to CompareNe.
223 \n
224 \n
225 \a arg[1] & 1
226 \n
227 If this is zero, y_0 is a parameter. Otherwise it is a variable.
228 \n
229 \n
230 \a arg[1] & 2
231 \n
232 If this is zero, y_1 is a parameter. Otherwise it is a variable.
233 \n
234 \n
235 \a arg[1] & 4
236 \n
237 If this is zero, y_2 is a parameter. Otherwise it is a variable.
238 \n
239 \n
240 \a arg[1] & 8
241 \n
242 If this is zero, y_3 is a parameter. Otherwise it is a variable.
243 \n
244 \n
245 \a arg[2 + j ] for j = 0, 1, 2, 3
246 \n
247 is the index corresponding to y_j.
248 
249 \param num_par
250 is the total number of values in the vector \a parameter.
251 
252 \param parameter
253 For j = 0, 1, 2, 3,
254 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
255 
256 \param cap_order
257 number of columns in the matrix containing the Taylor coefficients.
258 
259 \par Checked Assertions
260 \li NumArg(CExpOp) == 6
261 \li NumRes(CExpOp) == 1
262 \li arg[0] < static_cast<size_t> ( CompareNe )
263 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
264 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
265 <!-- end conditional_exp_op -->
266 
267 \param p
268 is the lowest order of the Taylor coefficient of z that we are computing.
269 
270 \param q
271 is the highest order of the Taylor coefficient of z that we are computing.
272 
273 \param taylor
274 \b Input:
275 For j = 0, 1, 2, 3 and k = 0 , ... , q,
276 if y_j is a variable then
277 <code>taylor [ arg[2+j] * cap_order + k ]</code>
278 is the k-th order Taylor coefficient corresponding to y_j.
279 \n
280 \b Input: <code>taylor [ i_z * cap_order + k ]</code>
281 for k = 0 , ... , p-1,
282 is the k-th order Taylor coefficient corresponding to z.
283 \n
284 \b Output: <code>taylor [ i_z * cap_order + k ]</code>
285 for k = p , ... , q,
286 is the k-th order Taylor coefficient corresponding to z.
287 
288 */
289 template <class Base>
290 inline void forward_cond_op(
291  size_t p ,
292  size_t q ,
293  size_t i_z ,
294  const addr_t* arg ,
295  size_t num_par ,
296  const Base* parameter ,
297  size_t cap_order ,
298  Base* taylor )
299 { Base y_0, y_1, y_2, y_3;
300  Base zero(0);
301  Base* z = taylor + i_z * cap_order;
302 
303  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
306  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
307 
308  if( arg[1] & 1 )
309  {
310  y_0 = taylor[ arg[2] * cap_order + 0 ];
311  }
312  else
313  { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
314  y_0 = parameter[ arg[2] ];
315  }
316  if( arg[1] & 2 )
317  {
318  y_1 = taylor[ arg[3] * cap_order + 0 ];
319  }
320  else
321  { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
322  y_1 = parameter[ arg[3] ];
323  }
324  if( p == 0 )
325  { if( arg[1] & 4 )
326  {
327  y_2 = taylor[ arg[4] * cap_order + 0 ];
328  }
329  else
330  { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
331  y_2 = parameter[ arg[4] ];
332  }
333  if( arg[1] & 8 )
334  {
335  y_3 = taylor[ arg[5] * cap_order + 0 ];
336  }
337  else
338  { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
339  y_3 = parameter[ arg[5] ];
340  }
341  z[0] = CondExpOp(
342  CompareOp( arg[0] ),
343  y_0,
344  y_1,
345  y_2,
346  y_3
347  );
348  p++;
349  }
350  for(size_t d = p; d <= q; d++)
351  { if( arg[1] & 4 )
352  {
353  y_2 = taylor[ arg[4] * cap_order + d];
354  }
355  else y_2 = zero;
356  if( arg[1] & 8 )
357  {
358  y_3 = taylor[ arg[5] * cap_order + d];
359  }
360  else y_3 = zero;
361  z[d] = CondExpOp(
362  CompareOp( arg[0] ),
363  y_0,
364  y_1,
365  y_2,
366  y_3
367  );
368  }
369  return;
370 }
371 
372 /*!
373 Multiple directions forward mode Taylor coefficients for op = CExpOp.
374 
375 <!-- replace conditional_exp_op -->
376 The C++ source code coresponding to this operation is
377 \verbatim
378  z = CondExpRel(y_0, y_1, y_2, y_3)
379 \endverbatim
380 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
381 
382 \tparam Base
383 base type for the operator; i.e., this operation was recorded
384 using AD< \a Base > and computations by this routine are done using type
385 \a Base.
386 
387 \param i_z
388 is the AD variable index corresponding to the variable z.
389 
390 \param arg
391 \n
392 \a arg[0]
393 is static cast to size_t from the enum type
394 \verbatim
395  enum CompareOp {
396  CompareLt,
397  CompareLe,
398  CompareEq,
399  CompareGe,
400  CompareGt,
401  CompareNe
402  }
403 \endverbatim
404 for this operation.
405 Note that arg[0] cannot be equal to CompareNe.
406 \n
407 \n
408 \a arg[1] & 1
409 \n
410 If this is zero, y_0 is a parameter. Otherwise it is a variable.
411 \n
412 \n
413 \a arg[1] & 2
414 \n
415 If this is zero, y_1 is a parameter. Otherwise it is a variable.
416 \n
417 \n
418 \a arg[1] & 4
419 \n
420 If this is zero, y_2 is a parameter. Otherwise it is a variable.
421 \n
422 \n
423 \a arg[1] & 8
424 \n
425 If this is zero, y_3 is a parameter. Otherwise it is a variable.
426 \n
427 \n
428 \a arg[2 + j ] for j = 0, 1, 2, 3
429 \n
430 is the index corresponding to y_j.
431 
432 \param num_par
433 is the total number of values in the vector \a parameter.
434 
435 \param parameter
436 For j = 0, 1, 2, 3,
437 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
438 
439 \param cap_order
440 number of columns in the matrix containing the Taylor coefficients.
441 
442 \par Checked Assertions
443 \li NumArg(CExpOp) == 6
444 \li NumRes(CExpOp) == 1
445 \li arg[0] < static_cast<size_t> ( CompareNe )
446 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
447 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
448 <!-- end conditional_exp_op -->
449 
450 \param q
451 is order of the Taylor coefficient of z that we are computing.
452 
453 \param r
454 is the number of Taylor coefficient directions that we are computing.
455 
456 \par tpv
457 We use the notation
458 <code>tpv = (cap_order-1) * r + 1</code>
459 which is the number of Taylor coefficients per variable
460 
461 \param taylor
462 \b Input:
463 For j = 0, 1, 2, 3, k = 1, ..., q,
464 if y_j is a variable then
465 <code>taylor [ arg[2+j] * tpv + 0 ]</code>
466 is the zero order Taylor coefficient corresponding to y_j and
467 <code>taylor [ arg[2+j] * tpv + (k-1)*r+1+ell</code> is its
468 k-th order Taylor coefficient in the ell-th direction.
469 \n
470 \b Input:
471 For j = 0, 1, 2, 3, k = 1, ..., q-1,
472 <code>taylor [ i_z * tpv + 0 ]</code>
473 is the zero order Taylor coefficient corresponding to z and
474 <code>taylor [ i_z * tpv + (k-1)*r+1+ell</code> is its
475 k-th order Taylor coefficient in the ell-th direction.
476 \n
477 \b Output: <code>taylor [ i_z * tpv + (q-1)*r+1+ell ]</code>
478 is the q-th order Taylor coefficient corresponding to z
479 in the ell-th direction.
480 */
481 template <class Base>
483  size_t q ,
484  size_t r ,
485  size_t i_z ,
486  const addr_t* arg ,
487  size_t num_par ,
488  const Base* parameter ,
489  size_t cap_order ,
490  Base* taylor )
491 { Base y_0, y_1, y_2, y_3;
492  Base zero(0);
493  size_t num_taylor_per_var = (cap_order-1) * r + 1;
494  Base* z = taylor + i_z * num_taylor_per_var;
495 
496  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
499  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
500  CPPAD_ASSERT_UNKNOWN( 0 < q );
501  CPPAD_ASSERT_UNKNOWN( q < cap_order );
502 
503  if( arg[1] & 1 )
504  {
505  y_0 = taylor[ arg[2] * num_taylor_per_var + 0 ];
506  }
507  else
508  { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
509  y_0 = parameter[ arg[2] ];
510  }
511  if( arg[1] & 2 )
512  {
513  y_1 = taylor[ arg[3] * num_taylor_per_var + 0 ];
514  }
515  else
516  { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
517  y_1 = parameter[ arg[3] ];
518  }
519  size_t m = (q-1) * r + 1;
520  for(size_t ell = 0; ell < r; ell++)
521  { if( arg[1] & 4 )
522  {
523  y_2 = taylor[ arg[4] * num_taylor_per_var + m + ell];
524  }
525  else y_2 = zero;
526  if( arg[1] & 8 )
527  {
528  y_3 = taylor[ arg[5] * num_taylor_per_var + m + ell];
529  }
530  else y_3 = zero;
531  z[m+ell] = CondExpOp(
532  CompareOp( arg[0] ),
533  y_0,
534  y_1,
535  y_2,
536  y_3
537  );
538  }
539  return;
540 }
541 
542 /*!
543 Compute zero order forward mode Taylor coefficients for op = CExpOp.
544 
545 <!-- replace conditional_exp_op -->
546 The C++ source code coresponding to this operation is
547 \verbatim
548  z = CondExpRel(y_0, y_1, y_2, y_3)
549 \endverbatim
550 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
551 
552 \tparam Base
553 base type for the operator; i.e., this operation was recorded
554 using AD< \a Base > and computations by this routine are done using type
555 \a Base.
556 
557 \param i_z
558 is the AD variable index corresponding to the variable z.
559 
560 \param arg
561 \n
562 \a arg[0]
563 is static cast to size_t from the enum type
564 \verbatim
565  enum CompareOp {
566  CompareLt,
567  CompareLe,
568  CompareEq,
569  CompareGe,
570  CompareGt,
571  CompareNe
572  }
573 \endverbatim
574 for this operation.
575 Note that arg[0] cannot be equal to CompareNe.
576 \n
577 \n
578 \a arg[1] & 1
579 \n
580 If this is zero, y_0 is a parameter. Otherwise it is a variable.
581 \n
582 \n
583 \a arg[1] & 2
584 \n
585 If this is zero, y_1 is a parameter. Otherwise it is a variable.
586 \n
587 \n
588 \a arg[1] & 4
589 \n
590 If this is zero, y_2 is a parameter. Otherwise it is a variable.
591 \n
592 \n
593 \a arg[1] & 8
594 \n
595 If this is zero, y_3 is a parameter. Otherwise it is a variable.
596 \n
597 \n
598 \a arg[2 + j ] for j = 0, 1, 2, 3
599 \n
600 is the index corresponding to y_j.
601 
602 \param num_par
603 is the total number of values in the vector \a parameter.
604 
605 \param parameter
606 For j = 0, 1, 2, 3,
607 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
608 
609 \param cap_order
610 number of columns in the matrix containing the Taylor coefficients.
611 
612 \par Checked Assertions
613 \li NumArg(CExpOp) == 6
614 \li NumRes(CExpOp) == 1
615 \li arg[0] < static_cast<size_t> ( CompareNe )
616 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
617 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
618 <!-- end conditional_exp_op -->
619 
620 \param taylor
621 \b Input:
622 For j = 0, 1, 2, 3,
623 if y_j is a variable then
624 \a taylor [ \a arg[2+j] * cap_order + 0 ]
625 is the zero order Taylor coefficient corresponding to y_j.
626 \n
627 \b Output: \a taylor [ \a i_z * \a cap_order + 0 ]
628 is the zero order Taylor coefficient corresponding to z.
629 */
630 template <class Base>
631 inline void forward_cond_op_0(
632  size_t i_z ,
633  const addr_t* arg ,
634  size_t num_par ,
635  const Base* parameter ,
636  size_t cap_order ,
637  Base* taylor )
638 { Base y_0, y_1, y_2, y_3;
639  Base* z;
640 
641  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
644  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
645 
646  if( arg[1] & 1 )
647  {
648  y_0 = taylor[ arg[2] * cap_order + 0 ];
649  }
650  else
651  { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
652  y_0 = parameter[ arg[2] ];
653  }
654  if( arg[1] & 2 )
655  {
656  y_1 = taylor[ arg[3] * cap_order + 0 ];
657  }
658  else
659  { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
660  y_1 = parameter[ arg[3] ];
661  }
662  if( arg[1] & 4 )
663  {
664  y_2 = taylor[ arg[4] * cap_order + 0 ];
665  }
666  else
667  { CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < num_par );
668  y_2 = parameter[ arg[4] ];
669  }
670  if( arg[1] & 8 )
671  {
672  y_3 = taylor[ arg[5] * cap_order + 0 ];
673  }
674  else
675  { CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < num_par );
676  y_3 = parameter[ arg[5] ];
677  }
678  z = taylor + i_z * cap_order;
679  z[0] = CondExpOp(
680  CompareOp( arg[0] ),
681  y_0,
682  y_1,
683  y_2,
684  y_3
685  );
686  return;
687 }
688 
689 /*!
690 Compute reverse mode Taylor coefficients for op = CExpOp.
691 
692 This routine is given the partial derivatives of a function
693 G( z , y , x , w , ... )
694 and it uses them to compute the partial derivatives of
695 \verbatim
696  H( y , x , w , u , ... ) = G[ z(y) , y , x , w , u , ... ]
697 \endverbatim
698 where y above represents y_0, y_1, y_2, y_3.
699 
700 <!-- replace conditional_exp_op -->
701 The C++ source code coresponding to this operation is
702 \verbatim
703  z = CondExpRel(y_0, y_1, y_2, y_3)
704 \endverbatim
705 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
706 
707 \tparam Base
708 base type for the operator; i.e., this operation was recorded
709 using AD< \a Base > and computations by this routine are done using type
710 \a Base.
711 
712 \param i_z
713 is the AD variable index corresponding to the variable z.
714 
715 \param arg
716 \n
717 \a arg[0]
718 is static cast to size_t from the enum type
719 \verbatim
720  enum CompareOp {
721  CompareLt,
722  CompareLe,
723  CompareEq,
724  CompareGe,
725  CompareGt,
726  CompareNe
727  }
728 \endverbatim
729 for this operation.
730 Note that arg[0] cannot be equal to CompareNe.
731 \n
732 \n
733 \a arg[1] & 1
734 \n
735 If this is zero, y_0 is a parameter. Otherwise it is a variable.
736 \n
737 \n
738 \a arg[1] & 2
739 \n
740 If this is zero, y_1 is a parameter. Otherwise it is a variable.
741 \n
742 \n
743 \a arg[1] & 4
744 \n
745 If this is zero, y_2 is a parameter. Otherwise it is a variable.
746 \n
747 \n
748 \a arg[1] & 8
749 \n
750 If this is zero, y_3 is a parameter. Otherwise it is a variable.
751 \n
752 \n
753 \a arg[2 + j ] for j = 0, 1, 2, 3
754 \n
755 is the index corresponding to y_j.
756 
757 \param num_par
758 is the total number of values in the vector \a parameter.
759 
760 \param parameter
761 For j = 0, 1, 2, 3,
762 if y_j is a parameter, \a parameter [ arg[2 + j] ] is its value.
763 
764 \param cap_order
765 number of columns in the matrix containing the Taylor coefficients.
766 
767 \par Checked Assertions
768 \li NumArg(CExpOp) == 6
769 \li NumRes(CExpOp) == 1
770 \li arg[0] < static_cast<size_t> ( CompareNe )
771 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
772 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
773 <!-- end conditional_exp_op -->
774 
775 \param d
776 is the order of the Taylor coefficient of z that we are computing.
777 
778 \param taylor
779 \b Input:
780 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
781 if y_j is a variable then
782 \a taylor [ \a arg[2+j] * cap_order + k ]
783 is the k-th order Taylor coefficient corresponding to y_j.
784 \n
785 \a taylor [ \a i_z * \a cap_order + k ]
786 for k = 0 , ... , \a d
787 is the k-th order Taylor coefficient corresponding to z.
788 
789 \param nc_partial
790 number of columns in the matrix containing the Taylor coefficients.
791 
792 \param partial
793 \b Input:
794 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
795 if y_j is a variable then
796 \a partial [ \a arg[2+j] * nc_partial + k ]
797 is the partial derivative of G( z , y , x , w , u , ... )
798 with respect to the k-th order Taylor coefficient corresponding to y_j.
799 \n
800 \b Input: \a partial [ \a i_z * \a cap_order + k ]
801 for k = 0 , ... , \a d
802 is the partial derivative of G( z , y , x , w , u , ... )
803 with respect to the k-th order Taylor coefficient corresponding to z.
804 \n
805 \b Output:
806 For j = 0, 1, 2, 3 and k = 0 , ... , \a d,
807 if y_j is a variable then
808 \a partial [ \a arg[2+j] * nc_partial + k ]
809 is the partial derivative of H( y , x , w , u , ... )
810 with respect to the k-th order Taylor coefficient corresponding to y_j.
811 
812 */
813 template <class Base>
814 inline void reverse_cond_op(
815  size_t d ,
816  size_t i_z ,
817  const addr_t* arg ,
818  size_t num_par ,
819  const Base* parameter ,
820  size_t cap_order ,
821  const Base* taylor ,
822  size_t nc_partial ,
823  Base* partial )
824 { Base y_0, y_1;
825  Base zero(0);
826  Base* pz;
827  Base* py_2;
828  Base* py_3;
829 
830  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
833  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
834 
835  pz = partial + i_z * nc_partial + 0;
836  if( arg[1] & 1 )
837  {
838  y_0 = taylor[ arg[2] * cap_order + 0 ];
839  }
840  else
841  { CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
842  y_0 = parameter[ arg[2] ];
843  }
844  if( arg[1] & 2 )
845  {
846  y_1 = taylor[ arg[3] * cap_order + 0 ];
847  }
848  else
849  { CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < num_par );
850  y_1 = parameter[ arg[3] ];
851  }
852  if( arg[1] & 4 )
853  {
854  py_2 = partial + arg[4] * nc_partial;
855  size_t j = d + 1;
856  while(j--)
857  { py_2[j] += CondExpOp(
858  CompareOp( arg[0] ),
859  y_0,
860  y_1,
861  pz[j],
862  zero
863  );
864  }
865  }
866  if( arg[1] & 8 )
867  {
868  py_3 = partial + arg[5] * nc_partial;
869  size_t j = d + 1;
870  while(j--)
871  { py_3[j] += CondExpOp(
872  CompareOp( arg[0] ),
873  y_0,
874  y_1,
875  zero,
876  pz[j]
877  );
878  }
879  }
880  return;
881 }
882 
883 /*!
884 Compute forward Jacobian sparsity patterns for op = CExpOp.
885 
886 <!-- replace sparse_conditional_exp_op -->
887 The C++ source code coresponding to this operation is
888 \verbatim
889  z = CondExpRel(y_0, y_1, y_2, y_3)
890 \endverbatim
891 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
892 
893 \tparam Vector_set
894 is the type used for vectors of sets. It can be either
895 sparse_pack or sparse_list.
896 
897 \param i_z
898 is the AD variable index corresponding to the variable z.
899 
900 \param arg
901 \n
902 \a arg[0]
903 is static cast to size_t from the enum type
904 \verbatim
905  enum CompareOp {
906  CompareLt,
907  CompareLe,
908  CompareEq,
909  CompareGe,
910  CompareGt,
911  CompareNe
912  }
913 \endverbatim
914 for this operation.
915 Note that arg[0] cannot be equal to CompareNe.
916 \n
917 \n
918 \a arg[1] & 1
919 \n
920 If this is zero, y_0 is a parameter. Otherwise it is a variable.
921 \n
922 \n
923 \a arg[1] & 2
924 \n
925 If this is zero, y_1 is a parameter. Otherwise it is a variable.
926 \n
927 \n
928 \a arg[1] & 4
929 \n
930 If this is zero, y_2 is a parameter. Otherwise it is a variable.
931 \n
932 \n
933 \a arg[1] & 8
934 \n
935 If this is zero, y_3 is a parameter. Otherwise it is a variable.
936 \n
937 \n
938 \a arg[2 + j ] for j = 0, 1, 2, 3
939 \n
940 is the index corresponding to y_j.
941 
942 \param num_par
943 is the total number of values in the vector \a parameter.
944 
945 \par Checked Assertions
946 \li NumArg(CExpOp) == 6
947 \li NumRes(CExpOp) == 1
948 \li arg[0] < static_cast<size_t> ( CompareNe )
949 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
950 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
951 <!-- end sparse_conditional_exp_op -->
952 
953 \param dependency
954 Are the derivatives with respect to left and right of the expression below
955 considered to be non-zero:
956 \code
957  CondExpRel(left, right, if_true, if_false)
958 \endcode
959 This is used by the optimizer to obtain the correct dependency relations.
960 
961 \param sparsity
962 \b Input:
963 if y_2 is a variable, the set with index t is
964 the sparsity pattern corresponding to y_2.
965 This identifies which of the independent variables the variable y_2
966 depends on.
967 \n
968 \b Input:
969 if y_3 is a variable, the set with index t is
970 the sparsity pattern corresponding to y_3.
971 This identifies which of the independent variables the variable y_3
972 depends on.
973 \n
974 \b Output:
975 The set with index T is
976 the sparsity pattern corresponding to z.
977 This identifies which of the independent variables the variable z
978 depends on.
979 */
980 template <class Vector_set>
982  bool dependency ,
983  size_t i_z ,
984  const addr_t* arg ,
985  size_t num_par ,
986  Vector_set& sparsity )
987 {
988  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
991  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
992 # ifndef NDEBUG
993  size_t k = 1;
994  for( size_t j = 0; j < 4; j++)
995  { if( ! ( arg[1] & k ) )
996  CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
997  k *= 2;
998  }
999 # endif
1000  sparsity.clear(i_z);
1001  if( dependency )
1002  { if( arg[1] & 1 )
1003  sparsity.binary_union(i_z, i_z, arg[2], sparsity);
1004  if( arg[1] & 2 )
1005  sparsity.binary_union(i_z, i_z, arg[3], sparsity);
1006  }
1007  if( arg[1] & 4 )
1008  sparsity.binary_union(i_z, i_z, arg[4], sparsity);
1009  if( arg[1] & 8 )
1010  sparsity.binary_union(i_z, i_z, arg[5], sparsity);
1011  return;
1012 }
1013 
1014 /*!
1015 Compute reverse Jacobian sparsity patterns for op = CExpOp.
1016 
1017 This routine is given the sparsity patterns
1018 for a function G(z, y, x, ... )
1019 and it uses them to compute the sparsity patterns for
1020 \verbatim
1021  H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
1022 \endverbatim
1023 where y represents the combination of y_0, y_1, y_2, and y_3.
1024 
1025 <!-- replace sparse_conditional_exp_op -->
1026 The C++ source code coresponding to this operation is
1027 \verbatim
1028  z = CondExpRel(y_0, y_1, y_2, y_3)
1029 \endverbatim
1030 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
1031 
1032 \tparam Vector_set
1033 is the type used for vectors of sets. It can be either
1034 sparse_pack or sparse_list.
1035 
1036 \param i_z
1037 is the AD variable index corresponding to the variable z.
1038 
1039 \param arg
1040 \n
1041 \a arg[0]
1042 is static cast to size_t from the enum type
1043 \verbatim
1044  enum CompareOp {
1045  CompareLt,
1046  CompareLe,
1047  CompareEq,
1048  CompareGe,
1049  CompareGt,
1050  CompareNe
1051  }
1052 \endverbatim
1053 for this operation.
1054 Note that arg[0] cannot be equal to CompareNe.
1055 \n
1056 \n
1057 \a arg[1] & 1
1058 \n
1059 If this is zero, y_0 is a parameter. Otherwise it is a variable.
1060 \n
1061 \n
1062 \a arg[1] & 2
1063 \n
1064 If this is zero, y_1 is a parameter. Otherwise it is a variable.
1065 \n
1066 \n
1067 \a arg[1] & 4
1068 \n
1069 If this is zero, y_2 is a parameter. Otherwise it is a variable.
1070 \n
1071 \n
1072 \a arg[1] & 8
1073 \n
1074 If this is zero, y_3 is a parameter. Otherwise it is a variable.
1075 \n
1076 \n
1077 \a arg[2 + j ] for j = 0, 1, 2, 3
1078 \n
1079 is the index corresponding to y_j.
1080 
1081 \param num_par
1082 is the total number of values in the vector \a parameter.
1083 
1084 \par Checked Assertions
1085 \li NumArg(CExpOp) == 6
1086 \li NumRes(CExpOp) == 1
1087 \li arg[0] < static_cast<size_t> ( CompareNe )
1088 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
1089 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
1090 <!-- end sparse_conditional_exp_op -->
1091 
1092 \param dependency
1093 Are the derivatives with respect to left and right of the expression below
1094 considered to be non-zero:
1095 \code
1096  CondExpRel(left, right, if_true, if_false)
1097 \endcode
1098 This is used by the optimizer to obtain the correct dependency relations.
1099 
1100 
1101 \param sparsity
1102 if y_2 is a variable, the set with index t is
1103 the sparsity pattern corresponding to y_2.
1104 This identifies which of the dependent variables depend on the variable y_2.
1105 On input, this pattern corresponds to the function G.
1106 On ouput, it corresponds to the function H.
1107 \n
1108 \n
1109 if y_3 is a variable, the set with index t is
1110 the sparsity pattern corresponding to y_3.
1111 This identifies which of the dependent variables depeond on the variable y_3.
1112 On input, this pattern corresponds to the function G.
1113 On ouput, it corresponds to the function H.
1114 \n
1115 \b Output:
1116 The set with index T is
1117 the sparsity pattern corresponding to z.
1118 This identifies which of the dependent variables depend on the variable z.
1119 On input and output, this pattern corresponds to the function G.
1120 */
1121 template <class Vector_set>
1123  bool dependency ,
1124  size_t i_z ,
1125  const addr_t* arg ,
1126  size_t num_par ,
1127  Vector_set& sparsity )
1128 {
1129  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
1132  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
1133 # ifndef NDEBUG
1134  size_t k = 1;
1135  for( size_t j = 0; j < 4; j++)
1136  { if( ! ( arg[1] & k ) )
1137  CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
1138  k *= 2;
1139  }
1140 # endif
1141  if( dependency )
1142  { if( arg[1] & 1 )
1143  sparsity.binary_union(arg[2], arg[2], i_z, sparsity);
1144  if( arg[1] & 2 )
1145  sparsity.binary_union(arg[3], arg[3], i_z, sparsity);
1146  }
1147  // --------------------------------------------------------------------
1148  if( arg[1] & 4 )
1149  sparsity.binary_union(arg[4], arg[4], i_z, sparsity);
1150  if( arg[1] & 8 )
1151  sparsity.binary_union(arg[5], arg[5], i_z, sparsity);
1152  return;
1153 }
1154 
1155 /*!
1156 Compute reverse Hessian sparsity patterns for op = CExpOp.
1157 
1158 This routine is given the sparsity patterns
1159 for a function G(z, y, x, ... )
1160 and it uses them to compute the sparsity patterns for
1161 \verbatim
1162  H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
1163 \endverbatim
1164 where y represents the combination of y_0, y_1, y_2, and y_3.
1165 
1166 <!-- replace sparse_conditional_exp_op -->
1167 The C++ source code coresponding to this operation is
1168 \verbatim
1169  z = CondExpRel(y_0, y_1, y_2, y_3)
1170 \endverbatim
1171 where Rel is one of the following: Lt, Le, Eq, Ge, Gt.
1172 
1173 \tparam Vector_set
1174 is the type used for vectors of sets. It can be either
1175 sparse_pack or sparse_list.
1176 
1177 \param i_z
1178 is the AD variable index corresponding to the variable z.
1179 
1180 \param arg
1181 \n
1182 \a arg[0]
1183 is static cast to size_t from the enum type
1184 \verbatim
1185  enum CompareOp {
1186  CompareLt,
1187  CompareLe,
1188  CompareEq,
1189  CompareGe,
1190  CompareGt,
1191  CompareNe
1192  }
1193 \endverbatim
1194 for this operation.
1195 Note that arg[0] cannot be equal to CompareNe.
1196 \n
1197 \n
1198 \a arg[1] & 1
1199 \n
1200 If this is zero, y_0 is a parameter. Otherwise it is a variable.
1201 \n
1202 \n
1203 \a arg[1] & 2
1204 \n
1205 If this is zero, y_1 is a parameter. Otherwise it is a variable.
1206 \n
1207 \n
1208 \a arg[1] & 4
1209 \n
1210 If this is zero, y_2 is a parameter. Otherwise it is a variable.
1211 \n
1212 \n
1213 \a arg[1] & 8
1214 \n
1215 If this is zero, y_3 is a parameter. Otherwise it is a variable.
1216 \n
1217 \n
1218 \a arg[2 + j ] for j = 0, 1, 2, 3
1219 \n
1220 is the index corresponding to y_j.
1221 
1222 \param num_par
1223 is the total number of values in the vector \a parameter.
1224 
1225 \par Checked Assertions
1226 \li NumArg(CExpOp) == 6
1227 \li NumRes(CExpOp) == 1
1228 \li arg[0] < static_cast<size_t> ( CompareNe )
1229 \li arg[1] != 0; i.e., not all of y_0, y_1, y_2, y_3 are parameters.
1230 \li For j = 0, 1, 2, 3 if y_j is a parameter, arg[2+j] < num_par.
1231 <!-- end sparse_conditional_exp_op -->
1232 
1233 
1234 \param jac_reverse
1235 \a jac_reverse[i_z]
1236 is false (true) if the Jacobian of G with respect to z is always zero
1237 (may be non-zero).
1238 \n
1239 \n
1240 \a jac_reverse[ arg[4] ]
1241 If y_2 is a variable,
1242 \a jac_reverse[ arg[4] ]
1243 is false (true) if the Jacobian with respect to y_2 is always zero
1244 (may be non-zero).
1245 On input, it corresponds to the function G,
1246 and on output it corresponds to the function H.
1247 \n
1248 \n
1249 \a jac_reverse[ arg[5] ]
1250 If y_3 is a variable,
1251 \a jac_reverse[ arg[5] ]
1252 is false (true) if the Jacobian with respect to y_3 is always zero
1253 (may be non-zero).
1254 On input, it corresponds to the function G,
1255 and on output it corresponds to the function H.
1256 
1257 \param hes_sparsity
1258 The set with index \a i_z in \a hes_sparsity
1259 is the Hessian sparsity pattern for the function G
1260 where one of the partials is with respect to z.
1261 \n
1262 \n
1263 If y_2 is a variable,
1264 the set with index \a arg[4] in \a hes_sparsity
1265 is the Hessian sparsity pattern
1266 where one of the partials is with respect to y_2.
1267 On input, this pattern corresponds to the function G.
1268 On output, this pattern corresponds to the function H.
1269 \n
1270 \n
1271 If y_3 is a variable,
1272 the set with index \a arg[5] in \a hes_sparsity
1273 is the Hessian sparsity pattern
1274 where one of the partials is with respect to y_3.
1275 On input, this pattern corresponds to the function G.
1276 On output, this pattern corresponds to the function H.
1277 */
1278 template <class Vector_set>
1280  size_t i_z ,
1281  const addr_t* arg ,
1282  size_t num_par ,
1283  bool* jac_reverse ,
1284  Vector_set& hes_sparsity )
1285 {
1286 
1287  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < static_cast<size_t> (CompareNe) );
1290  CPPAD_ASSERT_UNKNOWN( arg[1] != 0 );
1291 # ifndef NDEBUG
1292  size_t k = 1;
1293  for( size_t j = 0; j < 4; j++)
1294  { if( ! ( arg[1] & k ) )
1295  CPPAD_ASSERT_UNKNOWN( size_t(arg[2+j]) < num_par );
1296  k *= 2;
1297  }
1298 # endif
1299  if( arg[1] & 4 )
1300  {
1301  hes_sparsity.binary_union(arg[4], arg[4], i_z, hes_sparsity);
1302  jac_reverse[ arg[4] ] |= jac_reverse[i_z];
1303  }
1304  if( arg[1] & 8 )
1305  {
1306  hes_sparsity.binary_union(arg[5], arg[5], i_z, hes_sparsity);
1307  jac_reverse[ arg[5] ] |= jac_reverse[i_z];
1308  }
1309  return;
1310 }
1311 
1312 } } // END_CPPAD_LOCAL_NAMESPACE
1313 # endif
void forward_sparse_jacobian_cond_op(bool dependency, size_t i_z, const addr_t *arg, size_t num_par, Vector_set &sparsity)
Compute forward Jacobian sparsity patterns for op = CExpOp.
Definition: cond_op.hpp:981
void reverse_sparse_jacobian_cond_op(bool dependency, size_t i_z, const addr_t *arg, size_t num_par, Vector_set &sparsity)
Compute reverse Jacobian sparsity patterns for op = CExpOp.
Definition: cond_op.hpp:1122
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
void sparse_conditional_exp_op(size_t i_z, const addr_t *arg, size_t num_par)
Shared documentation for conditional expression sparse operations (not called).
Definition: cond_op.hpp:181
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
void forward_cond_op(size_t p, size_t q, size_t i_z, const addr_t *arg, size_t num_par, const Base *parameter, size_t cap_order, Base *taylor)
Compute forward mode Taylor coefficients for op = CExpOp.
Definition: cond_op.hpp:290
void reverse_sparse_hessian_cond_op(size_t i_z, const addr_t *arg, size_t num_par, bool *jac_reverse, Vector_set &hes_sparsity)
Compute reverse Hessian sparsity patterns for op = CExpOp.
Definition: cond_op.hpp:1279
void forward_cond_op_0(size_t i_z, const addr_t *arg, size_t num_par, const Base *parameter, size_t cap_order, Base *taylor)
Compute zero order forward mode Taylor coefficients for op = CExpOp.
Definition: cond_op.hpp:631
void conditional_exp_op(size_t i_z, const addr_t *arg, size_t num_par, const Base *parameter, size_t cap_order)
Shared documentation for conditional expressions (not called).
Definition: cond_op.hpp:100
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void forward_cond_op_dir(size_t q, size_t r, size_t i_z, const addr_t *arg, size_t num_par, const Base *parameter, size_t cap_order, Base *taylor)
Multiple directions forward mode Taylor coefficients for op = CExpOp.
Definition: cond_op.hpp:482
std::complex< double > CondExpOp(enum CppAD::CompareOp cop, const std::complex< double > &left, const std::complex< double > &right, const std::complex< double > &trueCase, const std::complex< double > &falseCase)
void reverse_cond_op(size_t d, size_t i_z, const addr_t *arg, size_t num_par, const Base *parameter, size_t cap_order, const Base *taylor, size_t nc_partial, Base *partial)
Compute reverse mode Taylor coefficients for op = CExpOp.
Definition: cond_op.hpp:814