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

Last change on this file since 3342 was 3342, checked in by bradbell, 6 years ago
  1. Zero order forward mode trace is correct, but results not getteing back

to function object; i.e. y and y_cache different.

  1. Change numvar to num_var in reverse mode sweep functions.
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: reverse_sweep.hpp 3342 2014-09-19 12:22:05Z 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 num_var
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 num_var, 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 num_var - m + i ) * K + d ] = v_i.
129For i = 0 , ... , m - 1 and for k = 0 , ... , d - 1,
130\a Partial [ ( \a num_var - m + i ) * K + k ] = 0.
131\n
132\n
133\b Temporary:
134For i = n+1 , ... , \a num_var - 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                      num_var,
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 num_var argument
183        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == num_var );
184        CPPAD_ASSERT_UNKNOWN( num_var > 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                        num_var,
260                        cache2var
261                );
262                if( NumRes(op) > 0 && op != BeginOp ) printOpResult(
263                        std::cout, 
264                        d + 1, 
265                        Z_tmp, 
266                        d + 1, 
267                        pZ_tmp
268                );
269                std::cout << std::endl;
270# endif
271                switch( op )
272                {
273
274                        case AbsOp:
275                        reverse_abs_op(
276                                d, i_var, arg[0], J, Taylor, K, Partial
277                        );
278                        break;
279                        // --------------------------------------------------
280
281                        case AddvvOp:
282                        reverse_addvv_op(
283                                d, i_var, arg, parameter, J, Taylor, K, Partial
284                        );
285                        break;
286                        // --------------------------------------------------
287
288                        case AddpvOp:
289                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
290                        reverse_addpv_op(
291                                d, i_var, arg, parameter, J, Taylor, K, Partial
292                        );
293                        break;
294                        // --------------------------------------------------
295
296                        case AcosOp:
297                        // sqrt(1 - x * x), acos(x)
298                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
299                        reverse_acos_op(
300                                d, i_var, arg[0], J, Taylor, K, Partial
301                        );
302                        break;
303                        // --------------------------------------------------
304
305                        case AsinOp:
306                        // sqrt(1 - x * x), asin(x)
307                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
308                        reverse_asin_op(
309                                d, i_var, arg[0], J, Taylor, K, Partial
310                        );
311                        break;
312                        // --------------------------------------------------
313
314                        case AtanOp:
315                        // 1 + x * x, atan(x)
316                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
317                        reverse_atan_op(
318                                d, i_var, arg[0], J, Taylor, K, Partial
319                        );
320                        break;
321                        // -------------------------------------------------
322
323                        case BeginOp:
324                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
325                        more_operators = false;
326                        break;
327                        // --------------------------------------------------
328
329                        case CSkipOp:
330                        // CSkipOp has a variable number of arguments and
331                        // forward_next thinks it one has one argument.
332                        // we must inform reverse_next of this special case.
333                        play->reverse_cskip(op, arg, i_op, i_var);
334                        break;
335                        // -------------------------------------------------
336
337                        case CSumOp:
338                        // CSumOp has a variable number of arguments and
339                        // reverse_next thinks it one has one argument.
340                        // We must inform reverse_next of this special case.
341                        play->reverse_csum(op, arg, i_op, i_var);
342                        reverse_csum_op(
343                                d, i_var, arg, K, Partial
344                        );
345                        // end of a cummulative summation
346                        break;
347                        // -------------------------------------------------
348
349                        case CExpOp:
350                        reverse_cond_op(
351                                d, 
352                                i_var, 
353                                arg, 
354                                num_par, 
355                                parameter, 
356                                J, 
357                                Taylor,
358                                K, 
359                                Partial
360                        );
361                        break;
362                        // --------------------------------------------------
363
364                        case ComOp:
365                        break;
366                        // --------------------------------------------------
367
368                        case CosOp:
369                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
370                        reverse_cos_op(
371                                d, i_var, arg[0], J, Taylor, K, Partial
372                        );
373                        break;
374                        // --------------------------------------------------
375
376                        case CoshOp:
377                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
378                        reverse_cosh_op(
379                                d, i_var, arg[0], J, Taylor, K, Partial
380                        );
381                        break;
382                        // --------------------------------------------------
383
384                        case DisOp:
385                        // Derivative of discrete operation is zero so no
386                        // contribution passes through this operation.
387                        break;
388                        // --------------------------------------------------
389
390                        case DivvvOp:
391                        reverse_divvv_op(
392                                d, i_var, arg, parameter, J, Taylor, K, Partial
393                        );
394                        break;
395                        // --------------------------------------------------
396
397                        case DivpvOp:
398                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
399                        reverse_divpv_op(
400                                d, i_var, arg, parameter, J, Taylor, K, Partial
401                        );
402                        break;
403                        // --------------------------------------------------
404
405                        case DivvpOp:
406                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
407                        reverse_divvp_op(
408                                d, i_var, arg, parameter, J, Taylor, K, Partial
409                        );
410                        break;
411                        // --------------------------------------------------
412
413                        case ExpOp:
414                        reverse_exp_op(
415                                d, i_var, arg[0], J, Taylor, K, Partial
416                        );
417                        break;
418                        // --------------------------------------------------
419                        case LdpOp:
420                        reverse_load_op(
421                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
422                        );
423                        break;
424                        // -------------------------------------------------
425
426                        case LdvOp:
427                        reverse_load_op(
428                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
429                        );
430                        break;
431                        // -------------------------------------------------
432
433                        case InvOp:
434                        break;
435                        // --------------------------------------------------
436
437                        case LogOp:
438                        reverse_log_op(
439                                d, i_var, arg[0], J, Taylor, K, Partial
440                        );
441                        break;
442                        // --------------------------------------------------
443
444                        case MulvvOp:
445                        reverse_mulvv_op(
446                                d, i_var, arg, parameter, J, Taylor, K, Partial
447                        );
448                        break;
449                        // --------------------------------------------------
450
451                        case MulpvOp:
452                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
453                        reverse_mulpv_op(
454                                d, i_var, arg, parameter, J, Taylor, K, Partial
455                        );
456                        break;
457                        // --------------------------------------------------
458
459                        case ParOp:
460                        break;
461                        // --------------------------------------------------
462
463                        case PowvpOp:
464                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
465                        reverse_powvp_op(
466                                d, i_var, arg, parameter, J, Taylor, K, Partial
467                        );
468                        break;
469                        // -------------------------------------------------
470
471                        case PowpvOp:
472                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
473                        reverse_powpv_op(
474                                d, i_var, arg, parameter, J, Taylor, K, Partial
475                        );
476                        break;
477                        // -------------------------------------------------
478
479                        case PowvvOp:
480                        reverse_powvv_op(
481                                d, i_var, arg, parameter, J, Taylor, K, Partial
482                        );
483                        break;
484                        // --------------------------------------------------
485
486                        case PriOp:
487                        // no result so nothing to do
488                        break;
489                        // --------------------------------------------------
490
491                        case SignOp:
492                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
493                        reverse_sign_op(
494                                d, i_var, arg[0], J, Taylor, K, Partial
495                        );
496                        break;
497                        // -------------------------------------------------
498
499                        case SinOp:
500                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
501                        reverse_sin_op(
502                                d, i_var, arg[0], J, Taylor, K, Partial
503                        );
504                        break;
505                        // -------------------------------------------------
506
507                        case SinhOp:
508                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
509                        reverse_sinh_op(
510                                d, i_var, arg[0], J, Taylor, K, Partial
511                        );
512                        break;
513                        // --------------------------------------------------
514
515                        case SqrtOp:
516                        reverse_sqrt_op(
517                                d, i_var, arg[0], J, Taylor, K, Partial
518                        );
519                        break;
520                        // --------------------------------------------------
521
522                        case StppOp:
523                        break;
524                        // --------------------------------------------------
525
526                        case StpvOp:
527                        break;
528                        // -------------------------------------------------
529
530                        case StvpOp:
531                        break;
532                        // -------------------------------------------------
533
534                        case StvvOp:
535                        break;
536                        // --------------------------------------------------
537
538                        case SubvvOp:
539                        reverse_subvv_op(
540                                d, i_var, arg, parameter, J, Taylor, K, Partial
541                        );
542                        break;
543                        // --------------------------------------------------
544
545                        case SubpvOp:
546                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
547                        reverse_subpv_op(
548                                d, i_var, arg, parameter, J, Taylor, K, Partial
549                        );
550                        break;
551                        // --------------------------------------------------
552
553                        case SubvpOp:
554                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
555                        reverse_subvp_op(
556                                d, i_var, arg, parameter, J, Taylor, K, Partial
557                        );
558                        break;
559                        // -------------------------------------------------
560
561                        case TanOp:
562                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
563                        reverse_tan_op(
564                                d, i_var, arg[0], J, Taylor, K, Partial
565                        );
566                        break;
567                        // -------------------------------------------------
568
569                        case TanhOp:
570                        CPPAD_ASSERT_UNKNOWN( i_var < num_var );
571                        reverse_tanh_op(
572                                d, i_var, arg[0], J, Taylor, K, Partial
573                        );
574                        break;
575                        // --------------------------------------------------
576
577                        case UserOp:
578                        // start or end an atomic operation sequence
579                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
580                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
581                        if( user_state == user_end )
582                        {       user_index = arg[0];
583                                user_id    = arg[1];
584                                user_n     = arg[2];
585                                user_m     = arg[3];
586                                user_atom  = atomic_base<Base>::class_object(user_index);
587# ifndef NDEBUG
588                                if( user_atom == CPPAD_NULL )
589                                {       std::string msg = 
590                                                atomic_base<Base>::class_name(user_index)
591                                                + ": atomic_base function has been deleted";
592                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
593                                }
594# endif
595                                if(user_ix.size() != user_n)
596                                        user_ix.resize(user_n);
597                                if(user_tx.size() != user_n * user_k1)
598                                {       user_tx.resize(user_n * user_k1);
599                                        user_px.resize(user_n * user_k1);
600                                }
601                                if(user_ty.size() != user_m * user_k1)
602                                {       user_ty.resize(user_m * user_k1);
603                                        user_py.resize(user_m * user_k1);
604                                }
605                                user_j     = user_n;
606                                user_i     = user_m;
607                                user_state = user_ret;
608                        }
609                        else
610                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_start );
611                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
612                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
613                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
614                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
615
616                                // call users function for this operation
617                                user_atom->set_id(user_id);
618                                CPPAD_ATOMIC_CALL(
619                                        user_k, user_tx, user_ty, user_px, user_py
620                                );
621# ifndef NDEBUG
622                                if( ! user_ok )
623                                {       std::string msg = 
624                                                atomic_base<Base>::class_name(user_index)
625                                                + ": atomic_base.reverse: returned false";
626                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
627                                }
628# endif
629                                for(j = 0; j < user_n; j++) if( user_ix[j] > 0 )
630                                {       for(ell = 0; ell < user_k1; ell++)
631                                                Partial[user_ix[j] * K + ell] +=
632                                                        user_px[j * user_k1 + ell];
633                                }
634                                user_state = user_end;
635                        }
636                        break;
637
638                        case UsrapOp:
639                        // parameter argument in an atomic operation sequence
640                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
641                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
642                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
643                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
644                        --user_j;
645                        user_ix[user_j] = 0;
646                        user_tx[user_j * user_k1 + 0] = parameter[ arg[0]];
647                        for(ell = 1; ell < user_k1; ell++)
648                                user_tx[user_j * user_k1 + ell] = Base(0.);
649                       
650                        if( user_j == 0 )
651                                user_state = user_start;
652                        break;
653
654                        case UsravOp:
655                        // variable argument in an atomic operation sequence
656                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
657                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
658                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
659                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
660                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
661                        --user_j;
662                        user_ix[user_j] = arg[0];
663                        for(ell = 0; ell < user_k1; ell++)
664                                user_tx[user_j*user_k1 + ell] = Taylor[ arg[0] * J + ell];
665                        if( user_j == 0 )
666                                user_state = user_start;
667                        break;
668
669                        case UsrrpOp:
670                        // parameter result in an atomic operation sequence
671                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
672                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
673                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
674                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
675                        --user_i;
676                        for(ell = 0; ell < user_k1; ell++)
677                        {       user_py[user_i * user_k1 + ell] = Base(0.);
678                                user_ty[user_i * user_k1 + ell] = Base(0.);
679                        }
680                        user_ty[user_i * user_k1 + 0] = parameter[ arg[0] ];
681                        if( user_i == 0 )
682                                user_state = user_arg;
683                        break;
684
685                        case UsrrvOp:
686                        // variable result in an atomic operation sequence
687                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
688                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
689                        --user_i;
690                        for(ell = 0; ell < user_k1; ell++)
691                        {       user_py[user_i * user_k1 + ell] =
692                                                Partial[i_var * K + ell];
693                                user_ty[user_i * user_k1 + ell] =
694                                                Taylor[i_var * J + ell];
695                        }
696                        if( user_i == 0 )
697                                user_state = user_arg;
698                        break;
699                        // ------------------------------------------------------------
700
701                        default:
702                        CPPAD_ASSERT_UNKNOWN(false);
703                }
704        }
705# if CPPAD_REVERSE_SWEEP_TRACE
706        std::cout << std::endl;
707# endif
708        // values corresponding to BeginOp
709        CPPAD_ASSERT_UNKNOWN( i_op == 0 );
710        CPPAD_ASSERT_UNKNOWN( i_var == 0 );
711}
712
713} // END_CPPAD_NAMESPACE
714
715// preprocessor symbols that are local to this file
716# undef CPPAD_REVERSE_SWEEP_TRACE
717# undef CPPAD_ATOMIC_CALL
718
719# endif
Note: See TracBrowser for help on using the repository browser.