source: branches/cache/cppad/local/rev_jac_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: rev_jac_sweep.hpp 3342 2014-09-19 12:22:05Z bradbell $ */
2# ifndef CPPAD_REV_JAC_SWEEP_INCLUDED
3# define CPPAD_REV_JAC_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
16namespace CppAD { // BEGIN_CPPAD_NAMESPACE
17/*!
18\file rev_jac_sweep.hpp
19Compute Reverse mode Jacobian sparsity patterns.
20*/
21
22/*!
23\def CPPAD_REV_JAC_SWEEP_TRACE
24This value is either zero or one.
25Zero is the normal operational value.
26If it is one, a trace of every rev_jac_sweep computation is printed.
27*/
28# define CPPAD_REV_JAC_SWEEP_TRACE 0
29
30/*
31\def CPPAD_ATOMIC_CALL
32This avoids warnings when NDEBUG is defined and user_ok is not used.
33If \c NDEBUG is defined, this resolves to
34\code
35        user_atom->rev_sparse_jac
36\endcode
37otherwise, it respolves to
38\code
39        user_ok = user_atom->rev_sparse_jac
40\endcode
41This maco is undefined at the end of this file to facillitate is
42use with a different definition in other files.
43*/
44# ifdef NDEBUG
45# define CPPAD_ATOMIC_CALL user_atom->rev_sparse_jac
46# else
47# define CPPAD_ATOMIC_CALL user_ok = user_atom->rev_sparse_jac
48# endif
49
50/*!
51Given the sparsity pattern for the dependent variables,
52RevJacSweep computes the sparsity pattern for all the independent variables.
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\tparam Vector_set
60is the type used for vectors of sets. It can be either
61\c sparse_pack, \c sparse_set, or \c sparse_list.
62
63\param nz_compare
64Are the derivatives with respect to left and right of the expression below
65considered to be non-zero:
66\code
67        CondExpRel(left, right, if_true, if_false)
68\endcode
69This is used by the optimizer to obtain the correct dependency relations.
70
71\param n
72is the number of independent variables on the tape.
73
74\param num_var
75is the total number of variables on the tape; i.e.,
76\a play->num_var_rec().
77This is also the number of rows in the entire sparsity pattern \a RevJac.
78
79\param play
80The information stored in \a play
81is a recording of the operations corresponding to a function
82\f[
83        F : {\bf R}^n \rightarrow {\bf R}^m
84\f]
85where \f$ n \f$ is the number of independent variables
86and \f$ m \f$ is the number of dependent variables.
87The object \a play is effectly constant.
88It is not declared const because while playing back the tape
89the object \a play holds information about the currentl location
90with in the tape and this changes during playback.
91
92\param var_sparsity
93For i = 0 , ... , \a num_var - 1,
94(all the variables on the tape)
95the forward Jacobian sparsity pattern for variable i
96corresponds to the set with index i in \a var_sparsity.
97\b
98\b
99\b Input:
100For i = 0 , ... , \a num_var - 1,
101the forward Jacobian sparsity pattern for variable i is an input
102if i corresponds to a dependent variable.
103Otherwise the sparsity patten is empty.
104\n
105\n
106\b Output: For j = 1 , ... , \a n,
107the sparsity pattern for the dependent variable with index (j-1)
108is given by the set with index index j in \a var_sparsity.
109*/
110
111template <class Base, class Vector_set>
112void RevJacSweep(
113        bool                  nz_compare,
114        size_t                n,
115        size_t                num_var,
116        player<Base>         *play,
117        Vector_set&           var_sparsity
118)
119{
120        OpCode           op;
121        size_t         i_op;
122        size_t        i_var;
123
124        const addr_t*   arg = CPPAD_NULL;
125
126        size_t            i, j, k;
127
128        // length of the parameter vector (used by CppAD assert macros)
129        const size_t num_par = play->num_par_rec();
130
131        // check num_var argument
132        CPPAD_ASSERT_UNKNOWN( num_var > 0 );
133        CPPAD_ASSERT_UNKNOWN( play->num_var_rec()   == num_var );
134        CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == num_var );
135
136        // upper limit (exclusive) for elements in the set
137        size_t limit = var_sparsity.end();
138
139        // vecad_sparsity contains a sparsity pattern for each VecAD object.
140        // vecad_ind maps a VecAD index (beginning of the VecAD object)
141        // to the index of the corresponding set in vecad_sparsity.
142        size_t num_vecad_ind   = play->num_vec_ind_rec();
143        size_t num_vecad_vec   = play->num_vecad_vec_rec();
144        Vector_set  vecad_sparsity;
145        vecad_sparsity.resize(num_vecad_vec, limit);
146        pod_vector<size_t> vecad_ind;
147        if( num_vecad_vec > 0 )
148        {       size_t length;
149                vecad_ind.extend(num_vecad_ind);
150                j             = 0;
151                for(i = 0; i < num_vecad_vec; i++)
152                {       // length of this VecAD
153                        length   = play->GetVecInd(j);
154                        // set to proper index for this VecAD
155                        vecad_ind[j] = i; 
156                        for(k = 1; k <= length; k++)
157                                vecad_ind[j+k] = num_vecad_vec; // invalid index
158                        // start of next VecAD
159                        j       += length + 1;
160                }
161                CPPAD_ASSERT_UNKNOWN( j == play->num_vec_ind_rec() );
162        }
163
164        // work space used by UserOp.
165        typedef std::set<size_t> size_set;
166        size_set::iterator set_itr;  // iterator for a standard set
167        size_set::iterator set_end;  // end of iterator sequence
168        vector< size_set > set_r;   // set sparsity pattern for the argument x
169        vector< size_set > set_s;   // set sparisty pattern for the result y
170        //
171        vector<bool>       bool_r;   // bool sparsity pattern for the argument x
172        vector<bool>       bool_s;   // bool sparisty pattern for the result y
173        //
174        const size_t user_q = limit; // maximum element plus one
175        size_t user_index = 0;       // indentifier for this atomic operation
176        size_t user_id    = 0;       // user identifier for this call to operator
177        size_t user_i     = 0;       // index in result vector
178        size_t user_j     = 0;       // index in argument vector
179        size_t user_m     = 0;       // size of result vector
180        size_t user_n     = 0;       // size of arugment vector
181        //
182        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
183        bool               user_bool = false;      // use bool or set sparsity ?
184# ifndef NDEBUG
185        bool               user_ok   = false;      // atomic op return value
186# endif
187        // next expected operator in a UserOp sequence
188        enum { user_start, user_arg, user_ret, user_end } user_state = user_end;
189
190        // Initialize
191        play->reverse_start(op, arg, i_op, i_var);
192        CPPAD_ASSERT_UNKNOWN( op == EndOp );
193# if CPPAD_REV_JAC_SWEEP_TRACE
194        std::cout << std::endl;
195        CppAD::vectorBool z_value(limit);
196
197        // 2DO: implement tracing cache
198        CppAD::vector<addr_t> cache2var;
199# endif
200        bool more_operators = true;
201        while(more_operators)
202        {
203                // next op
204                play->reverse_next(op, arg, i_op, i_var);
205# ifndef NDEBUG
206                if( i_op <= n )
207                {       CPPAD_ASSERT_UNKNOWN((op == InvOp) | (op == BeginOp));
208                }
209                else    CPPAD_ASSERT_UNKNOWN((op != InvOp) & (op != BeginOp));
210# endif
211
212                // rest of information depends on the case
213                switch( op )
214                {
215                        case AbsOp:
216                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
217                        reverse_sparse_jacobian_unary_op(
218                                i_var, arg[0], var_sparsity
219                        );
220                        break;
221                        // -------------------------------------------------
222
223                        case AddvvOp:
224                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
225                        reverse_sparse_jacobian_binary_op(
226                                i_var, arg, var_sparsity
227                        );
228                        break;
229                        // -------------------------------------------------
230
231                        case AddpvOp:
232                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
233                        reverse_sparse_jacobian_unary_op(
234                                i_var, arg[1], var_sparsity
235                        );
236                        break;
237                        // -------------------------------------------------
238
239                        case AcosOp:
240                        // sqrt(1 - x * x), acos(x)
241                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
242                        reverse_sparse_jacobian_unary_op(
243                                i_var, arg[0], var_sparsity
244                        );
245                        break;
246                        // -------------------------------------------------
247
248                        case AsinOp:
249                        // sqrt(1 - x * x), asin(x)
250                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
251                        reverse_sparse_jacobian_unary_op(
252                                i_var, arg[0], var_sparsity
253                        );
254                        break;
255                        // -------------------------------------------------
256
257                        case AtanOp:
258                        // 1 + x * x, atan(x)
259                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
260                        reverse_sparse_jacobian_unary_op(
261                                i_var, arg[0], var_sparsity
262                        );
263                        break;
264                        // -------------------------------------------------
265
266                        case BeginOp:
267                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
268                        more_operators = false;
269                        break;
270                        // -------------------------------------------------
271
272                        case CSkipOp:
273                        // CSkipOp has a variable number of arguments and
274                        // reverse_next thinks it one has one argument.
275                        // We must inform reverse_next of this special case.
276                        play->reverse_cskip(op, arg, i_op, i_var);
277                        break;
278                        // -------------------------------------------------
279
280                        case CSumOp:
281                        // CSumOp has a variable number of arguments and
282                        // reverse_next thinks it one has one argument.
283                        // We must inform reverse_next of this special case.
284                        play->reverse_csum(op, arg, i_op, i_var);
285                        reverse_sparse_jacobian_csum_op(
286                                i_var, arg, var_sparsity
287                        );
288                        break;
289                        // -------------------------------------------------
290
291                        case CExpOp:
292                        reverse_sparse_jacobian_cond_op(
293                                nz_compare, i_var, arg, num_par, var_sparsity
294                        );
295                        break;
296                        // ---------------------------------------------------
297
298                        case ComOp:
299                        CPPAD_ASSERT_NARG_NRES(op, 4, 0);
300                        CPPAD_ASSERT_UNKNOWN( arg[1] > 1 );
301                        break;
302                        // --------------------------------------------------
303
304                        case CosOp:
305                        // sin(x), cos(x)
306                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
307                        reverse_sparse_jacobian_unary_op(
308                                i_var, arg[0], var_sparsity
309                        );
310                        break;
311                        // ---------------------------------------------------
312
313                        case CoshOp:
314                        // sinh(x), cosh(x)
315                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
316                        reverse_sparse_jacobian_unary_op(
317                                i_var, arg[0], var_sparsity
318                        );
319                        break;
320                        // -------------------------------------------------
321
322                        case DisOp:
323                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
324                        // derivative is identically zero
325                        break;
326                        // -------------------------------------------------
327
328                        case DivvvOp:
329                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
330                        reverse_sparse_jacobian_binary_op(
331                                i_var, arg, var_sparsity
332                        );
333                        break;
334                        // -------------------------------------------------
335
336                        case DivpvOp:
337                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
338                        reverse_sparse_jacobian_unary_op(
339                                i_var, arg[1], var_sparsity
340                        );
341                        break;
342                        // -------------------------------------------------
343
344                        case DivvpOp:
345                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
346                        reverse_sparse_jacobian_unary_op(
347                                i_var, arg[0], var_sparsity
348                        );
349                        break;
350                        // -------------------------------------------------
351
352                        case ExpOp:
353                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
354                        reverse_sparse_jacobian_unary_op(
355                                i_var, arg[0], var_sparsity
356                        );
357                        break;
358                        // -------------------------------------------------
359
360                        case InvOp:
361                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
362                        break;
363                        // -------------------------------------------------
364
365                        case LdpOp:
366                        reverse_sparse_jacobian_load_op(
367                                op,
368                                i_var,
369                                arg,
370                                num_vecad_ind,
371                                vecad_ind.data(),
372                                var_sparsity,
373                                vecad_sparsity
374                        );
375                        break;
376                        // -------------------------------------------------
377
378                        case LdvOp:
379                        reverse_sparse_jacobian_load_op(
380                                op,
381                                i_var,
382                                arg,
383                                num_vecad_ind,
384                                vecad_ind.data(),
385                                var_sparsity,
386                                vecad_sparsity
387                        );
388                        break;
389                        // -------------------------------------------------
390
391                        case LogOp:
392                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
393                        reverse_sparse_jacobian_unary_op(
394                                i_var, arg[0], var_sparsity
395                        );
396                        break;
397                        // -------------------------------------------------
398
399                        case MulvvOp:
400                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
401                        reverse_sparse_jacobian_binary_op(
402                                i_var, arg, var_sparsity
403                        );
404                        break;
405                        // -------------------------------------------------
406
407                        case MulpvOp:
408                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
409                        reverse_sparse_jacobian_unary_op(
410                                i_var, arg[1], var_sparsity
411                        );
412                        break;
413                        // -------------------------------------------------
414
415                        case ParOp:
416                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
417
418                        break;
419                        // -------------------------------------------------
420
421                        case PowvpOp:
422                        reverse_sparse_jacobian_unary_op(
423                                i_var, arg[0], var_sparsity
424                        );
425                        break;
426                        // -------------------------------------------------
427
428                        case PowpvOp:
429                        CPPAD_ASSERT_NARG_NRES(op, 2, 3);
430                        reverse_sparse_jacobian_unary_op(
431                                i_var, arg[1], var_sparsity
432                        );
433                        break;
434                        // -------------------------------------------------
435
436                        case PowvvOp:
437                        CPPAD_ASSERT_NARG_NRES(op, 2, 3);
438                        reverse_sparse_jacobian_binary_op(
439                                i_var, arg, var_sparsity
440                        );
441                        break;
442                        // -------------------------------------------------
443
444                        case PriOp:
445                        CPPAD_ASSERT_NARG_NRES(op, 5, 0);
446                        break;
447                        // -------------------------------------------------
448
449                        case SignOp:
450                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
451                        // derivative is identically zero
452                        break;
453                        // -------------------------------------------------
454
455                        case SinOp:
456                        // cos(x), sin(x)
457                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
458                        reverse_sparse_jacobian_unary_op(
459                                i_var, arg[0], var_sparsity
460                        );
461                        break;
462                        // -------------------------------------------------
463
464                        case SinhOp:
465                        // cosh(x), sinh(x)
466                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
467                        reverse_sparse_jacobian_unary_op(
468                                i_var, arg[0], var_sparsity
469                        );
470                        break;
471                        // -------------------------------------------------
472
473                        case SqrtOp:
474                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
475                        reverse_sparse_jacobian_unary_op(
476                                i_var, arg[0], var_sparsity
477                        );
478                        break;
479                        // -------------------------------------------------
480
481                        case StppOp:
482                        // sparsity cannot proagate through a parameter
483                        CPPAD_ASSERT_NARG_NRES(op, 3, 0);
484                        break;
485                        // -------------------------------------------------
486
487                        case StpvOp:
488                        reverse_sparse_jacobian_store_op(
489                                op,
490                                arg,
491                                num_vecad_ind,
492                                vecad_ind.data(),
493                                var_sparsity,
494                                vecad_sparsity
495                        );
496                        break;
497                        // -------------------------------------------------
498
499                        case StvpOp:
500                        CPPAD_ASSERT_NARG_NRES(op, 3, 0);
501                        break;
502                        // -------------------------------------------------
503
504                        case StvvOp:
505                        reverse_sparse_jacobian_store_op(
506                                op,
507                                arg,
508                                num_vecad_ind,
509                                vecad_ind.data(),
510                                var_sparsity,
511                                vecad_sparsity
512                        );
513                        break;
514                        // -------------------------------------------------
515
516                        case SubvvOp:
517                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
518                        reverse_sparse_jacobian_binary_op(
519                                i_var, arg, var_sparsity
520                        );
521                        break;
522                        // -------------------------------------------------
523
524                        case SubpvOp:
525                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
526                        reverse_sparse_jacobian_unary_op(
527                                i_var, arg[1], var_sparsity
528                        );
529                        break;
530                        // -------------------------------------------------
531
532                        case SubvpOp:
533                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
534                        reverse_sparse_jacobian_unary_op(
535                                i_var, arg[0], var_sparsity
536                        );
537                        break;
538                        // -------------------------------------------------
539
540                        case TanOp:
541                        // tan(x)^2, tan(x)
542                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
543                        reverse_sparse_jacobian_unary_op(
544                                i_var, arg[0], var_sparsity
545                        );
546                        break;
547                        // -------------------------------------------------
548
549                        case TanhOp:
550                        // tanh(x)^2, tanh(x)
551                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
552                        reverse_sparse_jacobian_unary_op(
553                                i_var, arg[0], var_sparsity
554                        );
555                        break;
556                        // -------------------------------------------------
557
558                        case UserOp:
559                        // start or end atomic operation sequence
560                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
561                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
562                        if( user_state == user_end )
563                        {       user_index = arg[0];
564                                user_id    = arg[1];
565                                user_n     = arg[2];
566                                user_m     = arg[3];
567                                user_atom  = atomic_base<Base>::class_object(user_index);
568# ifndef NDEBUG
569                                if( user_atom == CPPAD_NULL )
570                                {       std::string msg = 
571                                                atomic_base<Base>::class_name(user_index)
572                                                + ": atomic_base function has been deleted";
573                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
574                                }
575# endif
576                                user_bool  = user_atom->sparsity() ==
577                                                        atomic_base<Base>::bool_sparsity_enum;
578                                if( user_bool )
579                                {       if( bool_r.size() != user_m * user_q )
580                                                bool_r.resize( user_m * user_q );
581                                        if( bool_s.size() != user_n * user_q )
582                                                bool_s.resize( user_n * user_q );
583                                        for(i = 0; i < user_m; i++)
584                                                for(j = 0; j < user_q; j++)
585                                                        bool_r[ i * user_q + j] = false;
586                                }
587                                else
588                                {       if(set_r.size() != user_m )
589                                                set_r.resize(user_m);
590                                        if(set_s.size() != user_n )
591                                                set_s.resize(user_n);
592                                        for(i = 0; i < user_m; i++)
593                                                set_r[i].clear();
594                                }
595                                user_j     = user_n;
596                                user_i     = user_m;
597                                user_state = user_ret;
598                        }
599                        else
600                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_start );
601                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
602                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
603                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
604                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
605# ifndef NDEBUG
606                                if( ! user_ok )
607                                {       std::string msg = 
608                                                atomic_base<Base>::class_name(user_index)
609                                                + ": atomic_base.rev_sparse_jac: returned false";
610                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
611                                }
612# endif
613                                user_state = user_end;
614               }
615                        break;
616
617                        case UsrapOp:
618                        // parameter argument in an atomic operation sequence
619                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
620                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
621                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
622                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
623                        --user_j;
624                        if( user_j == 0 )
625                                user_state = user_start;
626                        break;
627
628                        case UsravOp:
629                        // variable argument in an atomic operation sequence
630                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
631                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
632                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
633                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
634                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
635                        --user_j;
636                        // It might be faster if we add set union to var_sparsity
637                        // where one of the sets is not in var_sparsity.
638                        if( user_bool )
639                        {       for(j = 0; j < user_q; j++)
640                                        if( bool_s[ user_j * user_q + j ] )     
641                                                var_sparsity.add_element(arg[0], j);   
642                        }
643                        else
644                        {       set_itr = set_s[user_j].begin();
645                                set_end = set_s[user_j].end();
646                                while( set_itr != set_end )
647                                        var_sparsity.add_element(arg[0], *set_itr++);   
648                        }
649                        if( user_j == 0 )
650                                user_state = user_start;
651                        break;
652
653                        case UsrrpOp:
654                        // parameter result in an atomic operation sequence
655                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
656                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
657                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
658                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
659                        --user_i;
660                        if( user_i == 0 )
661                        {       // call users function for this operation
662                                user_atom->set_id(user_id);
663                                if( user_bool) 
664                                        CPPAD_ATOMIC_CALL(
665                                                user_q, bool_r, bool_s
666                                );
667                                else
668                                        CPPAD_ATOMIC_CALL(
669                                                user_q, set_r, set_s
670                                );
671                                user_state = user_arg;
672                        }
673                        break;
674
675                        case UsrrvOp:
676                        // variable result in an atomic operation sequence
677                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
678                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
679                        --user_i;
680                        var_sparsity.begin(i_var);
681                        i = var_sparsity.next_element();
682                        while( i < user_q )
683                        {       if( user_bool )
684                                        bool_r[ user_i * user_q + i ] = true;
685                                        else
686                                                set_r[user_i].insert(i);
687                                i = var_sparsity.next_element();
688                        }
689                        if( user_i == 0 )
690                        {       // call users function for this operation
691                                user_atom->set_id(user_id);
692                                if( user_bool) 
693                                        CPPAD_ATOMIC_CALL(
694                                                user_q, bool_r, bool_s
695                                );
696                                else
697                                        CPPAD_ATOMIC_CALL(
698                                                user_q, set_r, set_s
699                                );
700                                user_state = user_arg;
701                        }
702                        break;
703                        // -------------------------------------------------
704
705                        default:
706                        CPPAD_ASSERT_UNKNOWN(0);
707                }
708# if CPPAD_REV_JAC_SWEEP_TRACE
709                for(j = 0; j < limit; j++)
710                        z_value[j] = false;
711                var_sparsity.begin(i_var);
712                j = var_sparsity.next_element();
713                while( j < limit )
714                {       z_value[j] = true;
715                        j          = var_sparsity.next_element();
716                }
717                printOp(
718                        std::cout, 
719                        play,
720                        i_op,
721                        i_var,
722                        op, 
723                        arg,
724                        num_var,
725                        cache2var
726                );
727                if( NumRes(op) > 0 && op != BeginOp ) printOpResult(
728                        std::cout, 
729                        0, 
730                        (CppAD::vectorBool *) CPPAD_NULL,
731                        1, 
732                        &z_value
733                );
734                std::cout << std::endl;
735        }
736        std::cout << std::endl;
737# else
738        }
739# endif
740        // values corresponding to BeginOp
741        CPPAD_ASSERT_UNKNOWN( i_op == 0 );
742        CPPAD_ASSERT_UNKNOWN( i_var == 0 );
743
744        return;
745}
746} // END_CPPAD_NAMESPACE
747
748// preprocessor symbols that are local to this file
749# undef CPPAD_REV_JAC_SWEEP_TRACE
750# undef CPPAD_ATOMIC_CALL
751
752# endif
Note: See TracBrowser for help on using the repository browser.