source: trunk/cppad/local/for_hes_sweep.hpp @ 3804

Last change on this file since 3804 was 3804, checked in by bradbell, 4 years ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 8dd8b10d36b325a3f4bbf3c03f1ea00e288331ae
end hash code: 624601e5e709d2872b5873f628fae76d5f575a9b

commit 624601e5e709d2872b5873f628fae76d5f575a9b
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 07:28:40 2016 -0700

Advance version to 20160320.

commit e1c5beb2bd5a445e08ca84ce6fc91728bae51678
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 07:24:09 2016 -0700

matrix branch:
check_addon.sh: check for use of addon reserved symbols.

commit fe7791a4bcee56631c6fbc7acc91d842c1d0bf0c
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 06:50:42 2016 -0700

matrix branch:
whats_new_16.omh: user's view of most recent changes.

commit fd8d5b9e101e6337b052c819892258c2682b533a
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 06:32:07 2016 -0700

matrix branch:
Add sub-directory names to #ifndef names in remaining *.hpp files.

commit 23e6fdf57bcad1fe0e618b36288b11800a9c40fc
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 05:17:06 2016 -0700

matrix branch:
check_include_def.sh: check for CPPAD_EXAMPLE name conflict.
batch_edit.sh: fix case where moving directory.

commit 3ff379548fecea2563713047f6e35a93928678af
Author: Brad Bell <bradbell@…>
Date: Sun Mar 20 04:51:46 2016 -0700

matrix branch:
Add sub-directory name to # ifndef names in cppad/*/*.hpp files.

commit f5651065f2e3cdbcd2839f7d7181d423d9a9906b
Author: Brad Bell <bradbell@…>
Date: Sat Mar 19 07:38:12 2016 -0700

matrix branch:
Move atomic_matrix_mul.hpp -> atomic_mat_mul.hpp.

commit 974b63e6362aa4162a70323db932493acc9fed17
Author: Brad Bell <bradbell@…>
Date: Sat Mar 19 07:11:08 2016 -0700

matrix branch:
Move atomic_mat_mul.cpp -> atomic_mat_mul_xam.cpp.

commit 21c23d7ef18d8cf0a56d39873da12a10eb129804
Author: Brad Bell <bradbell@…>
Date: Sat Mar 19 04:40:05 2016 -0700

checkpoint.hpp: Mention in doc that forward mode gets recomputed.

