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