source: trunk/cppad/local/rev_jac_sweep.hpp @ 2910

Last change on this file since 2910 was 2910, checked in by bradbell, 7 years ago

Remove CPPAD_BEGIN_NAMESPACE, CPPAD_END_NAMESPACE, and instead use

namespace CppAD { BEGIN_CPPAD_NAMESPACE
}
END_CPPAD_NAMESPACE

becasue doxygen 1.8.3 gets confused when using a macro for this purpose
(begining and ending the CppAD namespace without indenting code).

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