1 # ifndef CPPAD_LOCAL_SWEEP_FORWARD1_HPP
2 # define CPPAD_LOCAL_SWEEP_FORWARD1_HPP
3 /* --------------------------------------------------------------------------
4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-20 Bradley M. Bell
5
6 CppAD is distributed under the terms of the
7 Eclipse Public License Version 2.0.
8
9 This Source Code may also be made available under the following
10 Secondary License when the conditions for such availability set forth
11 in the Eclipse Public License, Version 2.0 are satisfied:
12 GNU General Public License, Version 2.0 or later.
13 ---------------------------------------------------------------------------- */
14
15 # include <cppad/local/play/atom_op_info.hpp>
16 # include <cppad/local/sweep/call_atomic.hpp>
17
18 // BEGIN_CPPAD_LOCAL_SWEEP_NAMESPACE
19 namespace CppAD { namespace local { namespace sweep {
20 /*!
21 \file sweep/forward1.hpp
22 Compute one Taylor coefficient for each order requested.
23 */
24
25 /*!
26 \def CPPAD_FORWARD1_TRACE
27 This value is either zero or one.
28 Zero is the normal operational value.
29 If it is one, a trace of every forward1sweep computation is printed.
30 */
31 # define CPPAD_FORWARD1_TRACE 0
32
33 /*!
34 Compute arbitrary order forward mode Taylor coefficients.
35
36 <!-- replace forward0_doc_define -->
37 \tparam Base
38 The type used during the forward mode computations; i.e., the corresponding
39 recording of operations used the type AD<Base>.
40
41 \param s_out
42 Is the stream where output corresponding to PriOp operations will
43 be written.
44
45 \param print
46 If print is false,
47 suppress the output that is otherwise generated by the c PriOp instructions.
48
49 \param n
50 is the number of independent variables on the tape.
51
52 \param numvar
53 is the total number of variables on the tape.
54 This is also equal to the number of rows in the matrix taylor; i.e.,
55 play->num_var_rec().
56
57 \param play
58 The information stored in play
59 is a recording of the operations corresponding to the function
60 \f[
61 F : {\bf R}^n \rightarrow {\bf R}^m
62 \f]
63 where \f$ n \f$ is the number of independent variables and
64 \f$ m \f$ is the number of dependent variables.
65
66 \param J
67 Is the number of columns in the coefficient matrix taylor.
68 This must be greater than or equal one.
69
70 <!-- end forward0_doc_define -->
71
72 \param cskip_op
73 Is a vector with size play->num_op_rec().
74 \n
75 \n
76 <tt>p = 0</tt>
77 \n
78 In this case,
79 the input value of the elements does not matter.
80 Upon return, if cskip_op[i] is true, the operator with index i
81 does not affect any of the dependent variable
82 (given the value of the independent variables).
83 \n
84 \n
85 <tt>p > 0</tt>
86 \n
87 In this case cskip_op is not modified and has the same meaning
88 as its return value above.
89
90 \param load_op2var
91 is a vector with size play->num_var_load_rec().
92 \n
93 \n
94 <tt>p == 0</tt>
95 \n
96 In this case,
97 The input value of the elements does not matter.
98 Upon return,
99 it is the variable index corresponding the result for each load operator.
100 In the case where the index is zero,
101 the load operator results in a parameter (not a variable).
102 Note that the is no variable with index zero on the tape.
103 \n
104 \n
105 <tt>p > 0</tt>
106 \n
107 In this case load_op2var is not modified and has the meaning
108 as its return value above.
109
110 \param p
111 is the lowest order of the Taylor coefficients
112 that are computed during this call.
113
114 \param q
115 is the highest order of the Taylor coefficients
116 that are computed during this call.
117
118 \param taylor
119 \n
120 \b Input:
121 For <code>i = 1 , ... , numvar-1</code>,
122 <code>k = 0 , ... , p-1</code>,
123 <code>taylor[ J*i + k]</code>
124 is the k-th order Taylor coefficient corresponding to
125 the i-th variable.
126 \n
127 \n
128 \b Input:
129 For <code>i = 1 , ... , n</code>,
130 <code>k = p , ... , q</code>,
131 <code>taylor[ J*j + k]</code>
132 is the k-th order Taylor coefficient corresponding to
133 the i-th variable
134 (these are the independent varaibles).
135 \n
136 \n
137 \b Output:
138 For <code>i = n+1 , ... , numvar-1</code>, and
139 <code>k = 0 , ... , p-1</code>,
140 <code>taylor[ J*i + k]</code>
141 is the k-th order Taylor coefficient corresponding to
142 the i-th variable.
143
144
145 \param compare_change_count
146 Is the count value for changing number and op_index during
147 zero order foward mode.
148
149 \param compare_change_number
150 If p is non-zero, this value is not changed, otherwise:
151 If compare_change_count is zero, this value is set to zero, otherwise:
152 this value is set to the number of comparison operations
153 that have a different result from when the information in
154 play was recorded.
155
156 \param compare_change_op_index
157 if p is non-zero, this value is not changed, otherwise:
158 If compare_change_count is zero, this value is set to zero.
159 Otherwise it is the operator index (see forward_next) for the count-th
160 comparison operation that has a different result from when the information in
161 play was recorded.
162
163 \param not_used_rec_base
164 Specifies RecBase for this call.
165 */
166
167 template <class Addr, class Base, class RecBase>
forward1(const local::player<Base> * play,std::ostream & s_out,const bool print,const size_t p,const size_t q,const size_t n,const size_t numvar,const size_t J,Base * taylor,bool * cskip_op,pod_vector<Addr> & load_op2var,size_t compare_change_count,size_t & compare_change_number,size_t & compare_change_op_index,const RecBase & not_used_rec_base)168 void forward1(
169 const local::player<Base>* play,
170 std::ostream& s_out,
171 const bool print,
172 const size_t p,
173 const size_t q,
174 const size_t n,
175 const size_t numvar,
176 const size_t J,
177 Base* taylor,
178 bool* cskip_op,
179 pod_vector<Addr>& load_op2var,
180 size_t compare_change_count,
181 size_t& compare_change_number,
182 size_t& compare_change_op_index,
183 const RecBase& not_used_rec_base
184 )
185 {
186 // number of directions
187 const size_t r = 1;
188
189 CPPAD_ASSERT_UNKNOWN( p <= q );
190 CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
191 CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
192
193 /*
194 <!-- replace forward0sweep_code_define -->
195 */
196
197 // initialize the comparison operator counter
198 if( p == 0 )
199 { compare_change_number = 0;
200 compare_change_op_index = 0;
201 }
202
203 // If this includes a zero calculation, initialize this information
204 pod_vector<bool> vec_ad2isvar;
205 pod_vector<size_t> vec_ad2index;
206 if( p == 0 )
207 { size_t i;
208
209 // this includes order zero calculation, initialize vector indices
210 size_t num = play->num_var_vecad_ind_rec();
211 if( num > 0 )
212 { vec_ad2isvar.extend(num);
213 vec_ad2index.extend(num);
214 for(i = 0; i < num; i++)
215 { vec_ad2index[i] = play->GetVecInd(i);
216 vec_ad2isvar[i] = false;
217 }
218 }
219 // includes zero order, so initialize conditional skip flags
220 num = play->num_op_rec();
221 for(i = 0; i < num; i++)
222 cskip_op[i] = false;
223 }
224
225 // information used by atomic function operators
226 const pod_vector<bool>& dyn_par_is( play->dyn_par_is() );
227 const size_t need_y = size_t( variable_enum );
228 const size_t order_low = p;
229 const size_t order_up = q;
230
231 // vectors used by atomic function operators
232 vector<Base> atom_par_x; // argument parameter values
233 vector<ad_type_enum> atom_type_x; // argument type
234 vector<Base> atom_tx; // argument vector Taylor coefficients
235 vector<Base> atom_ty; // result vector Taylor coefficients
236 //
237 // information defined by atomic function operators
238 size_t atom_index=0, atom_old=0, atom_m=0, atom_n=0, atom_i=0, atom_j=0;
239 enum_atom_state atom_state = start_atom; // proper initialization
240
241 // length of the parameter vector (used by CppAD assert macros)
242 const size_t num_par = play->num_par_rec();
243
244 // pointer to the beginning of the parameter vector
245 CPPAD_ASSERT_UNKNOWN( num_par > 0 )
246 const Base* parameter = play->GetPar();
247
248 // length of the text vector (used by CppAD assert macros)
249 const size_t num_text = play->num_text_rec();
250
251 // pointer to the beginning of the text vector
252 const char* text = nullptr;
253 if( num_text > 0 )
254 text = play->GetTxt(0);
255 /*
256 <!-- end forward0sweep_code_define -->
257 */
258 // temporary indices
259 size_t i, k;
260
261 // number of orders for this atomic calculation
262 // (not needed for order zero)
263 const size_t atom_q1 = q+1;
264
265 // variable indices for results vector
266 // (done differently for order zero).
267 vector<size_t> atom_iy;
268
269 // skip the BeginOp at the beginning of the recording
270 play::const_sequential_iterator itr = play->begin();
271 // op_info
272 OpCode op;
273 size_t i_var;
274 const Addr* arg;
275 itr.op_info(op, arg, i_var);
276 CPPAD_ASSERT_UNKNOWN( op == BeginOp );
277 //
278 # if CPPAD_FORWARD1_TRACE
279 bool atom_trace = false;
280 std::cout << std::endl;
281 # endif
282 //
283 bool flag; // a temporary flag to use in switch cases
284 bool more_operators = true;
285 while(more_operators)
286 {
287 // next op
288 (++itr).op_info(op, arg, i_var);
289 CPPAD_ASSERT_UNKNOWN( itr.op_index() < play->num_op_rec() );
290
291 // check if we are skipping this operation
292 while( cskip_op[itr.op_index()] )
293 { switch(op)
294 {
295 case AFunOp:
296 { // get information for this atomic function call
297 CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );
298 play::atom_op_info<Base>(
299 op, arg, atom_index, atom_old, atom_m, atom_n
300 );
301 //
302 // skip to the second AFunOp
303 for(i = 0; i < atom_m + atom_n + 1; ++i)
304 ++itr;
305 # ifndef NDEBUG
306 itr.op_info(op, arg, i_var);
307 CPPAD_ASSERT_UNKNOWN( op == AFunOp );
308 # endif
309 }
310 break;
311
312 case CSkipOp:
313 case CSumOp:
314 itr.correct_before_increment();
315 break;
316
317 default:
318 break;
319 }
320 (++itr).op_info(op, arg, i_var);
321 }
322
323 // action depends on the operator
324 switch( op )
325 {
326 case AbsOp:
327 forward_abs_op(p, q, i_var, size_t(arg[0]), J, taylor);
328 break;
329 // -------------------------------------------------
330
331 case AddvvOp:
332 forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);
333 break;
334 // -------------------------------------------------
335
336 case AddpvOp:
337 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
338 forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);
339 break;
340 // -------------------------------------------------
341
342 case AcosOp:
343 // sqrt(1 - x * x), acos(x)
344 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
345 forward_acos_op(p, q, i_var, size_t(arg[0]), J, taylor);
346 break;
347 // -------------------------------------------------
348
349 case AcoshOp:
350 // sqrt(x * x - 1), acosh(x)
351 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
352 forward_acosh_op(p, q, i_var, size_t(arg[0]), J, taylor);
353 break;
354 // -------------------------------------------------
355
356 case AsinOp:
357 // sqrt(1 - x * x), asin(x)
358 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
359 forward_asin_op(p, q, i_var, size_t(arg[0]), J, taylor);
360 break;
361 // -------------------------------------------------
362
363 case AsinhOp:
364 // sqrt(1 + x * x), asinh(x)
365 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
366 forward_asinh_op(p, q, i_var, size_t(arg[0]), J, taylor);
367 break;
368 // -------------------------------------------------
369
370 case AtanOp:
371 // 1 + x * x, atan(x)
372 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
373 forward_atan_op(p, q, i_var, size_t(arg[0]), J, taylor);
374 break;
375 // -------------------------------------------------
376
377 case AtanhOp:
378 // 1 - x * x, atanh(x)
379 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
380 forward_atanh_op(p, q, i_var, size_t(arg[0]), J, taylor);
381 break;
382 // -------------------------------------------------
383
384 case CExpOp:
385 forward_cond_op(
386 p, q, i_var, arg, num_par, parameter, J, taylor
387 );
388 break;
389 // ---------------------------------------------------
390
391 case CosOp:
392 // sin(x), cos(x)
393 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
394 forward_cos_op(p, q, i_var, size_t(arg[0]), J, taylor);
395 break;
396 // ---------------------------------------------------
397
398 case CoshOp:
399 // sinh(x), cosh(x)
400 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
401 forward_cosh_op(p, q, i_var, size_t(arg[0]), J, taylor);
402 break;
403 // -------------------------------------------------
404
405 case CSkipOp:
406 if( p == 0 )
407 { forward_cskip_op_0(
408 i_var, arg, num_par, parameter, J, taylor, cskip_op
409 );
410 }
411 itr.correct_before_increment();
412 break;
413 // -------------------------------------------------
414
415 case CSumOp:
416 forward_csum_op(
417 p, q, i_var, arg, num_par, parameter, J, taylor
418 );
419 itr.correct_before_increment();
420 break;
421 // -------------------------------------------------
422
423 case DisOp:
424 forward_dis_op(p, q, r, i_var, arg, J, taylor);
425 break;
426 // -------------------------------------------------
427
428 case DivvvOp:
429 forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);
430 break;
431 // -------------------------------------------------
432
433 case DivpvOp:
434 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
435 forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);
436 break;
437 // -------------------------------------------------
438
439 case DivvpOp:
440 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
441 forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);
442 break;
443 // -------------------------------------------------
444
445 case EndOp:
446 CPPAD_ASSERT_NARG_NRES(op, 0, 0);
447 more_operators = false;
448 break;
449 // -------------------------------------------------
450
451 case EqppOp:
452 if( compare_change_count )
453 { forward_eqpp_op_0(
454 compare_change_number, arg, parameter
455 );
456 { if( compare_change_count == compare_change_number )
457 compare_change_op_index = itr.op_index();
458 }
459 }
460 break;
461 // -------------------------------------------------
462
463 case EqpvOp:
464 if( ( p == 0 ) & ( compare_change_count > 0 ) )
465 { forward_eqpv_op_0(
466 compare_change_number, arg, parameter, J, taylor
467 );
468 if( compare_change_count == compare_change_number )
469 compare_change_op_index = itr.op_index();
470 }
471 break;
472 // -------------------------------------------------
473
474 case EqvvOp:
475 if( ( p == 0 ) & ( compare_change_count > 0 ) )
476 { forward_eqvv_op_0(
477 compare_change_number, arg, parameter, J, taylor
478 );
479 if( compare_change_count == compare_change_number )
480 compare_change_op_index = itr.op_index();
481 }
482 break;
483 // -------------------------------------------------
484
485 case ErfOp:
486 case ErfcOp:
487 forward_erf_op(op, p, q, i_var, arg, parameter, J, taylor);
488 break;
489 // -------------------------------------------------
490
491 case ExpOp:
492 forward_exp_op(p, q, i_var, size_t(arg[0]), J, taylor);
493 break;
494 // ---------------------------------------------------
495
496 case Expm1Op:
497 forward_expm1_op(p, q, i_var, size_t(arg[0]), J, taylor);
498 break;
499 // ---------------------------------------------------
500
501 case InvOp:
502 CPPAD_ASSERT_NARG_NRES(op, 0, 1);
503 break;
504 // -------------------------------------------------
505
506 case LdpOp:
507 if( p == 0 )
508 { forward_load_p_op_0(
509 play,
510 i_var,
511 arg,
512 parameter,
513 J,
514 taylor,
515 vec_ad2isvar.data(),
516 vec_ad2index.data(),
517 load_op2var.data()
518 );
519 if( p < q ) forward_load_op(
520 play,
521 op,
522 p+1,
523 q,
524 r,
525 J,
526 i_var,
527 arg,
528 load_op2var.data(),
529 taylor
530 );
531 }
532 else
533 forward_load_op(
534 play,
535 op,
536 p,
537 q,
538 r,
539 J,
540 i_var,
541 arg,
542 load_op2var.data(),
543 taylor
544 );
545 break;
546 // -------------------------------------------------
547
548 case LdvOp:
549 if( p == 0 )
550 { forward_load_v_op_0(
551 play,
552 i_var,
553 arg,
554 parameter,
555 J,
556 taylor,
557 vec_ad2isvar.data(),
558 vec_ad2index.data(),
559 load_op2var.data()
560 );
561 if( p < q ) forward_load_op(
562 play,
563 op,
564 p+1,
565 q,
566 r,
567 J,
568 i_var,
569 arg,
570 load_op2var.data(),
571 taylor
572 );
573 }
574 else
575 forward_load_op(
576 play,
577 op,
578 p,
579 q,
580 r,
581 J,
582 i_var,
583 arg,
584 load_op2var.data(),
585 taylor
586 );
587 break;
588 // -------------------------------------------------
589
590 case LeppOp:
591 if( ( p == 0 ) & ( compare_change_count > 0 ) )
592 { forward_lepp_op_0(
593 compare_change_number, arg, parameter
594 );
595 if( compare_change_count == compare_change_number )
596 compare_change_op_index = itr.op_index();
597 }
598 break;
599 // -------------------------------------------------
600
601 case LepvOp:
602 if( ( p == 0 ) & ( compare_change_count > 0 ) )
603 { forward_lepv_op_0(
604 compare_change_number, arg, parameter, J, taylor
605 );
606 if( compare_change_count == compare_change_number )
607 compare_change_op_index = itr.op_index();
608 }
609 break;
610 // -------------------------------------------------
611
612 case LevpOp:
613 if( ( p == 0 ) & ( compare_change_count > 0 ) )
614 { forward_levp_op_0(
615 compare_change_number, arg, parameter, J, taylor
616 );
617 if( compare_change_count == compare_change_number )
618 compare_change_op_index = itr.op_index();
619 }
620 break;
621 // -------------------------------------------------
622
623 case LevvOp:
624 if( ( p == 0 ) & ( compare_change_count > 0 ) )
625 { forward_levv_op_0(
626 compare_change_number, arg, parameter, J, taylor
627 );
628 if( compare_change_count == compare_change_number )
629 compare_change_op_index = itr.op_index();
630 }
631 break;
632 // -------------------------------------------------
633
634 case LogOp:
635 forward_log_op(p, q, i_var, size_t(arg[0]), J, taylor);
636 break;
637 // -------------------------------------------------
638
639 case Log1pOp:
640 forward_log1p_op(p, q, i_var, size_t(arg[0]), J, taylor);
641 break;
642 // -------------------------------------------------
643
644 case LtppOp:
645 if( ( p == 0 ) & ( compare_change_count > 0 ) )
646 { forward_ltpp_op_0(
647 compare_change_number, arg, parameter
648 );
649 if( compare_change_count == compare_change_number )
650 compare_change_op_index = itr.op_index();
651 }
652 break;
653 // -------------------------------------------------
654
655 case LtpvOp:
656 if( ( p == 0 ) & ( compare_change_count > 0 ) )
657 { forward_ltpv_op_0(
658 compare_change_number, arg, parameter, J, taylor
659 );
660 if( compare_change_count == compare_change_number )
661 compare_change_op_index = itr.op_index();
662 }
663 break;
664 // -------------------------------------------------
665
666 case LtvpOp:
667 if( ( p == 0 ) & ( compare_change_count > 0 ) )
668 { forward_ltvp_op_0(
669 compare_change_number, arg, parameter, J, taylor
670 );
671 if( compare_change_count == compare_change_number )
672 compare_change_op_index = itr.op_index();
673 }
674 break;
675 // -------------------------------------------------
676
677 case LtvvOp:
678 if( ( p == 0 ) & ( compare_change_count > 0 ) )
679 { forward_ltvv_op_0(
680 compare_change_number, arg, parameter, J, taylor
681 );
682 if( compare_change_count == compare_change_number )
683 compare_change_op_index = itr.op_index();
684 }
685 break;
686 // -------------------------------------------------
687
688 case MulpvOp:
689 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
690 forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
691 break;
692 // -------------------------------------------------
693
694 case MulvvOp:
695 forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
696 break;
697 // -------------------------------------------------
698
699 case NeppOp:
700 if( compare_change_count )
701 { forward_nepp_op_0(
702 compare_change_number, arg, parameter
703 );
704 { if( compare_change_count == compare_change_number )
705 compare_change_op_index = itr.op_index();
706 }
707 }
708 break;
709 // -------------------------------------------------
710
711 case NepvOp:
712 if( ( p == 0 ) & ( compare_change_count > 0 ) )
713 { forward_nepv_op_0(
714 compare_change_number, arg, parameter, J, taylor
715 );
716 if( compare_change_count == compare_change_number )
717 compare_change_op_index = itr.op_index();
718 }
719 break;
720 // -------------------------------------------------
721
722 case NevvOp:
723 if( ( p == 0 ) & ( compare_change_count > 0 ) )
724 { forward_nevv_op_0(
725 compare_change_number, arg, parameter, J, taylor
726 );
727 if( compare_change_count == compare_change_number )
728 compare_change_op_index = itr.op_index();
729 }
730 break;
731 // -------------------------------------------------
732
733 case ParOp:
734 i = p;
735 if( i == 0 )
736 { forward_par_op_0(
737 i_var, arg, num_par, parameter, J, taylor
738 );
739 i++;
740 }
741 while(i <= q)
742 { taylor[ i_var * J + i] = Base(0.0);
743 i++;
744 }
745 break;
746 // -------------------------------------------------
747
748 case PowvpOp:
749 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
750 forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
751 break;
752 // -------------------------------------------------
753
754 case PowpvOp:
755 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
756 forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
757 break;
758 // -------------------------------------------------
759
760 case PowvvOp:
761 forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
762 break;
763 // -------------------------------------------------
764
765 case PriOp:
766 if( (p == 0) & print ) forward_pri_0(s_out,
767 arg, num_text, text, num_par, parameter, J, taylor
768 );
769 break;
770 // -------------------------------------------------
771
772 case SignOp:
773 // sign(x)
774 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
775 forward_sign_op(p, q, i_var, size_t(arg[0]), J, taylor);
776 break;
777 // -------------------------------------------------
778
779 case SinOp:
780 // cos(x), sin(x)
781 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
782 forward_sin_op(p, q, i_var, size_t(arg[0]), J, taylor);
783 break;
784 // -------------------------------------------------
785
786 case SinhOp:
787 // cosh(x), sinh(x)
788 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
789 forward_sinh_op(p, q, i_var, size_t(arg[0]), J, taylor);
790 break;
791 // -------------------------------------------------
792
793 case SqrtOp:
794 forward_sqrt_op(p, q, i_var, size_t(arg[0]), J, taylor);
795 break;
796 // -------------------------------------------------
797
798 case StppOp:
799 if( p == 0 )
800 { forward_store_pp_op_0(
801 i_var,
802 arg,
803 num_par,
804 parameter,
805 J,
806 taylor,
807 vec_ad2isvar.data(),
808 vec_ad2index.data()
809 );
810 }
811 break;
812 // -------------------------------------------------
813
814 case StpvOp:
815 if( p == 0 )
816 { forward_store_pv_op_0(
817 i_var,
818 arg,
819 num_par,
820 parameter,
821 J,
822 taylor,
823 vec_ad2isvar.data(),
824 vec_ad2index.data()
825 );
826 }
827 break;
828 // -------------------------------------------------
829
830 case StvpOp:
831 if( p == 0 )
832 { forward_store_vp_op_0(
833 i_var,
834 arg,
835 num_par,
836 J,
837 taylor,
838 vec_ad2isvar.data(),
839 vec_ad2index.data()
840 );
841 }
842 break;
843 // -------------------------------------------------
844
845 case StvvOp:
846 if( p == 0 )
847 { forward_store_vv_op_0(
848 i_var,
849 arg,
850 num_par,
851 J,
852 taylor,
853 vec_ad2isvar.data(),
854 vec_ad2index.data()
855 );
856 }
857 break;
858 // -------------------------------------------------
859
860 case SubvvOp:
861 forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
862 break;
863 // -------------------------------------------------
864
865 case SubpvOp:
866 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
867 forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
868 break;
869 // -------------------------------------------------
870
871 case SubvpOp:
872 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
873 forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
874 break;
875 // -------------------------------------------------
876
877 case TanOp:
878 // tan(x)^2, tan(x)
879 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
880 forward_tan_op(p, q, i_var, size_t(arg[0]), J, taylor);
881 break;
882 // -------------------------------------------------
883
884 case TanhOp:
885 // tanh(x)^2, tanh(x)
886 CPPAD_ASSERT_UNKNOWN( i_var < numvar );
887 forward_tanh_op(p, q, i_var, size_t(arg[0]), J, taylor);
888 break;
889 // -------------------------------------------------
890
891 case AFunOp:
892 // start or end an atomic function call
893 flag = atom_state == start_atom;
894 play::atom_op_info<RecBase>(
895 op, arg, atom_index, atom_old, atom_m, atom_n
896 );
897 if( flag )
898 { atom_state = arg_atom;
899 atom_i = 0;
900 atom_j = 0;
901 //
902 atom_par_x.resize(atom_n);
903 atom_type_x.resize(atom_n);
904 atom_tx.resize(atom_n * atom_q1);
905 atom_ty.resize(atom_m * atom_q1);
906 atom_iy.resize(atom_m);
907 }
908 else
909 { CPPAD_ASSERT_UNKNOWN( atom_i == atom_m );
910 CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );
911 atom_state = start_atom;
912 //
913 // call atomic function for this operation
914 call_atomic_forward<Base, RecBase>(
915 atom_par_x, atom_type_x, need_y,
916 order_low, order_up, atom_index, atom_old, atom_tx, atom_ty
917 );
918 for(i = 0; i < atom_m; i++)
919 if( atom_iy[i] > 0 )
920 for(k = p; k <= q; k++)
921 taylor[ atom_iy[i] * J + k ] =
922 atom_ty[ i * atom_q1 + k ];
923 # if CPPAD_FORWARD1_TRACE
924 atom_trace = true;
925 # endif
926 }
927 break;
928
929 case FunapOp:
930 // parameter argument for a atomic function
931 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
932 CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );
933 CPPAD_ASSERT_UNKNOWN( atom_i == 0 );
934 CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );
935 CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );
936 //
937 if( dyn_par_is[ arg[0] ] )
938 atom_type_x[atom_j] = dynamic_enum;
939 else
940 atom_type_x[atom_j] = constant_enum;
941 atom_par_x[atom_j] = parameter[ arg[0] ];
942 atom_tx[atom_j * atom_q1 + 0] = parameter[ arg[0]];
943 for(k = 1; k < atom_q1; k++)
944 atom_tx[atom_j * atom_q1 + k] = Base(0.0);
945 //
946 ++atom_j;
947 if( atom_j == atom_n )
948 atom_state = ret_atom;
949 break;
950
951 case FunavOp:
952 // variable argument for a atomic function
953 CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
954 CPPAD_ASSERT_UNKNOWN( atom_state == arg_atom );
955 CPPAD_ASSERT_UNKNOWN( atom_i == 0 );
956 CPPAD_ASSERT_UNKNOWN( atom_j < atom_n );
957 //
958 atom_type_x[atom_j] = variable_enum;
959 atom_par_x[atom_j] = CppAD::numeric_limits<Base>::quiet_NaN();
960 for(k = 0; k < atom_q1; k++)
961 atom_tx[atom_j * atom_q1 + k] = taylor[ size_t(arg[0]) * J + k];
962 //
963 ++atom_j;
964 if( atom_j == atom_n )
965 atom_state = ret_atom;
966 break;
967
968 case FunrpOp:
969 // parameter result for a atomic function
970 CPPAD_ASSERT_NARG_NRES(op, 1, 0);
971 CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );
972 CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );
973 CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );
974 CPPAD_ASSERT_UNKNOWN( size_t( arg[0] ) < num_par );
975 //
976 atom_iy[atom_i] = 0;
977 atom_ty[atom_i * atom_q1 + 0] = parameter[ arg[0]];
978 for(k = 1; k < p; k++)
979 atom_ty[atom_i * atom_q1 + k] = Base(0.0);
980 //
981 ++atom_i;
982 if( atom_i == atom_m )
983 atom_state = end_atom;
984 break;
985
986 case FunrvOp:
987 // variable result for a atomic function
988 CPPAD_ASSERT_NARG_NRES(op, 0, 1);
989 CPPAD_ASSERT_UNKNOWN( atom_state == ret_atom );
990 CPPAD_ASSERT_UNKNOWN( atom_i < atom_m );
991 CPPAD_ASSERT_UNKNOWN( atom_j == atom_n );
992 //
993 atom_iy[atom_i] = i_var;
994 for(k = 0; k < p; k++)
995 atom_ty[atom_i * atom_q1 + k] = taylor[ i_var * J + k];
996 //
997 ++atom_i;
998 if( atom_i == atom_m )
999 atom_state = end_atom;
1000 break;
1001 // -------------------------------------------------
1002
1003 case ZmulpvOp:
1004 CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
1005 forward_zmulpv_op(p, q, i_var, arg, parameter, J, taylor);
1006 break;
1007 // -------------------------------------------------
1008
1009 case ZmulvpOp:
1010 CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
1011 forward_zmulvp_op(p, q, i_var, arg, parameter, J, taylor);
1012 break;
1013 // -------------------------------------------------
1014
1015 case ZmulvvOp:
1016 forward_zmulvv_op(p, q, i_var, arg, parameter, J, taylor);
1017 break;
1018 // -------------------------------------------------
1019
1020 default:
1021 CPPAD_ASSERT_UNKNOWN(0);
1022 }
1023 # if CPPAD_FORWARD1_TRACE
1024 if( atom_trace )
1025 { atom_trace = false;
1026
1027 CPPAD_ASSERT_UNKNOWN( op == AFunOp );
1028 CPPAD_ASSERT_UNKNOWN( NumArg(FunrvOp) == 0 );
1029 for(i = 0; i < atom_m; i++) if( atom_iy[i] > 0 )
1030 { size_t i_tmp = (itr.op_index() + i) - atom_m;
1031 printOp<Base, RecBase>(
1032 std::cout,
1033 play,
1034 i_tmp,
1035 atom_iy[i],
1036 FunrvOp,
1037 nullptr
1038 );
1039 Base* Z_tmp = taylor + atom_iy[i] * J;
1040 printOpResult(
1041 std::cout,
1042 q + 1,
1043 Z_tmp,
1044 0,
1045 (Base *) nullptr
1046 );
1047 std::cout << std::endl;
1048 }
1049 }
1050 Base* Z_tmp = taylor + J * i_var;
1051 if( op != FunrvOp )
1052 {
1053 printOp<Base, RecBase>(
1054 std::cout,
1055 play,
1056 itr.op_index(),
1057 i_var,
1058 op,
1059 arg
1060 );
1061 if( NumRes(op) > 0 ) printOpResult(
1062 std::cout,
1063 q + 1,
1064 Z_tmp,
1065 0,
1066 (Base *) nullptr
1067 );
1068 std::cout << std::endl;
1069 }
1070 }
1071 std::cout << std::endl;
1072 # else
1073 }
1074 # endif
1075 CPPAD_ASSERT_UNKNOWN( atom_state == start_atom );
1076
1077 if( (p == 0) & (compare_change_count == 0) )
1078 compare_change_number = 0;
1079 return;
1080 }
1081
1082 // preprocessor symbols that are local to this file
1083 # undef CPPAD_FORWARD1_TRACE
1084
1085 } } } // END_CPPAD_LOCAL_SWEEP_NAMESPACE
1086 # endif
1087