source: trunk/cppad/local/forward1sweep.hpp @ 3301

Last change on this file since 3301 was 3301, checked in by bradbell, 6 years ago

merge in multiple forward direcitons from branches/forward_dir

  • Property svn:keywords set to Id
File size: 22.2 KB
Line 
1/* $Id: forward1sweep.hpp 3301 2014-05-24 05:20:21Z bradbell $ */
2# ifndef CPPAD_FORWARD1SWEEP_INCLUDED
3# define CPPAD_FORWARD1SWEEP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15
16namespace CppAD { // BEGIN_CPPAD_NAMESPACE
17/*!
18\file forward1sweep.hpp
19Compute one Taylor coefficient for each order requested.
20*/
21
22/*
23\def CPPAD_ATOMIC_CALL
24This avoids warnings when NDEBUG is defined and user_ok is not used.
25If NDEBUG is defined, this resolves to
26\code
27        user_atom->forward
28\endcode
29otherwise, it respolves to
30\code
31        user_ok = user_atom->forward
32\endcode
33This macro is undefined at the end of this file to facillitate its
34use with a different definition in other files.
35*/
36# ifdef NDEBUG
37# define CPPAD_ATOMIC_CALL user_atom->forward
38# else
39# define CPPAD_ATOMIC_CALL user_ok = user_atom->forward
40# endif
41
42/*!
43\def CPPAD_FORWARD1SWEEP_TRACE
44This value is either zero or one.
45Zero is the normal operational value.
46If it is one, a trace of every forward1sweep computation is printed.
47*/
48# define CPPAD_FORWARD1SWEEP_TRACE 0
49
50/*!
51Compute arbitrary order forward mode Taylor coefficients.
52
53<!-- replace forward0sweep_doc_define -->
54\tparam Base
55The type used during the forward mode computations; i.e., the corresponding
56recording of operations used the type AD<Base>.
57
58\param s_out
59Is the stream where output corresponding to PriOp operations will
60be written.
61
62\param print
63If print is false,
64suppress the output that is otherwise generated by the c PriOp instructions.
65
66\param n
67is the number of independent variables on the tape.
68
69\param numvar
70is the total number of variables on the tape.
71This is also equal to the number of rows in the matrix taylor; i.e.,
72play->num_var_rec().
73
74\param play
75The information stored in play
76is a recording of the operations corresponding to the function
77\f[
78        F : {\bf R}^n \rightarrow {\bf R}^m
79\f]
80where \f$ n \f$ is the number of independent variables and
81\f$ m \f$ is the number of dependent variables.
82\n
83\n
84The object play is effectly constant.
85The exception to this is that while palying back the tape
86the object play holds information about the current location
87with in the tape and this changes during palyback.
88
89\param J
90Is the number of columns in the coefficient matrix taylor.
91This must be greater than or equal one.
92
93<!-- end forward0sweep_doc_define -->
94
95\param cskip_op
96Is a vector with size play->num_op_rec().
97\n
98\n
99<tt>p = 0</tt>
100\n
101In this case,
102the input value of the elements does not matter.
103Upon return, if cskip_op[i] is true, the operator with index i
104does not affect any of the dependent variable
105(given the value of the independent variables).
106\n
107\n
108<tt>p > 0</tt>
109\n
110In this case cskip_op is not modified and has the same meaning
111as its return value above.
112
113\param var_by_load_op
114is a vector with size play->num_load_op_rec().
115\n
116\n
117<tt>p == 0</tt>
118\n
119In this case,
120The input value of the elements does not matter.
121Upon return,
122it is the variable index corresponding the result for each load operator.
123In the case where the index is zero,
124the load operator results in a parameter (not a variable).
125Note that the is no variable with index zero on the tape.
126\n
127\n
128<tt>p > 0</tt>
129\n
130In this case var_by_load_op is not modified and has the meaning
131as its return value above.
132
133\param p
134is the lowest order of the Taylor coefficients
135that are computed during this call.
136
137\param q
138is the highest order of the Taylor coefficients
139that are computed during this call.
140
141\param taylor
142\n
143\b Input:
144For <code>i = 1 , ... , numvar-1</code>,
145<code>k = 0 , ... , p-1</code>,
146<code>taylor[ J*i + k]</code>
147is the k-th order Taylor coefficient corresponding to
148the i-th variable.
149\n
150\n
151\b Input:
152For <code>i = 1 , ... , n</code>,
153<code>k = p , ... , q</code>,
154<code>taylor[ J*j + k]</code>
155is the k-th order Taylor coefficient corresponding to
156the i-th variable
157(these are the independent varaibles).
158\n
159\n
160\b Output:
161For <code>i = n+1 , ... , numvar-1</code>, and
162<code>k = 0 , ... , p-1</code>,
163<code>taylor[ J*i + k]</code>
164is the k-th order Taylor coefficient corresponding to
165the i-th variable.
166
167\return
168If p is not zero, the return value is zero.
169If p is zero,
170the return value is equal to the number of ComOp operations
171that have a different result from when the information in
172a play was recorded.
173(Note that if NDEBUG is true, there are no ComOp operations
174in play and hence this return value is always zero.)
175*/
176
177template <class Base>
178size_t forward1sweep(
179        std::ostream&         s_out,
180        const bool            print,
181        const size_t          p,
182        const size_t          q,
183        const size_t          n,
184        const size_t          numvar,
185        player<Base>*         play,
186        const size_t          J,
187        Base*                 taylor,
188        bool*                 cskip_op,
189        pod_vector<addr_t>&   var_by_load_op
190)
191{
192        // number of directions
193        const size_t r = 1;
194
195        CPPAD_ASSERT_UNKNOWN( p <= q );
196        CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
197        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
198
199        /*
200        <!-- replace forward0sweep_code_define -->
201        */
202        // op code for current instruction
203        OpCode op;
204
205        // index for current instruction
206        size_t i_op;
207
208        // next variables
209        size_t i_var;
210
211        // operation argument indices
212        const addr_t*   arg = CPPAD_NULL;
213
214        // initialize the comparision operator (ComOp) counter
215        size_t compareCount = 0;
216
217        // If this includes a zero calculation, initialize this information
218        pod_vector<bool>   isvar_by_ind;
219        pod_vector<size_t> index_by_ind;
220        if( p == 0 )
221        {       size_t i;
222
223                // this includes order zero calculation, initialize vector indices
224                size_t num = play->num_vec_ind_rec();
225                if( num > 0 )
226                {       isvar_by_ind.extend(num);
227                        index_by_ind.extend(num);
228                        for(i = 0; i < num; i++)
229                        {       index_by_ind[i] = play->GetVecInd(i);
230                                isvar_by_ind[i] = false;
231                        }
232                }
233                // includes zero order, so initialize conditional skip flags
234                num = play->num_op_rec();
235                for(i = 0; i < num; i++)
236                        cskip_op[i] = false;
237        }
238
239        // work space used by UserOp.
240        vector<bool> user_vx;        // empty vecotor
241        vector<bool> user_vy;        // empty vecotor
242        vector<Base> user_tx;        // argument vector Taylor coefficients
243        vector<Base> user_ty;        // result vector Taylor coefficients
244        size_t user_index = 0;       // indentifier for this atomic operation
245        size_t user_id    = 0;       // user identifier for this call to operator
246        size_t user_i     = 0;       // index in result vector
247        size_t user_j     = 0;       // index in argument vector
248        size_t user_m     = 0;       // size of result vector
249        size_t user_n     = 0;       // size of arugment vector
250        //
251        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
252# ifndef NDEBUG
253        bool               user_ok   = false;      // atomic op return value
254# endif
255        //
256        // next expected operator in a UserOp sequence
257        enum { user_start, user_arg, user_ret, user_end, user_trace }
258        user_state = user_start;
259
260        // length of the parameter vector (used by CppAD assert macros)
261        const size_t num_par = play->num_par_rec();
262
263        // pointer to the beginning of the parameter vector
264        const Base* parameter = CPPAD_NULL;
265        if( num_par > 0 )
266                parameter = play->GetPar();
267
268        // length of the text vector (used by CppAD assert macros)
269        const size_t num_text = play->num_text_rec();
270
271        // pointer to the beginning of the text vector
272        const char* text = CPPAD_NULL;
273        if( num_text > 0 )
274                text = play->GetTxt(0);
275        /*
276        <!-- end forward0sweep_code_define -->
277        */
278        // temporary indices
279        size_t i, k;
280
281        // number of orders for this user calculation
282        // (not needed for order zero)
283        const size_t user_q1 = q+1;
284
285        // variable indices for results vector
286        // (done differently for order zero).
287        vector<size_t> user_iy;     
288
289        // skip the BeginOp at the beginning of the recording
290        play->forward_start(op, arg, i_op, i_var);
291        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
292# if CPPAD_FORWARD1SWEEP_TRACE
293        std::cout << std::endl;
294# endif
295        bool more_operators = true;
296        while(more_operators)
297        {
298                // this op
299                play->forward_next(op, arg, i_op, i_var);
300                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) ); 
301                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); 
302                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
303
304                // check if we are skipping this operation
305                while( cskip_op[i_op] )
306                {       if( op == CSumOp )
307                        {       // CSumOp has a variable number of arguments
308                                play->forward_csum(op, arg, i_op, i_var);
309                        }
310                        play->forward_next(op, arg, i_op, i_var);
311                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
312                }
313
314                // action depends on the operator
315                switch( op )
316                {
317                        case AbsOp:
318                        forward_abs_op(p, q, i_var, arg[0], J, taylor);
319                        break;
320                        // -------------------------------------------------
321
322                        case AddvvOp:
323                        forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);
324                        break;
325                        // -------------------------------------------------
326
327                        case AddpvOp:
328                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
329                        forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);
330                        break;
331                        // -------------------------------------------------
332
333                        case AcosOp:
334                        // sqrt(1 - x * x), acos(x)
335                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
336                        forward_acos_op(p, q, i_var, arg[0], J, taylor);
337                        break;
338                        // -------------------------------------------------
339
340                        case AsinOp:
341                        // sqrt(1 - x * x), asin(x)
342                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
343                        forward_asin_op(p, q, i_var, arg[0], J, taylor);
344                        break;
345                        // -------------------------------------------------
346
347                        case AtanOp:
348                        // 1 + x * x, atan(x)
349                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
350                        forward_atan_op(p, q, i_var, arg[0], J, taylor);
351                        break;
352                        // -------------------------------------------------
353
354                        case CExpOp:
355                        forward_cond_op(
356                                p, q, i_var, arg, num_par, parameter, J, taylor
357                        );
358                        break;
359                        // ---------------------------------------------------
360
361                        case ComOp:
362                        if( p == 0 ) forward_comp_op_0(
363                        compareCount, arg, num_par, parameter, J, taylor
364                        );
365                        break;
366                        // ---------------------------------------------------
367
368                        case CosOp:
369                        // sin(x), cos(x)
370                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
371                        forward_cos_op(p, q, i_var, arg[0], J, taylor);
372                        break;
373                        // ---------------------------------------------------
374
375                        case CoshOp:
376                        // sinh(x), cosh(x)
377                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
378                        forward_cosh_op(p, q, i_var, arg[0], J, taylor);
379                        break;
380                        // -------------------------------------------------
381
382                        case CSkipOp:
383                        // CSkipOp has a variable number of arguments and
384                        // forward_next thinks it has no arguments.
385                        // we must inform forward_next of this special case.
386                        if( p == 0 )
387                        {       forward_cskip_op_0(
388                                        i_var, arg, num_par, parameter, J, taylor, cskip_op
389                                );
390                        }
391                        play->forward_cskip(op, arg, i_op, i_var);
392                        break;
393                        // -------------------------------------------------
394
395                        case CSumOp:
396                        // CSumOp has a variable number of arguments and
397                        // forward_next thinks it has no arguments.
398                        // we must inform forward_next of this special case.
399                        forward_csum_op(
400                                p, q, i_var, arg, num_par, parameter, J, taylor
401                        );
402                        play->forward_csum(op, arg, i_op, i_var);
403                        break;
404                        // -------------------------------------------------
405
406                        case DisOp:
407                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
408                        break;
409                        // -------------------------------------------------
410
411                        case DivvvOp:
412                        forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);
413                        break;
414                        // -------------------------------------------------
415
416                        case DivpvOp:
417                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
418                        forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);
419                        break;
420                        // -------------------------------------------------
421
422                        case DivvpOp:
423                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
424                        forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);
425                        break;
426                        // -------------------------------------------------
427
428                        case EndOp:
429                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
430                        more_operators = false;
431                        break;
432                        // -------------------------------------------------
433
434                        case ExpOp:
435                        forward_exp_op(p, q, i_var, arg[0], J, taylor);
436                        break;
437                        // -------------------------------------------------
438
439                        case InvOp:
440                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
441                        break;
442                        // -------------------------------------------------
443
444                        case LdpOp:
445                        if( p == 0 )
446                        {       forward_load_p_op_0(
447                                        play,
448                                        i_var, 
449                                        arg, 
450                                        parameter, 
451                                        J, 
452                                        taylor,
453                                        isvar_by_ind.data(),
454                                        index_by_ind.data(),
455                                        var_by_load_op.data()
456                                );
457                                if( p < q ) forward_load_op( 
458                                        play,
459                                        op,
460                                        p+1,
461                                        q,
462                                        r,
463                                        J,
464                                        i_var,
465                                        arg,
466                                        var_by_load_op.data(),
467                                        taylor
468                                );
469                        }
470                        else    forward_load_op( 
471                                play,
472                                op,
473                                p,
474                                q,
475                                r,
476                                J,
477                                i_var,
478                                arg,
479                                var_by_load_op.data(),
480                                taylor
481                        );
482                        break;
483                        // -------------------------------------------------
484
485                        case LdvOp:
486                        if( p == 0 )
487                        {       forward_load_v_op_0(
488                                        play,
489                                        i_var, 
490                                        arg, 
491                                        parameter, 
492                                        J, 
493                                        taylor,
494                                        isvar_by_ind.data(),
495                                        index_by_ind.data(),
496                                        var_by_load_op.data()
497                                );
498                                if( p < q ) forward_load_op( 
499                                        play,
500                                        op,
501                                        p+1,
502                                        q,
503                                        r,
504                                        J,
505                                        i_var,
506                                        arg,
507                                        var_by_load_op.data(),
508                                        taylor
509                                );
510                        }
511                        else    forward_load_op( 
512                                play,
513                                op,
514                                p,
515                                q,
516                                r,
517                                J,
518                                i_var,
519                                arg,
520                                var_by_load_op.data(),
521                                taylor
522                        );
523                        break;
524                        // -------------------------------------------------
525
526                        case LogOp:
527                        forward_log_op(p, q, i_var, arg[0], J, taylor);
528                        break;
529                        // -------------------------------------------------
530
531                        case MulvvOp:
532                        forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
533                        break;
534                        // -------------------------------------------------
535
536                        case MulpvOp:
537                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
538                        forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
539                        break;
540                        // -------------------------------------------------
541
542                        case ParOp:
543                        i = p;
544                        if( i == 0 )
545                        {       forward_par_op_0(
546                                        i_var, arg, num_par, parameter, J, taylor
547                                );
548                                i++;
549                        }
550                        while(i <= q)
551                        {       taylor[ i_var * J + i] = Base(0); 
552                                i++;
553                        }
554                        break;
555                        // -------------------------------------------------
556
557                        case PowvpOp:
558                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
559                        forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
560                        break;
561                        // -------------------------------------------------
562
563                        case PowpvOp:
564                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
565                        forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
566                        break;
567                        // -------------------------------------------------
568
569                        case PowvvOp:
570                        forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
571                        break;
572                        // -------------------------------------------------
573
574                        case PriOp:
575                        if( (p == 0) & print ) forward_pri_0(s_out,
576                                i_var, arg, num_text, text, num_par, parameter, J, taylor
577                        );
578                        break;
579                        // -------------------------------------------------
580
581                        case SignOp:
582                        // sign(x)
583                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
584                        forward_sign_op(p, q, i_var, arg[0], J, taylor);
585                        break;
586                        // -------------------------------------------------
587
588                        case SinOp:
589                        // cos(x), sin(x)
590                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
591                        forward_sin_op(p, q, i_var, arg[0], J, taylor);
592                        break;
593                        // -------------------------------------------------
594
595                        case SinhOp:
596                        // cosh(x), sinh(x)
597                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
598                        forward_sinh_op(p, q, i_var, arg[0], J, taylor);
599                        break;
600                        // -------------------------------------------------
601
602                        case SqrtOp:
603                        forward_sqrt_op(p, q, i_var, arg[0], J, taylor);
604                        break;
605                        // -------------------------------------------------
606
607                        case StppOp:
608                        if( p == 0 )
609                        {       forward_store_pp_op_0(
610                                        i_var, 
611                                        arg, 
612                                        num_par, 
613                                        J, 
614                                        taylor,
615                                        isvar_by_ind.data(),
616                                        index_by_ind.data()
617                                );
618                        }
619                        break;
620                        // -------------------------------------------------
621
622                        case StpvOp:
623                        if( p == 0 )
624                        {       forward_store_pv_op_0(
625                                        i_var, 
626                                        arg, 
627                                        num_par, 
628                                        J, 
629                                        taylor,
630                                        isvar_by_ind.data(),
631                                        index_by_ind.data()
632                                );
633                        }
634                        break;
635                        // -------------------------------------------------
636
637                        case StvpOp:
638                        if( p == 0 )
639                        {       forward_store_vp_op_0(
640                                        i_var, 
641                                        arg, 
642                                        num_par, 
643                                        J, 
644                                        taylor,
645                                        isvar_by_ind.data(),
646                                        index_by_ind.data()
647                                );
648                        }
649                        break;
650                        // -------------------------------------------------
651
652                        case StvvOp:
653                        if( p == 0 )
654                        {       forward_store_vv_op_0(
655                                        i_var, 
656                                        arg, 
657                                        num_par, 
658                                        J, 
659                                        taylor,
660                                        isvar_by_ind.data(),
661                                        index_by_ind.data()
662                                );
663                        }
664                        break;
665                        // -------------------------------------------------
666
667                        case SubvvOp:
668                        forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
669                        break;
670                        // -------------------------------------------------
671
672                        case SubpvOp:
673                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
674                        forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
675                        break;
676                        // -------------------------------------------------
677
678                        case SubvpOp:
679                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
680                        forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
681                        break;
682                        // -------------------------------------------------
683
684                        case TanOp:
685                        // tan(x)^2, tan(x)
686                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
687                        forward_tan_op(p, q, i_var, arg[0], J, taylor);
688                        break;
689                        // -------------------------------------------------
690
691                        case TanhOp:
692                        // tanh(x)^2, tanh(x)
693                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
694                        forward_tanh_op(p, q, i_var, arg[0], J, taylor);
695                        break;
696                        // -------------------------------------------------
697
698                        case UserOp:
699                        // start or end an atomic operation sequence
700                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
701                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
702                        if( user_state == user_start )
703                        {       user_index = arg[0];
704                                user_id    = arg[1];
705                                user_n     = arg[2];
706                                user_m     = arg[3];
707                                user_atom  = atomic_base<Base>::class_object(user_index);
708# ifndef NDEBUG
709                                if( user_atom == CPPAD_NULL )
710                                {       std::string msg = 
711                                                atomic_base<Base>::class_name(user_index)
712                                                + ": atomic_base function has been deleted";
713                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
714                                }
715# endif
716                                if(user_tx.size() != user_n * user_q1)
717                                        user_tx.resize(user_n * user_q1);
718                                if(user_ty.size() != user_m * user_q1)
719                                        user_ty.resize(user_m * user_q1);
720                                if(user_iy.size() != user_m)
721                                        user_iy.resize(user_m);
722                                user_j     = 0;
723                                user_i     = 0;
724                                user_state = user_arg;
725                        }
726                        else
727                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
728                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
729                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
730                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
731                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
732
733                                // call users function for this operation
734                                user_atom->set_id(user_id);
735                                CPPAD_ATOMIC_CALL(
736                                        p, q, user_vx, user_vy, user_tx, user_ty
737                                );
738# ifndef NDEBUG
739                                if( ! user_ok )
740                                {       std::string msg = 
741                                                atomic_base<Base>::class_name(user_index)
742                                                + ": atomic_base.forward: returned false";
743                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
744                                }
745# endif
746                                for(i = 0; i < user_m; i++) 
747                                        if( user_iy[i] > 0 )
748                                                for(k = p; k <= q; k++)
749                                                        taylor[ user_iy[i] * J + k ] = 
750                                                                user_ty[ i * user_q1 + k ];
751# if CPPAD_FORWARD1SWEEP_TRACE
752                                user_state = user_trace;
753# else
754                                user_state = user_start;
755# endif
756                        }
757                        break;
758
759                        case UsrapOp:
760                        // parameter argument in an atomic operation sequence
761                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
762                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
763                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
764                        user_tx[user_j * user_q1 + 0] = parameter[ arg[0]];
765                        for(k = 1; k < user_q1; k++)
766                                user_tx[user_j * user_q1 + k] = Base(0);
767                        ++user_j;
768                        if( user_j == user_n )
769                                user_state = user_ret;
770                        break;
771
772                        case UsravOp:
773                        // variable argument in an atomic operation sequence
774                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
775                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
776                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
777                        for(k = 0; k < user_q1; k++)
778                                user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k];
779                        ++user_j;
780                        if( user_j == user_n )
781                                user_state = user_ret;
782                        break;
783
784                        case UsrrpOp:
785                        // parameter result in an atomic operation sequence
786                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
787                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
788                        user_iy[user_i] = 0;
789                        user_ty[user_i * user_q1 + 0] = parameter[ arg[0]];
790                        for(k = 1; k < p; k++)
791                                user_ty[user_i * user_q1 + k] = Base(0);
792                        user_i++;
793                        if( user_i == user_m )
794                                user_state = user_end;
795                        break;
796
797                        case UsrrvOp:
798                        // variable result in an atomic operation sequence
799                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
800                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
801                        user_iy[user_i] = i_var;
802                        for(k = 0; k < p; k++)
803                                user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k];
804                        user_i++;
805                        if( user_i == user_m )
806                                user_state = user_end;
807                        break;
808                        // -------------------------------------------------
809
810                        default:
811                        CPPAD_ASSERT_UNKNOWN(0);
812                }
813# if CPPAD_FORWARD1SWEEP_TRACE
814                if( user_state == user_trace )
815                {       user_state = user_start;
816
817                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
818                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
819                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
820                        {       size_t i_tmp   = (i_op + i) - user_m;
821                                printOp(
822                                        std::cout, 
823                                        play,
824                                        i_tmp,
825                                        user_iy[i],
826                                        UsrrvOp, 
827                                        CPPAD_NULL
828                                );
829                                Base* Z_tmp = taylor + user_iy[i] * J;
830                                printOpResult(
831                                        std::cout, 
832                                        q + 1, 
833                                        Z_tmp,
834                                        0, 
835                                        (Base *) CPPAD_NULL
836                                );
837                                std::cout << std::endl;
838                        }
839                }
840                Base*           Z_tmp   = taylor + J * i_var;
841                const addr_t*   arg_tmp = arg;
842                if( op == CSumOp )
843                        arg_tmp = arg - arg[-1] - 4;
844                if( op == CSkipOp )
845                        arg_tmp = arg - arg[-1] - 7;
846                if( op != UsrrvOp )
847                {
848                        printOp(
849                                std::cout, 
850                                play,
851                                i_op,
852                                i_var,
853                                op, 
854                                arg_tmp
855                        );
856                        if( NumRes(op) > 0 ) printOpResult(
857                                std::cout, 
858                                q + 1, 
859                                Z_tmp, 
860                                0, 
861                                (Base *) CPPAD_NULL
862                        );
863                        std::cout << std::endl;
864                }
865        }
866        std::cout << std::endl;
867# else
868        }
869# endif
870        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
871        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
872
873        return compareCount;
874}
875
876// preprocessor symbols that are local to this file
877# undef CPPAD_FORWARD1SWEEP_TRACE
878# undef CPPAD_ATOMIC_CALL
879
880} // END_CPPAD_NAMESPACE
881# endif
Note: See TracBrowser for help on using the repository browser.