source: branches/cache/cppad/local/reverse_sweep.hpp @ 3335

Last change on this file since 3335 was 3335, checked in by bradbell, 6 years ago
  1. cache.sh should not revert sweep files that have changed.
  2. Fix calls that were erased by mistake fixed in 1.
  3. Use cache2var (better description than cache).
  4. Put cache2var in ADFun function object.
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: reverse_sweep.hpp 3335 2014-09-15 22:32:35Z bradbell $ */
2# ifndef CPPAD_REVERSE_SWEEP_INCLUDED
3# define CPPAD_REVERSE_SWEEP_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
16
17namespace CppAD { // BEGIN_CPPAD_NAMESPACE
18/*!
19\file reverse_sweep.hpp
20Compute derivatives of arbitrary order Taylor coefficients.
21*/
22
23/*
24\def CPPAD_ATOMIC_CALL
25This avoids warnings when NDEBUG is defined and user_ok is not used.
26If \c NDEBUG is defined, this resolves to
27\code
28        user_atom->reverse
29\endcode
30otherwise, it respolves to
31\code
32        user_ok = user_atom->reverse
33\endcode
34This maco is undefined at the end of this file to facillitate is
35use with a different definition in other files.
36*/
37# ifdef NDEBUG
38# define CPPAD_ATOMIC_CALL user_atom->reverse
39# else
40# define CPPAD_ATOMIC_CALL user_ok = user_atom->reverse
41# endif
42
43/*!
44\def CPPAD_REVERSE_SWEEP_TRACE
45This value is either zero or one.
46Zero is the normal operational value.
47If it is one, a trace of every reverse_sweep computation is printed.
48*/
49# define CPPAD_REVERSE_SWEEP_TRACE 0
50
51/*!
52Compute derivative of arbitrary order forward mode Taylor coefficients.
53
54\tparam Base
55base type for the operator; i.e., this operation sequence was recorded
56using AD< \a Base > and computations by this routine are done using type
57\a Base.
58
59\param d
60is the highest order Taylor coefficients that
61we are computing the derivative of.
62
63\param n
64is the number of independent variables on the tape.
65
66\param numvar
67is the total number of variables on the tape.
68This is also equal to the number of rows in the matrix \a Taylor; i.e.,
69play->num_var_rec().
70
71\param play
72The information stored in \a play
73is a recording of the operations corresponding to the function
74\f[
75        F : {\bf R}^n \rightarrow {\bf R}^m
76\f]
77where \f$ n \f$ is the number of independent variables and
78\f$ m \f$ is the number of dependent variables.
79We define the function
80\f$ G : {\bf R}^{n \times d} \rightarrow {\bf R} \f$ by
81\f[
82G( u ) = \frac{1}{d !} \frac{ \partial^d }{ \partial t^d }
83\left[
84        \sum_{i=1}^m w_i  F_i ( u^{(0)} + u^{(1)} t + \cdots + u^{(d)} t^d )
85\right]_{t=0}
86\f]
87Note that the scale factor  1 / a d  converts
88the \a d-th partial derivative to the \a d-th order Taylor coefficient.
89This routine computes the derivative of \f$ G(u) \f$
90with respect to all the Taylor coefficients
91\f$ u^{(k)} \f$ for \f$ k = 0 , ... , d \f$.
92The vector \f$ w \in {\bf R}^m \f$, and
93value of \f$ u \in {\bf R}^{n \times d} \f$
94at which the derivative is computed,
95are defined below.
96\n
97\n
98The object \a play is effectly constant.
99There is an exception to this,
100while palying back the tape
101the object \a play holds information about the current location
102with in the tape and this changes during palyback.
103
104\param J
105Is the number of columns in the coefficient matrix \a Taylor.
106This must be greater than or equal \a d + 1.
107
108\param Taylor
109For i = 1 , ... , \a numvar, and for k = 0 , ... , \a d,
110\a Taylor [ i * J + k ]
111is the k-th order Taylor coefficient corresponding to
112variable with index i on the tape.
113The value \f$ u \in {\bf R}^{n \times d} \f$,
114at which the derivative is computed,
115is defined by
116\f$ u_j^{(k)} \f$ = \a Taylor [ j * J + k ]
117for j = 1 , ... , \a n, and for k = 0 , ... , \a d.
118
119\param K
120Is the number of columns in the partial derivative matrix \a Partial.
121It must be greater than or equal \a d + 1.
122
123\param Partial
124\b Input:
125The last \f$ m \f$ rows of \a Partial are inputs.
126The vector \f$ v \f$, used to define \f$ G(u) \f$,
127is specified by these rows.
128For i = 0 , ... , m - 1, \a Partial [ ( \a numvar - m + i ) * K + d ] = v_i.
129For i = 0 , ... , m - 1 and for k = 0 , ... , d - 1,
130\a Partial [ ( \a numvar - m + i ) * K + k ] = 0.
131\n
132\n
133\b Temporary:
134For i = n+1 , ... , \a numvar - 1 and for k = 0 , ... , d,
135the value of \a Partial [ i * K + k ] is used for temporary work space
136and its output value is not defined.
137\n
138\n
139\b Output:
140For j = 1 , ... , n and for k = 0 , ... , d,
141\a Partial [ j * K + k ]
142is the partial derivative of \f$ G( u ) \f$ with
143respect to \f$ u_j^{(k)} \f$.
144
145\param cskip_op
146Is a vector with size play->num_op_rec().
147If cskip_op[i] is true, the operator index i in the recording
148does not affect any of the dependent variable (given the value
149of the independent variables).
150
151\param var_by_load_op
152is a vector with size play->num_load_op_rec().
153Is the variable index corresponding to each load instruction.
154In the case where the index is zero,
155the instruction corresponds to a parameter (not variable).
156
157\par Assumptions
158The first operator on the tape is a BeginOp,
159and the next \a n operators are InvOp operations for the
160corresponding independent variables.
161*/
162template <class Base>
163void ReverseSweep(
164        size_t                      d,
165        size_t                      n,
166        size_t                      numvar,
167        player<Base>*               play,
168        size_t                      J,
169        const Base*                 Taylor,
170        size_t                      K,
171        Base*                       Partial,
172        bool*                       cskip_op,
173        const pod_vector<addr_t>&   var_by_load_op
174)
175{
176        OpCode           op;
177        size_t         i_op;
178        size_t        i_var;
179
180        const addr_t*   arg = CPPAD_NULL;
181
182        // check numvar argument
183        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
184        CPPAD_ASSERT_UNKNOWN( numvar > 0 );
185
186        // length of the parameter vector (used by CppAD assert macros)
187        const size_t num_par = play->num_par_rec();
188
189        // pointer to the beginning of the parameter vector
190        const Base* parameter = CPPAD_NULL;
191        if( num_par > 0 )
192                parameter = play->GetPar();
193
194        // work space used by UserOp.
195        const size_t user_k  = d;    // highest order we are differentiating
196        const size_t user_k1 = d+1;  // number of orders for this calculation
197        vector<size_t> user_ix;      // variable indices for argument vector
198        vector<Base> user_tx;        // argument vector Taylor coefficients
199        vector<Base> user_ty;        // result vector Taylor coefficients
200        vector<Base> user_px;        // partials w.r.t argument vector
201        vector<Base> user_py;        // partials w.r.t. result vector
202        size_t user_index = 0;       // indentifier for this atomic operation
203        size_t user_id    = 0;       // user identifier for this call to operator
204        size_t user_i     = 0;       // index in result vector
205        size_t user_j     = 0;       // index in argument vector
206        size_t user_m     = 0;       // size of result vector
207        size_t user_n     = 0;       // size of arugment vector
208        //
209        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
210# ifndef NDEBUG
211        bool               user_ok   = false;      // atomic op return value
212# endif
213        //
214        // next expected operator in a UserOp sequence
215        enum { user_start, user_arg, user_ret, user_end } user_state = user_end;
216
217        // temporary indices
218        size_t j, ell;
219
220        // Initialize
221        play->reverse_start(op, arg, i_op, i_var);
222        CPPAD_ASSERT_UNKNOWN( op == EndOp );
223# if CPPAD_REVERSE_SWEEP_TRACE
224        std::cout << std::endl;
225
226        // 2DO: implement tracing cache
227        CppAD::vector<addr_t> cache2var;
228# endif
229        bool more_operators = true;
230        while(more_operators)
231        {       // next op
232                play->reverse_next(op, arg, i_op, i_var);
233                CPPAD_ASSERT_UNKNOWN((i_op >  n) | (op == InvOp) | (op == BeginOp));
234                CPPAD_ASSERT_UNKNOWN((i_op <= n) | (op != InvOp) | (op != BeginOp));
235                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
236
237                // check if we are skipping this operation
238                while( cskip_op[i_op] )
239                {       if( op == CSumOp )
240                        {       // CSumOp has a variable number of arguments
241                                play->reverse_csum(op, arg, i_op, i_var);
242                        }
243                        play->reverse_next(op, arg, i_op, i_var);
244                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
245                }
246
247                // rest of informaiton depends on the case
248# if CPPAD_REVERSE_SWEEP_TRACE
249                size_t       i_tmp  = i_var;
250                const Base*  Z_tmp  = Taylor + i_var * J;
251                const Base*  pZ_tmp = Partial + i_var * K;
252                printOp(
253                        std::cout, 
254                        play,
255                        i_op,
256                        i_tmp,
257                        op, 
258                        arg,
259                        cache2var
260                );
261                if( NumRes(op) > 0 && op != BeginOp ) printOpResult(
262                        std::cout, 
263                        d + 1, 
264                        Z_tmp, 
265                        d + 1, 
266                        pZ_tmp
267                );
268                std::cout << std::endl;
269# endif
270                switch( op )
271                {
272
273                        case AbsOp:
274                        reverse_abs_op(
275                                d, i_var, arg[0], J, Taylor, K, Partial
276                        );
277                        break;
278                        // --------------------------------------------------
279
280                        case AddvvOp:
281                        reverse_addvv_op(
282                                d, i_var, arg, parameter, J, Taylor, K, Partial
283                        );
284                        break;
285                        // --------------------------------------------------
286
287                        case AddpvOp:
288                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
289                        reverse_addpv_op(
290                                d, i_var, arg, parameter, J, Taylor, K, Partial
291                        );
292                        break;
293                        // --------------------------------------------------
294
295                        case AcosOp:
296                        // sqrt(1 - x * x), acos(x)
297                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
298                        reverse_acos_op(
299                                d, i_var, arg[0], J, Taylor, K, Partial
300                        );
301                        break;
302                        // --------------------------------------------------
303
304                        case AsinOp:
305                        // sqrt(1 - x * x), asin(x)
306                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
307                        reverse_asin_op(
308                                d, i_var, arg[0], J, Taylor, K, Partial
309                        );
310                        break;
311                        // --------------------------------------------------
312
313                        case AtanOp:
314                        // 1 + x * x, atan(x)
315                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
316                        reverse_atan_op(
317                                d, i_var, arg[0], J, Taylor, K, Partial
318                        );
319                        break;
320                        // -------------------------------------------------
321
322                        case BeginOp:
323                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
324                        more_operators = false;
325                        break;
326                        // --------------------------------------------------
327
328                        case CSkipOp:
329                        // CSkipOp has a variable number of arguments and
330                        // forward_next thinks it one has one argument.
331                        // we must inform reverse_next of this special case.
332                        play->reverse_cskip(op, arg, i_op, i_var);
333                        break;
334                        // -------------------------------------------------
335
336                        case CSumOp:
337                        // CSumOp has a variable number of arguments and
338                        // reverse_next thinks it one has one argument.
339                        // We must inform reverse_next of this special case.
340                        play->reverse_csum(op, arg, i_op, i_var);
341                        reverse_csum_op(
342                                d, i_var, arg, K, Partial
343                        );
344                        // end of a cummulative summation
345                        break;
346                        // -------------------------------------------------
347
348                        case CExpOp:
349                        reverse_cond_op(
350                                d, 
351                                i_var, 
352                                arg, 
353                                num_par, 
354                                parameter, 
355                                J, 
356                                Taylor,
357                                K, 
358                                Partial
359                        );
360                        break;
361                        // --------------------------------------------------
362
363                        case ComOp:
364                        break;
365                        // --------------------------------------------------
366
367                        case CosOp:
368                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
369                        reverse_cos_op(
370                                d, i_var, arg[0], J, Taylor, K, Partial
371                        );
372                        break;
373                        // --------------------------------------------------
374
375                        case CoshOp:
376                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
377                        reverse_cosh_op(
378                                d, i_var, arg[0], J, Taylor, K, Partial
379                        );
380                        break;
381                        // --------------------------------------------------
382
383                        case DisOp:
384                        // Derivative of discrete operation is zero so no
385                        // contribution passes through this operation.
386                        break;
387                        // --------------------------------------------------
388
389                        case DivvvOp:
390                        reverse_divvv_op(
391                                d, i_var, arg, parameter, J, Taylor, K, Partial
392                        );
393                        break;
394                        // --------------------------------------------------
395
396                        case DivpvOp:
397                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
398                        reverse_divpv_op(
399                                d, i_var, arg, parameter, J, Taylor, K, Partial
400                        );
401                        break;
402                        // --------------------------------------------------
403
404                        case DivvpOp:
405                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
406                        reverse_divvp_op(
407                                d, i_var, arg, parameter, J, Taylor, K, Partial
408                        );
409                        break;
410                        // --------------------------------------------------
411
412                        case ExpOp:
413                        reverse_exp_op(
414                                d, i_var, arg[0], J, Taylor, K, Partial
415                        );
416                        break;
417                        // --------------------------------------------------
418                        case LdpOp:
419                        reverse_load_op(
420                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
421                        );
422                        break;
423                        // -------------------------------------------------
424
425                        case LdvOp:
426                        reverse_load_op(
427                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
428                        );
429                        break;
430                        // -------------------------------------------------
431
432                        case InvOp:
433                        break;
434                        // --------------------------------------------------
435
436                        case LogOp:
437                        reverse_log_op(
438                                d, i_var, arg[0], J, Taylor, K, Partial
439                        );
440                        break;
441                        // --------------------------------------------------
442
443                        case MulvvOp:
444                        reverse_mulvv_op(
445                                d, i_var, arg, parameter, J, Taylor, K, Partial
446                        );
447                        break;
448                        // --------------------------------------------------
449
450                        case MulpvOp:
451                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
452                        reverse_mulpv_op(
453                                d, i_var, arg, parameter, J, Taylor, K, Partial
454                        );
455                        break;
456                        // --------------------------------------------------
457
458                        case ParOp:
459                        break;
460                        // --------------------------------------------------
461
462                        case PowvpOp:
463                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
464                        reverse_powvp_op(
465                                d, i_var, arg, parameter, J, Taylor, K, Partial
466                        );
467                        break;
468                        // -------------------------------------------------
469
470                        case PowpvOp:
471                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
472                        reverse_powpv_op(
473                                d, i_var, arg, parameter, J, Taylor, K, Partial
474                        );
475                        break;
476                        // -------------------------------------------------
477
478                        case PowvvOp:
479                        reverse_powvv_op(
480                                d, i_var, arg, parameter, J, Taylor, K, Partial
481                        );
482                        break;
483                        // --------------------------------------------------
484
485                        case PriOp:
486                        // no result so nothing to do
487                        break;
488                        // --------------------------------------------------
489
490                        case SignOp:
491                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
492                        reverse_sign_op(
493                                d, i_var, arg[0], J, Taylor, K, Partial
494                        );
495                        break;
496                        // -------------------------------------------------
497
498                        case SinOp:
499                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
500                        reverse_sin_op(
501                                d, i_var, arg[0], J, Taylor, K, Partial
502                        );
503                        break;
504                        // -------------------------------------------------
505
506                        case SinhOp:
507                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
508                        reverse_sinh_op(
509                                d, i_var, arg[0], J, Taylor, K, Partial
510                        );
511                        break;
512                        // --------------------------------------------------
513
514                        case SqrtOp:
515                        reverse_sqrt_op(
516                                d, i_var, arg[0], J, Taylor, K, Partial
517                        );
518                        break;
519                        // --------------------------------------------------
520
521                        case StppOp:
522                        break;
523                        // --------------------------------------------------
524
525                        case StpvOp:
526                        break;
527                        // -------------------------------------------------
528
529                        case StvpOp:
530                        break;
531                        // -------------------------------------------------
532
533                        case StvvOp:
534                        break;
535                        // --------------------------------------------------
536
537                        case SubvvOp:
538                        reverse_subvv_op(
539                                d, i_var, arg, parameter, J, Taylor, K, Partial
540                        );
541                        break;
542                        // --------------------------------------------------
543
544                        case SubpvOp:
545                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
546                        reverse_subpv_op(
547                                d, i_var, arg, parameter, J, Taylor, K, Partial
548                        );
549                        break;
550                        // --------------------------------------------------
551
552                        case SubvpOp:
553                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
554                        reverse_subvp_op(
555                                d, i_var, arg, parameter, J, Taylor, K, Partial
556                        );
557                        break;
558                        // -------------------------------------------------
559
560                        case TanOp:
561                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
562                        reverse_tan_op(
563                                d, i_var, arg[0], J, Taylor, K, Partial
564                        );
565                        break;
566                        // -------------------------------------------------
567
568                        case TanhOp:
569                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
570                        reverse_tanh_op(
571                                d, i_var, arg[0], J, Taylor, K, Partial
572                        );
573                        break;
574                        // --------------------------------------------------
575
576                        case UserOp:
577                        // start or end an atomic operation sequence
578                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
579                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
580                        if( user_state == user_end )
581                        {       user_index = arg[0];
582                                user_id    = arg[1];
583                                user_n     = arg[2];
584                                user_m     = arg[3];
585                                user_atom  = atomic_base<Base>::class_object(user_index);
586# ifndef NDEBUG
587                                if( user_atom == CPPAD_NULL )
588                                {       std::string msg = 
589                                                atomic_base<Base>::class_name(user_index)
590                                                + ": atomic_base function has been deleted";
591                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
592                                }
593# endif
594                                if(user_ix.size() != user_n)
595                                        user_ix.resize(user_n);
596                                if(user_tx.size() != user_n * user_k1)
597                                {       user_tx.resize(user_n * user_k1);
598                                        user_px.resize(user_n * user_k1);
599                                }
600                                if(user_ty.size() != user_m * user_k1)
601                                {       user_ty.resize(user_m * user_k1);
602                                        user_py.resize(user_m * user_k1);
603                                }
604                                user_j     = user_n;
605                                user_i     = user_m;
606                                user_state = user_ret;
607                        }
608                        else
609                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_start );
610                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
611                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
612                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
613                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
614
615                                // call users function for this operation
616                                user_atom->set_id(user_id);
617                                CPPAD_ATOMIC_CALL(
618                                        user_k, user_tx, user_ty, user_px, user_py
619                                );
620# ifndef NDEBUG
621                                if( ! user_ok )
622                                {       std::string msg = 
623                                                atomic_base<Base>::class_name(user_index)
624                                                + ": atomic_base.reverse: returned false";
625                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
626                                }
627# endif
628                                for(j = 0; j < user_n; j++) if( user_ix[j] > 0 )
629                                {       for(ell = 0; ell < user_k1; ell++)
630                                                Partial[user_ix[j] * K + ell] +=
631                                                        user_px[j * user_k1 + ell];
632                                }
633                                user_state = user_end;
634                        }
635                        break;
636
637                        case UsrapOp:
638                        // parameter argument in an atomic operation sequence
639                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
640                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
641                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
642                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
643                        --user_j;
644                        user_ix[user_j] = 0;
645                        user_tx[user_j * user_k1 + 0] = parameter[ arg[0]];
646                        for(ell = 1; ell < user_k1; ell++)
647                                user_tx[user_j * user_k1 + ell] = Base(0.);
648                       
649                        if( user_j == 0 )
650                                user_state = user_start;
651                        break;
652
653                        case UsravOp:
654                        // variable argument in an atomic operation sequence
655                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
656                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
657                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
658                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
659                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
660                        --user_j;
661                        user_ix[user_j] = arg[0];
662                        for(ell = 0; ell < user_k1; ell++)
663                                user_tx[user_j*user_k1 + ell] = Taylor[ arg[0] * J + ell];
664                        if( user_j == 0 )
665                                user_state = user_start;
666                        break;
667
668                        case UsrrpOp:
669                        // parameter result in an atomic operation sequence
670                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
671                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
672                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
673                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
674                        --user_i;
675                        for(ell = 0; ell < user_k1; ell++)
676                        {       user_py[user_i * user_k1 + ell] = Base(0.);
677                                user_ty[user_i * user_k1 + ell] = Base(0.);
678                        }
679                        user_ty[user_i * user_k1 + 0] = parameter[ arg[0] ];
680                        if( user_i == 0 )
681                                user_state = user_arg;
682                        break;
683
684                        case UsrrvOp:
685                        // variable result in an atomic operation sequence
686                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
687                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
688                        --user_i;
689                        for(ell = 0; ell < user_k1; ell++)
690                        {       user_py[user_i * user_k1 + ell] =
691                                                Partial[i_var * K + ell];
692                                user_ty[user_i * user_k1 + ell] =
693                                                Taylor[i_var * J + ell];
694                        }
695                        if( user_i == 0 )
696                                user_state = user_arg;
697                        break;
698                        // ------------------------------------------------------------
699
700                        default:
701                        CPPAD_ASSERT_UNKNOWN(false);
702                }
703        }
704# if CPPAD_REVERSE_SWEEP_TRACE
705        std::cout << std::endl;
706# endif
707        // values corresponding to BeginOp
708        CPPAD_ASSERT_UNKNOWN( i_op == 0 );
709        CPPAD_ASSERT_UNKNOWN( i_var == 0 );
710}
711
712} // END_CPPAD_NAMESPACE
713
714// preprocessor symbols that are local to this file
715# undef CPPAD_REVERSE_SWEEP_TRACE
716# undef CPPAD_ATOMIC_CALL
717
718# endif
Note: See TracBrowser for help on using the repository browser.