source: branches/opt_cond_exp/cppad/local/forward_sweep.hpp @ 2979

Last change on this file since 2979 was 2979, checked in by bradbell, 7 years ago
  1. Add operator index to trace output.
  2. Check that new operator values have been set and are valid.
  3. Reinitialize cskip_op_ after optimization.

optimize.hpp: Add test of entirely removing an atomic call.

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