source: trunk/cppad/local/rev_hes_sweep.hpp @ 2625

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

Change comment so end of group is included in doxygen processing
(do not know why works without this command at end).

ad_assign.hpp: fix doxygen brief description.
ad_ctor.hpp: fix doxygen brief description.

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