File size: 17.8 KB
Line 
1// $Id$
2# ifndef CPPAD_LOCAL_FOR_HES_SWEEP_HPP
3# define CPPAD_LOCAL_FOR_HES_SWEEP_HPP
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-16 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_hes_sweep.hpp
19Compute Forward mode Hessian sparsity patterns.
20*/
21
22/*!
23\def CPPAD_FOR_HES_SWEEP_TRACE
24This value is either zero or one.
25Zero is the normal operational value.
26If it is one, a trace of every rev_hes_sweep computation is printed.
27*/
28# define CPPAD_FOR_HES_SWEEP_TRACE 0
29
30/*!
31Given the forward Jacobian sparsity pattern for all the variables,
32and the reverse Jacobian sparsity pattern for the dependent variables,
33ForHesSweep computes the Hessian sparsity pattern for all the independent
34variables.
35
36\tparam Base
37base type for the operator; i.e., this operation sequence was recorded
38using AD< \a Base > and computations by this routine are done using type
39\a Base.
40
41\tparam Vector_set
42is the type used for vectors of sets. It can be either
43sparse_pack or sparse_list.
44
45\param n
46is the number of independent variables on the tape.
47
48\param numvar
49is the total number of variables on the tape; i.e.,
50\a play->num_var_rec().
51This is also the number of rows in the entire sparsity pattern
52\a for_hes_sparse.
53
54\param play
55The information stored in \a play
56is a recording of the operations corresponding to a function
57\f[
58        F : {\bf R}^n \rightarrow {\bf R}^m
59\f]
60where \f$ n \f$ is the number of independent variables
61and \f$ m \f$ is the number of dependent variables.
62The object \a play is effectly constant.
63It is not declared const because while playing back the tape
64the object \a play holds information about the current location
65with in the tape and this changes during playback.
66
67\param for_jac_sparse
68For i = 0 , ... , \a numvar - 1,
69(for all the variables on the tape),
70the forward Jacobian sparsity pattern for the variable with index i
71corresponds to the set with index i in \a for_jac_sparse.
72
73\param rev_jac_sparse
74\b Input:
75For i = 0, ... , \a numvar - 1
76the if the function we are computing the Hessian for has a non-zero
77derivative w.r.t. variable with index i,
78the set with index i has element zero.
79Otherwise it has no elements.
80
81\param for_hes_sparse
82The reverse Hessian sparsity pattern for the variable with index i
83corresponds to the set with index i in \a for_hes_sparse.
84The number of rows in this sparsity patter is n+1 and the row
85with index zero is not used.
86\n
87\n
88\b Input: For i = 1 , ... , \a n
89the reverse Hessian sparsity pattern for the variable with index i is empty.
90\n
91\n
92\b Output: For j = 1 , ... , \a n,
93the reverse Hessian sparsity pattern for the independent dependent variable
94with index (j-1) is given by the set with index j
95in \a for_hes_sparse.
96*/
97
98template <class Base, class Vector_set>
99void ForHesSweep(
100        size_t                n,
101        size_t                numvar,
102        player<Base>         *play,
103        Vector_set&           for_jac_sparse, // should be const
104        Vector_set&           rev_jac_sparse, // should be const
105        Vector_set&           for_hes_sparse
106)
107{
108        OpCode           op;
109        size_t         i_op;
110        size_t        i_var;
111
112        const addr_t*   arg = CPPAD_NULL;
113
114        // length of the parameter vector (used by CppAD assert macros)
115# ifndef NDEBUG
116        const size_t num_par = play->num_par_rec();
117# endif
118
119        size_t             i, j, k;
120
121        // check numvar argument
122        size_t limit = n+1;
123        CPPAD_ASSERT_UNKNOWN( play->num_var_rec()    == numvar );
124        CPPAD_ASSERT_UNKNOWN( for_jac_sparse.n_set() == numvar );
125        CPPAD_ASSERT_UNKNOWN( for_hes_sparse.n_set() == limit );
126        CPPAD_ASSERT_UNKNOWN( numvar > 0 );
127
128        // upper limit exclusive for set elements
129        CPPAD_ASSERT_UNKNOWN( for_jac_sparse.end() == limit );
130        CPPAD_ASSERT_UNKNOWN( for_hes_sparse.end() == limit );
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 for the corresponding set in vecad_sparsity.
135        size_t num_vecad_ind   = play->num_vec_ind_rec();
136        size_t num_vecad_vec   = play->num_vecad_vec_rec();
137        Vector_set vecad_sparse;
138        vecad_sparse.resize(num_vecad_vec, limit);
139        pod_vector<size_t> vecad_ind;
140        pod_vector<bool>   vecad_jac;
141        if( num_vecad_vec > 0 )
142        {       size_t length;
143                vecad_ind.extend(num_vecad_ind);
144                vecad_jac.extend(num_vecad_vec);
145                j             = 0;
146                for(i = 0; i < num_vecad_vec; i++)
147                {       // length of this VecAD
148                        length   = play->GetVecInd(j);
149                        // set vecad_ind to proper index for this VecAD
150                        vecad_ind[j] = i;
151                        // make all other values for this vector invalid
152                        for(k = 1; k <= length; k++)
153                                vecad_ind[j+k] = num_vecad_vec;
154                        // start of next VecAD
155                        j       += length + 1;
156                        // initialize this vector's reverse jacobian value
157                        vecad_jac[i] = false;
158                }
159                CPPAD_ASSERT_UNKNOWN( j == play->num_vec_ind_rec() );
160        }
161
162        // work space used by UserOp.
163        vector<size_t>     user_ix;  // variable indices for argument vector x
164        //
165        //
166        typedef std::set<size_t> size_set;
167        vector< size_set > set_h;    // forward Hessian sparsity
168        vector<bool>       bool_h;   // forward Hessian sparsity
169        vectorBool         pack_h;   // forward Hessian sparstiy
170        //
171        vector<bool>       user_vx;  // which components of x are variables
172        vector<bool>       user_r;   // forward Jacobian sparsity for x
173        vector<bool>       user_s;   // reverse Jacobian sparsity for y
174        //
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_pack = false;      // sparsity pattern type is pack
184        bool               user_bool = false;      // sparsity pattern type is bool
185        bool               user_set  = false;      // sparsity pattern type is set
186# ifndef NDEBUG
187        bool               user_ok   = false;      // atomic op return value
188# endif
189        // next expected operator in a UserOp sequence
190        enum { user_start, user_arg, user_ret, user_end } user_state = user_start;
191
192        // Initialize
193        play->forward_start(op, arg, i_op, i_var);
194        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
195        bool more_operators = true;
196# if CPPAD_FOR_HES_SWEEP_TRACE
197        std::cout << std::endl;
198        CppAD::vectorBool zf_value(limit);
199        CppAD::vectorBool zh_value(limit * limit);
200# endif
201        while(more_operators)
202        {
203                // next op
204                play->forward_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                // does the Hessian in question have a non-zero derivative
213                // with respect to this variable
214                bool include = rev_jac_sparse.is_element(i_var, 0);
215                //
216                // operators to include even if derivative is zero
217                include |= op == EndOp;
218                include |= op == CSkipOp;
219                include |= op == UserOp;
220                include |= op == UsrapOp;
221                include |= op == UsravOp;
222                include |= op == UsrrpOp;
223                include |= op == UsrrvOp;
224                //
225                if( include ) switch( op )
226                {       // operators that should not occurr
227                        // case BeginOp
228                        // -------------------------------------------------
229
230                        // operators that do not affect hessian
231                        case AbsOp:
232                        case AddvvOp:
233                        case AddpvOp:
234                        case CExpOp:
235                        case DisOp:
236                        case DivvpOp:
237                        case InvOp:
238                        case LdpOp:
239                        case LdvOp:
240                        case MulpvOp:
241                        case ParOp:
242                        case PriOp:
243                        case SignOp:
244                        case StppOp:
245                        case StpvOp:
246                        case StvpOp:
247                        case StvvOp:
248                        case SubvvOp:
249                        case SubpvOp:
250                        case SubvpOp:
251                        case ZmulpvOp:
252                        case ZmulvpOp:
253                        break;
254                        // -------------------------------------------------
255
256                        // nonlinear unary operators
257                        case AcosOp:
258                        case AsinOp:
259                        case AtanOp:
260                        case CosOp:
261                        case CoshOp:
262                        case ExpOp:
263                        case LogOp:
264                        case SinOp:
265                        case SinhOp:
266                        case SqrtOp:
267                        case TanOp:
268                        case TanhOp:
269# if CPPAD_USE_CPLUSPLUS_2011
270                        case AcoshOp:
271                        case AsinhOp:
272                        case AtanhOp:
273                        case Expm1Op:
274                        case Log1pOp:
275# endif
276                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 )
277                        forward_sparse_hessian_nonlinear_unary_op(
278                                arg[0], for_jac_sparse, for_hes_sparse
279                        );
280                        break;
281                        // -------------------------------------------------
282
283                        case CSkipOp:
284                        // CSkipOp has a variable number of arguments and
285                        // reverse_next thinks it one has one argument.
286                        // We must inform reverse_next of this special case.
287                        play->reverse_cskip(op, arg, i_op, i_var);
288                        break;
289                        // -------------------------------------------------
290
291                        case CSumOp:
292                        // CSumOp has a variable number of arguments and
293                        // reverse_next thinks it one has one argument.
294                        // We must inform reverse_next of this special case.
295                        play->reverse_csum(op, arg, i_op, i_var);
296                        break;
297                        // -------------------------------------------------
298
299                        case DivvvOp:
300                        CPPAD_ASSERT_NARG_NRES(op, 2, 1)
301                        forward_sparse_hessian_div_op(
302                                arg, for_jac_sparse, for_hes_sparse
303                        );
304                        break;
305                        // -------------------------------------------------
306
307                        case DivpvOp:
308                        CPPAD_ASSERT_NARG_NRES(op, 2, 1)
309                        forward_sparse_hessian_nonlinear_unary_op(
310                                arg[1], for_jac_sparse, for_hes_sparse
311                        );
312                        break;
313                        // -------------------------------------------------
314
315                        case EndOp:
316                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
317                        more_operators = false;
318                        break;
319                        // -------------------------------------------------
320
321                        case ErfOp:
322                        // arg[1] is always the parameter 0
323                        // arg[2] is always the parameter 2 / sqrt(pi)
324                        CPPAD_ASSERT_NARG_NRES(op, 3, 5);
325                        forward_sparse_hessian_nonlinear_unary_op(
326                                arg[0], for_jac_sparse, for_hes_sparse
327                        );
328                        break;
329                        // -------------------------------------------------
330
331                        // -------------------------------------------------
332                        // logical comparision operators
333                        case EqpvOp:
334                        case EqvvOp:
335                        case LtpvOp:
336                        case LtvpOp:
337                        case LtvvOp:
338                        case LepvOp:
339                        case LevpOp:
340                        case LevvOp:
341                        case NepvOp:
342                        case NevvOp:
343                        CPPAD_ASSERT_NARG_NRES(op, 2, 0);
344                        break;
345                        // -------------------------------------------------
346
347                        case MulvvOp:
348                        CPPAD_ASSERT_NARG_NRES(op, 2, 1)
349                        forward_sparse_hessian_mul_op(
350                                arg, for_jac_sparse, for_hes_sparse
351                        );
352                        break;
353                        // -------------------------------------------------
354
355                        case PowpvOp:
356                        CPPAD_ASSERT_NARG_NRES(op, 2, 3)
357                        forward_sparse_hessian_nonlinear_unary_op(
358                                arg[1], for_jac_sparse, for_hes_sparse
359                        );
360                        break;
361                        // -------------------------------------------------
362
363                        case PowvpOp:
364                        CPPAD_ASSERT_NARG_NRES(op, 2, 3)
365                        forward_sparse_hessian_nonlinear_unary_op(
366                                arg[0], for_jac_sparse, for_hes_sparse
367                        );
368                        break;
369                        // -------------------------------------------------
370
371                        case PowvvOp:
372                        CPPAD_ASSERT_NARG_NRES(op, 2, 3)
373                        forward_sparse_hessian_pow_op(
374                                arg, for_jac_sparse, for_hes_sparse
375                        );
376                        break;
377                        // -------------------------------------------------
378
379                        case UserOp:
380                        // start or end an atomic operation sequence
381                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
382                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
383                        if( user_state == user_start )
384                        {       user_index = arg[0];
385                                user_id    = arg[1];
386                                user_n     = arg[2];
387                                user_m     = arg[3];
388                                user_atom  = atomic_base<Base>::class_object(user_index);
389# ifndef NDEBUG
390                                if( user_atom == CPPAD_NULL )
391                                {       std::string msg =
392                                                atomic_base<Base>::class_name(user_index)
393                                                + ": atomic_base function has been deleted";
394                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
395                                }
396# endif
397                                user_pack  = user_atom->sparsity() ==
398                                                        atomic_base<Base>::pack_sparsity_enum;
399                                user_bool  = user_atom->sparsity() ==
400                                                        atomic_base<Base>::bool_sparsity_enum;
401                                user_set   = user_atom->sparsity() ==
402                                                        atomic_base<Base>::set_sparsity_enum;
403                                CPPAD_ASSERT_UNKNOWN( user_pack || user_bool || user_set );
404                                user_ix.resize(user_n);
405                                user_vx.resize(user_n);
406                                user_r.resize(user_n);
407                                user_s.resize(user_m);
408
409                                // simpler to initialize sparsity patterns as empty
410                                for(i = 0; i < user_m; i++)
411                                        user_s[i] = false;
412                                for(i = 0; i < user_n; i++)
413                                        user_r[i] = false;
414                                if( user_pack )
415                                {       pack_h.resize(user_n * user_n);
416                                        for(i = 0; i < user_n; i++)
417                                        {       for(j = 0; j < user_n; j++)
418                                                        pack_h[ i * user_n + j] = false;
419                                        }
420                                }
421                                if( user_bool )
422                                {       bool_h.resize(user_n * user_n);
423                                        for(i = 0; i < user_n; i++)
424                                        {       for(j = 0; j < user_n; j++)
425                                                        bool_h[ i * user_n + j] = false;
426                                        }
427                                }
428                                if( user_set )
429                                {       set_h.resize(user_n);
430                                        for(i = 0; i < user_n; i++)
431                                                set_h[i].clear();
432                                }
433                                user_j     = 0;
434                                user_i     = 0;
435                                user_state = user_arg;
436                        }
437                        else
438                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
439                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
440                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
441                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
442                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
443
444                                // call users function for this operation
445                                user_atom->set_id(user_id);
446# ifdef NDEBUG
447                                if( user_pack )
448                                        user_atom->for_sparse_hes(
449                                                user_vx, user_r, user_s, pack_h
450                                );
451                                if( user_bool )
452                                        user_atom->for_sparse_hes(
453                                                user_vx, user_r, user_s, bool_h
454                                );
455                                if( user_set )
456                                        user_atom->for_sparse_hes(
457                                                user_vx, user_r, user_s, set_h
458                                );
459# else
460                                if( user_pack )
461                                        user_ok = user_atom->for_sparse_hes(
462                                                user_vx, user_r, user_s, pack_h
463                                );
464                                if( user_bool )
465                                        user_ok = user_atom->for_sparse_hes(
466                                                user_vx, user_r, user_s, bool_h
467                                );
468                                if( user_set )
469                                        user_ok = user_atom->for_sparse_hes(
470                                                user_vx, user_r, user_s, set_h
471                                );
472                                if( ! user_ok )
473                                {       std::string msg =
474                                                atomic_base<Base>::class_name(user_index)
475                                                + ": atomic_base.for_sparse_hes: returned false\n";
476                                        if( user_pack )
477                                                msg += "sparsity = pack_sparsity_enum";
478                                        if( user_bool )
479                                                msg += "sparsity = bool_sparsity_enum";
480                                        if( user_set )
481                                                msg += "sparsity = set_sparsity_enum";
482                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
483                                }
484# endif
485                                for(i = 0; i < user_n; i++)     for(j = 0; j < user_n; j++)
486                                {       if( user_ix[i] > 0 && user_ix[j] > 0 )
487                                        {       bool flag = false;
488                                                if( user_pack )
489                                                        flag = pack_h[i * user_n + j];
490                                                if( user_bool )
491                                                        flag = bool_h[i * user_n + j];
492                                                if( user_set )
493                                                        flag = set_h[i].find(j) != set_h[i].end();
494                                                if( flag )
495                                                {       size_t i_x = user_ix[i];
496                                                        size_t j_x = user_ix[j];
497                                                        for_hes_sparse.binary_union(
498                                                                i_x, i_x, j_x, for_jac_sparse
499                                                        );
500                                                        for_hes_sparse.binary_union(
501                                                                j_x, j_x, i_x, for_jac_sparse
502                                                        );
503                                                }
504                                        }
505                                }
506                                //
507                                user_state = user_start;
508                        }
509                        break;
510
511                        case UsrapOp:
512                        // parameter argument in an atomic operation sequence
513                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
514                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
515                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
516                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
517                        user_ix[user_j] = 0;
518                        user_vx[user_j] = false;
519                        ++user_j;
520                        if( user_j == n )
521                                user_state = user_ret;
522                        break;
523
524                        case UsravOp:
525                        // variable argument in an atomic operation sequence
526                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
527                        CPPAD_ASSERT_UNKNOWN(  user_j < user_n );
528                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
529                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
530                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
531                        user_ix[user_j] = arg[0];
532                        user_vx[user_j] = true;
533                        for_jac_sparse.begin(arg[0]);
534                        i = for_jac_sparse.next_element();
535                        if( i < for_jac_sparse.end() )
536                                user_r[user_j] = true;
537                        ++user_j;
538                        if( user_j == n )
539                                user_state = user_ret;
540                        break;
541
542                        case UsrrpOp:
543                        // parameter result in an atomic operation sequence
544                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
545                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
546                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
547                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
548                        ++user_i;
549                        if( user_i == user_m )
550                                user_state = user_end;
551                        break;
552
553                        case UsrrvOp:
554                        // variable result in an atomic operation sequence
555                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
556                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
557                        if( rev_jac_sparse.is_element(i_var, 0) )
558                                user_s[user_i] = true;
559                        ++user_i;
560                        if( user_i == user_m )
561                                user_state = user_end;
562                        break;
563                        // -------------------------------------------------
564
565                        case ZmulvvOp:
566                        CPPAD_ASSERT_NARG_NRES(op, 2, 1)
567                        forward_sparse_hessian_mul_op(
568                                arg, for_jac_sparse, for_hes_sparse
569                        );
570                        break;
571
572                        // -------------------------------------------------
573
574                        default:
575                        CPPAD_ASSERT_UNKNOWN(0);
576                }
577# if CPPAD_FOR_HES_SWEEP_TRACE
578                if( include )
579                {       for(i = 0; i < limit; i++)
580                        {       zf_value[i] = false;
581                                for(j = 0; j < limit; j++)
582                                        zh_value[i * limit + j] = false;
583                        }
584                        for_jac_sparse.begin(i_var);;
585                        j = for_jac_sparse.next_element();;
586                        while( j < limit )
587                        {       zf_value[j] = true;
588                                j = for_jac_sparse.next_element();
589                        }
590                        for(i = 0; i < limit; i++)
591                        {       for_hes_sparse.begin(i);;
592                                j = for_hes_sparse.next_element();;
593                                while( j < limit )
594                                {       zh_value[i * limit + j] = true;
595                                        j = for_hes_sparse.next_element();
596                                }
597                        }
598                        printOp(
599                                std::cout,
600                                play,
601                                i_op,
602                                i_var,
603                                op,
604                                arg
605                        );
606                        // should also print RevJac[i_var], but printOpResult does not
607                        // yet allow for this
608                        if( NumRes(op) > 0 && op != BeginOp ) printOpResult(
609                                std::cout,
610                                1,
611                                &zf_value,
612                                1,
613                                &zh_value
614                        );
615                        std::cout << std::endl;
616                }
617        }
618        std::cout << std::endl;
619# else
620        }
621# endif
622        // value corresponding to EndOp
623        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
624
625        return;
626}
627} // END_CPPAD_NAMESPACE
628
629// preprocessor symbols that are local to this file
630# undef CPPAD_FOR_HES_SWEEP_TRACE
631
632# endif
Note: See TracBrowser for help on using the repository browser.