source: branches/cache/cppad/local/forward1sweep.hpp @ 3344

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

Implement and test first order forward mode.

cache.sh: Erase taylor coefficient when create cache.
forward1sweep.hpp: copy more information from forward0sweep.

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