CppAD: A C++ Algorithmic Differentiation Package  20130102
rev_hes_sweep.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_REV_HES_SWEEP_INCLUDED
00003 # define CPPAD_REV_HES_SWEEP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-12 Bradley M. Bell
00007 
00008 CppAD is distributed under multiple licenses. This distribution is under
00009 the terms of the 
00010                     Eclipse Public License Version 1.0.
00011 
00012 A copy of this license is included in the COPYING file of this distribution.
00013 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
00014 -------------------------------------------------------------------------- */
00015 
00016 CPPAD_BEGIN_NAMESPACE
00017 /*!
00018 \defgroup rev_hes_sweep_hpp rev_hes_sweep.hpp
00019 \{
00020 \file rev_hes_sweep.hpp
00021 Compute Reverse mode Hessian sparsity patterns.
00022 */
00023 
00024 /*!
00025 \def CPPAD_REV_HES_SWEEP_TRACE
00026 This value is either zero or one. 
00027 Zero is the normal operational value.
00028 If it is one, a trace of every rev_hes_sweep computation is printed.
00029 */
00030 # define CPPAD_REV_HES_SWEEP_TRACE 0
00031 
00032 /*!
00033 Given the forward Jacobian sparsity pattern for all the variables,
00034 and the reverse Jacobian sparsity pattern for the dependent variables,
00035 RevHesSweep computes the Hessian sparsity pattern for all the independent 
00036 variables.
00037 
00038 \tparam Base
00039 base type for the operator; i.e., this operation sequence was recorded
00040 using AD< \a Base > and computations by this routine are done using type 
00041 \a Base.
00042 
00043 \tparam Vector_set
00044 is the type used for vectors of sets. It can be either
00045 \c sparse_pack, \c sparse_set, or \c sparse_list.
00046 
00047 \param n
00048 is the number of independent variables on the tape.
00049 
00050 \param numvar
00051 is the total number of variables on the tape; i.e.,
00052 \a play->num_rec_var().
00053 This is also the number of rows in the entire sparsity pattern 
00054 \a rev_hes_sparse.
00055 
00056 \param play
00057 The information stored in \a play
00058 is a recording of the operations corresponding to a function
00059 \f[
00060      F : {\bf R}^n \rightarrow {\bf R}^m
00061 \f]
00062 where \f$ n \f$ is the number of independent variables
00063 and \f$ m \f$ is the number of dependent variables.
00064 The object \a play is effectly constant.
00065 It is not declared const because while playing back the tape
00066 the object \a play holds information about the currentl location
00067 with in the tape and this changes during playback.
00068 
00069 \param for_jac_sparse
00070 For i = 0 , ... , \a numvar - 1, 
00071 (for all the variables on the tape),
00072 the forward Jacobian sparsity pattern for the variable with index i
00073 corresponds to the set with index i in \a for_jac_sparse.
00074 
00075 \param RevJac
00076 \b Input:
00077 For i = 0, ... , \a numvar - 1 
00078 the if the variable with index i on the tape is an dependent variable and
00079 included in the Hessian, \a RevJac[ i ] is equal to true,
00080 otherwise it is equal to false. 
00081 \n
00082 \n
00083 \b Output: The values in \a RevJac upon return are not specified; i.e.,
00084 it is used for temporary work space.
00085 
00086 \param rev_hes_sparse
00087 The reverse Hessian sparsity pattern for the variable with index i
00088 corresponds to the set with index i in \a rev_hes_sparse.
00089 \n
00090 \n
00091 \b Input: For i = 0 , ... , \a numvar - 1  
00092 the reverse Hessian sparsity pattern for the variable with index i is empty.
00093 \n
00094 \n
00095 \b Output: For j = 1 , ... , \a n,
00096 the reverse Hessian sparsity pattern for the independent dependent variable 
00097 with index (j-1) is given by the set with index j
00098 in \a rev_hes_sparse. 
00099 The values in the rest of \a rev_hes_sparse are not specified; i.e.,
00100 they are used for temporary work space.
00101 */
00102 
00103 template <class Base, class Vector_set>
00104 void RevHesSweep(
00105      size_t                n,
00106      size_t                numvar,
00107      player<Base>         *play,
00108      Vector_set&           for_jac_sparse, // should be const
00109      bool*                 RevJac,
00110      Vector_set&           rev_hes_sparse
00111 )
00112 {
00113      OpCode           op;
00114      size_t         i_op;
00115      size_t        i_var;
00116 
00117      const addr_t*   arg = 0;
00118 
00119      // length of the parameter vector (used by CppAD assert macros)
00120      const size_t num_par = play->num_rec_par();
00121 
00122      size_t             i, j, k;
00123 
00124      // check numvar argument
00125      CPPAD_ASSERT_UNKNOWN( play->num_rec_var()     == numvar );
00126      CPPAD_ASSERT_UNKNOWN( for_jac_sparse.n_set() == numvar );
00127      CPPAD_ASSERT_UNKNOWN( rev_hes_sparse.n_set() == numvar );
00128      CPPAD_ASSERT_UNKNOWN( numvar > 0 );
00129 
00130      // upper limit exclusive for set elements
00131      size_t limit   = rev_hes_sparse.end();
00132      CPPAD_ASSERT_UNKNOWN( for_jac_sparse.end() == limit );
00133 
00134      // check number of sets match
00135      CPPAD_ASSERT_UNKNOWN( 
00136           for_jac_sparse.n_set() == rev_hes_sparse.n_set()
00137      );
00138 
00139      // vecad_sparsity contains a sparsity pattern for each VecAD object.
00140      // vecad_ind maps a VecAD index (beginning of the VecAD object) 
00141      // to the index for the corresponding set in vecad_sparsity.
00142      size_t num_vecad_ind   = play->num_rec_vecad_ind();
00143      size_t num_vecad_vec   = play->num_rec_vecad_vec();
00144      Vector_set vecad_sparse;
00145      vecad_sparse.resize(num_vecad_vec, limit);
00146      pod_vector<size_t> vecad_ind;
00147      pod_vector<bool>   vecad_jac;
00148      if( num_vecad_vec > 0 )
00149      {    size_t length;
00150           vecad_ind.extend(num_vecad_ind);
00151           vecad_jac.extend(num_vecad_vec);
00152           j             = 0;
00153           for(i = 0; i < num_vecad_vec; i++)
00154           {    // length of this VecAD
00155                length   = play->GetVecInd(j);
00156                // set vecad_ind to proper index for this VecAD
00157                vecad_ind[j] = i; 
00158                // make all other values for this vector invalid
00159                for(k = 1; k <= length; k++)
00160                     vecad_ind[j+k] = num_vecad_vec;
00161                // start of next VecAD
00162                j       += length + 1;
00163                // initialize this vector's reverse jacobian value 
00164                vecad_jac[i] = false;
00165           }
00166           CPPAD_ASSERT_UNKNOWN( j == play->num_rec_vecad_ind() );
00167      }
00168 
00169      // work space used by UserOp.
00170      typedef std::set<size_t> size_set;
00171      const size_t user_q = limit; // maximum element plus one
00172      size_set::iterator set_itr;  // iterator for a standard set
00173      size_set::iterator set_end;  // end of iterator sequence
00174      vector<size_t>     user_ix;  // variable indices for argument vector x
00175      vector< size_set > user_r;   // forward Jacobian sparsity pattern for x
00176      vector<bool>       user_s;   // reverse Jacobian sparsity for y
00177      vector<bool>       user_t;   // reverse Jacobian sparsity for x
00178      vector< size_set > user_u;   // reverse Hessian sparsity for y
00179      vector< size_set > user_v;   // reverse Hessian sparsity for x
00180      size_t user_index = 0;       // indentifier for this user_atomic operation
00181      size_t user_id    = 0;       // user identifier for this call to operator
00182      size_t user_i     = 0;       // index in result vector
00183      size_t user_j     = 0;       // index in argument vector
00184      size_t user_m     = 0;       // size of result vector
00185      size_t user_n     = 0;       // size of arugment vector
00186      // next expected operator in a UserOp sequence
00187      enum { user_start, user_arg, user_ret, user_end } user_state = user_end;
00188 
00189 
00190      // Initialize
00191      play->start_reverse(op, arg, i_op, i_var);
00192      CPPAD_ASSERT_UNKNOWN( op == EndOp );
00193 # if CPPAD_REV_HES_SWEEP_TRACE
00194      std::cout << std::endl;
00195      CppAD::vectorBool zf_value(limit);
00196      CppAD::vectorBool zh_value(limit);
00197 # endif
00198      while(op != BeginOp)
00199      {
00200           // next op
00201           play->next_reverse(op, arg, i_op, i_var);
00202 # ifndef NDEBUG
00203           if( i_op <= n )
00204           {    CPPAD_ASSERT_UNKNOWN((op == InvOp) | (op == BeginOp));
00205           }
00206           else CPPAD_ASSERT_UNKNOWN((op != InvOp) & (op != BeginOp));
00207 # endif
00208 
00209           // rest of information depends on the case
00210           switch( op )
00211           {
00212                case AbsOp:
00213                CPPAD_ASSERT_NARG_NRES(op, 1, 1)
00214                reverse_sparse_hessian_linear_unary_op(
00215                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00216                );
00217                break;
00218                // -------------------------------------------------
00219 
00220                case AddvvOp:
00221                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00222                reverse_sparse_hessian_addsub_op(
00223                i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse
00224                );
00225                break;
00226                // -------------------------------------------------
00227 
00228                case AddpvOp:
00229                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00230                reverse_sparse_hessian_linear_unary_op(
00231                i_var, arg[1], RevJac, for_jac_sparse, rev_hes_sparse
00232                );
00233                break;
00234                // -------------------------------------------------
00235 
00236                case AcosOp:
00237                // sqrt(1 - x * x), acos(x)
00238                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00239                reverse_sparse_hessian_nonlinear_unary_op(
00240                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00241                );
00242                break;
00243                // -------------------------------------------------
00244 
00245                case AsinOp:
00246                // sqrt(1 - x * x), asin(x)
00247                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00248                reverse_sparse_hessian_nonlinear_unary_op(
00249                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00250                );
00251                break;
00252                // -------------------------------------------------
00253 
00254                case AtanOp:
00255                // 1 + x * x, atan(x)
00256                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00257                reverse_sparse_hessian_nonlinear_unary_op(
00258                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00259                );
00260                break;
00261                // -------------------------------------------------
00262 
00263                case BeginOp:
00264                CPPAD_ASSERT_NARG_NRES(op, 0, 1)
00265                break;
00266                // -------------------------------------------------
00267 
00268                case CSumOp:
00269                // CSumOp has a variable number of arguments and
00270                // next_reverse thinks it one has one argument.
00271                // We must inform next_reverse of this special case.
00272                play->reverse_csum(op, arg, i_op, i_var);
00273                reverse_sparse_hessian_csum_op(
00274                     i_var, arg, RevJac, rev_hes_sparse
00275                );
00276                break;
00277                // -------------------------------------------------
00278 
00279                case CExpOp:
00280                reverse_sparse_hessian_cond_op(
00281                     i_var, arg, num_par, RevJac, rev_hes_sparse
00282                );
00283                break;
00284                // ---------------------------------------------------
00285 
00286                case ComOp:
00287                CPPAD_ASSERT_NARG_NRES(op, 4, 0)
00288                CPPAD_ASSERT_UNKNOWN( arg[1] > 1 );
00289                break;
00290                // --------------------------------------------------
00291 
00292                case CosOp:
00293                // sin(x), cos(x)
00294                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00295                reverse_sparse_hessian_nonlinear_unary_op(
00296                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00297                );
00298                break;
00299                // ---------------------------------------------------
00300 
00301                case CoshOp:
00302                // sinh(x), cosh(x)
00303                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00304                reverse_sparse_hessian_nonlinear_unary_op(
00305                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00306                );
00307                break;
00308                // -------------------------------------------------
00309 
00310                case DisOp:
00311                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00312                // derivativve is identically zero
00313                break;
00314                // -------------------------------------------------
00315 
00316                case DivvvOp:
00317                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00318                reverse_sparse_hessian_div_op(
00319                i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse
00320                );
00321                break;
00322                // -------------------------------------------------
00323 
00324                case DivpvOp:
00325                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00326                reverse_sparse_hessian_nonlinear_unary_op(
00327                i_var, arg[1], RevJac, for_jac_sparse, rev_hes_sparse
00328                );
00329                break;
00330                // -------------------------------------------------
00331 
00332                case DivvpOp:
00333                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00334                reverse_sparse_hessian_linear_unary_op(
00335                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00336                );
00337                break;
00338                // -------------------------------------------------
00339 
00340                case ExpOp:
00341                CPPAD_ASSERT_NARG_NRES(op, 1, 1)
00342                reverse_sparse_hessian_nonlinear_unary_op(
00343                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00344                );
00345                break;
00346                // -------------------------------------------------
00347 
00348                case InvOp:
00349                CPPAD_ASSERT_NARG_NRES(op, 0, 1)
00350                // Z is already defined
00351                break;
00352                // -------------------------------------------------
00353 
00354                case LdpOp:
00355                reverse_sparse_hessian_load_op(
00356                     op,
00357                     i_var,
00358                     arg,
00359                     num_vecad_ind,
00360                     vecad_ind.data(),
00361                     rev_hes_sparse,
00362                     vecad_sparse,
00363                     RevJac,
00364                     vecad_jac.data()
00365                );
00366                break;
00367                // -------------------------------------------------
00368 
00369                case LdvOp:
00370                reverse_sparse_hessian_load_op(
00371                     op,
00372                     i_var,
00373                     arg,
00374                     num_vecad_ind,
00375                     vecad_ind.data(),
00376                     rev_hes_sparse,
00377                     vecad_sparse,
00378                     RevJac,
00379                     vecad_jac.data()
00380                );
00381                break;
00382                // -------------------------------------------------
00383 
00384                case LogOp:
00385                CPPAD_ASSERT_NARG_NRES(op, 1, 1)
00386                reverse_sparse_hessian_nonlinear_unary_op(
00387                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00388                );
00389                break;
00390                // -------------------------------------------------
00391 
00392                case MulvvOp:
00393                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00394                reverse_sparse_hessian_mul_op(
00395                i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse
00396                );
00397                break;
00398                // -------------------------------------------------
00399 
00400                case MulpvOp:
00401                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00402                reverse_sparse_hessian_linear_unary_op(
00403                i_var, arg[1], RevJac, for_jac_sparse, rev_hes_sparse
00404                );
00405                break;
00406                // -------------------------------------------------
00407 
00408                case ParOp:
00409                CPPAD_ASSERT_NARG_NRES(op, 1, 1)
00410 
00411                break;
00412                // -------------------------------------------------
00413 
00414                case PowpvOp:
00415                CPPAD_ASSERT_NARG_NRES(op, 2, 3)
00416                reverse_sparse_hessian_nonlinear_unary_op(
00417                i_var, arg[1], RevJac, for_jac_sparse, rev_hes_sparse
00418                );
00419                break;
00420                // -------------------------------------------------
00421 
00422                case PowvpOp:
00423                CPPAD_ASSERT_NARG_NRES(op, 2, 3)
00424                reverse_sparse_hessian_nonlinear_unary_op(
00425                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00426                );
00427                break;
00428                // -------------------------------------------------
00429 
00430                case PowvvOp:
00431                CPPAD_ASSERT_NARG_NRES(op, 2, 3)
00432                         reverse_sparse_hessian_pow_op(
00433                i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse
00434                );
00435                break;
00436                // -------------------------------------------------
00437 
00438                case PriOp:
00439                CPPAD_ASSERT_NARG_NRES(op, 5, 0);
00440                break;
00441                // -------------------------------------------------
00442 
00443                case SignOp:
00444                CPPAD_ASSERT_NARG_NRES(op, 1, 1);
00445                // Derivative is identiaclly zero
00446                break;
00447                // -------------------------------------------------
00448 
00449                case SinOp:
00450                // cos(x), sin(x)
00451                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00452                reverse_sparse_hessian_nonlinear_unary_op(
00453                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00454                );
00455                break;
00456                // -------------------------------------------------
00457 
00458                case SinhOp:
00459                // cosh(x), sinh(x)
00460                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00461                reverse_sparse_hessian_nonlinear_unary_op(
00462                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00463                );
00464                break;
00465                // -------------------------------------------------
00466 
00467                case SqrtOp:
00468                CPPAD_ASSERT_NARG_NRES(op, 1, 1)
00469                reverse_sparse_hessian_nonlinear_unary_op(
00470                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00471                );
00472                break;
00473                // -------------------------------------------------
00474 
00475                case StppOp:
00476                // sparsity cannot propagate through a parameter
00477                CPPAD_ASSERT_NARG_NRES(op, 3, 0)
00478                break;
00479                // -------------------------------------------------
00480 
00481                case StpvOp:
00482                reverse_sparse_hessian_store_op(
00483                     op,
00484                     arg,
00485                     num_vecad_ind,
00486                     vecad_ind.data(),
00487                     rev_hes_sparse,
00488                     vecad_sparse,
00489                     RevJac,
00490                     vecad_jac.data()
00491                );
00492                break;
00493                // -------------------------------------------------
00494 
00495                case StvpOp:
00496                // sparsity cannot propagate through a parameter
00497                CPPAD_ASSERT_NARG_NRES(op, 3, 0)
00498                break;
00499                // -------------------------------------------------
00500 
00501                case StvvOp:
00502                reverse_sparse_hessian_store_op(
00503                     op,
00504                     arg,
00505                     num_vecad_ind,
00506                     vecad_ind.data(),
00507                     rev_hes_sparse,
00508                     vecad_sparse,
00509                     RevJac,
00510                     vecad_jac.data()
00511                );
00512                break;
00513                // -------------------------------------------------
00514 
00515                case SubvvOp:
00516                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00517                reverse_sparse_hessian_addsub_op(
00518                i_var, arg, RevJac, for_jac_sparse, rev_hes_sparse
00519                );
00520                break;
00521                // -------------------------------------------------
00522 
00523                case SubpvOp:
00524                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00525                reverse_sparse_hessian_linear_unary_op(
00526                i_var, arg[1], RevJac, for_jac_sparse, rev_hes_sparse
00527                );
00528                break;
00529                // -------------------------------------------------
00530 
00531                case SubvpOp:
00532                CPPAD_ASSERT_NARG_NRES(op, 2, 1)
00533                reverse_sparse_hessian_linear_unary_op(
00534                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00535                );
00536                break;
00537                // -------------------------------------------------
00538 
00539                case TanOp:
00540                // tan(x)^2, tan(x)
00541                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00542                reverse_sparse_hessian_nonlinear_unary_op(
00543                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00544                );
00545                break;
00546                // -------------------------------------------------
00547 
00548                case TanhOp:
00549                // tanh(x)^2, tanh(x)
00550                CPPAD_ASSERT_NARG_NRES(op, 1, 2)
00551                reverse_sparse_hessian_nonlinear_unary_op(
00552                i_var, arg[0], RevJac, for_jac_sparse, rev_hes_sparse
00553                );
00554                break;
00555                // -------------------------------------------------
00556 
00557                case UserOp:
00558                // start or end an atomic operation sequence
00559                CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
00560                CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
00561                if( user_state == user_end )
00562                {    user_index = arg[0];
00563                     user_id    = arg[1];
00564                     user_n     = arg[2];
00565                     user_m     = arg[3];
00566                     if(user_ix.size() < user_n)
00567                     {    user_ix.resize(user_n);
00568                          user_r.resize(user_n);
00569                          user_t.resize(user_n);
00570                          user_v.resize(user_n);
00571                     }
00572                     if(user_s.size() < user_m)
00573                     {    user_s.resize(user_m);
00574                          user_u.resize(user_m);
00575                     }
00576                     user_j     = user_n;
00577                     user_i     = user_m;
00578                     user_state = user_ret;
00579                }
00580                else
00581                {    CPPAD_ASSERT_UNKNOWN( user_state == user_start );
00582                     CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
00583                     CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
00584                     CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
00585                     CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
00586                     user_state = user_end;
00587 
00588                     // call users function for this operation
00589                     user_atomic<Base>::rev_hes_sparse(user_index, user_id,
00590                          user_n, user_m, 
00591                          user_q, user_r, user_s, user_t, user_u, user_v
00592                     );
00593                     for(j = 0; j < user_n; j++) if( user_ix[j] > 0 )
00594                     {    size_t i_x = user_ix[j];
00595                          RevJac[i_x] = user_t[j];
00596                          set_itr = user_v[j].begin();
00597                          set_end = user_v[j].end();
00598                          while( set_itr != set_end )
00599                               rev_hes_sparse.add_element(i_x, *set_itr++);
00600                     }
00601                }
00602                break;
00603 
00604                case UsrapOp:
00605                // parameter argument in an atomic operation sequence
00606                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00607                CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
00608                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00609                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00610                --user_j;
00611                user_ix[user_j] = 0;
00612                user_r[user_j].clear();
00613                if( user_j == 0 )
00614                     user_state = user_start;
00615                break;
00616 
00617                case UsravOp:
00618                // variable argument in an atomic operation sequence
00619                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00620                CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
00621                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00622                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
00623                CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00624                --user_j;
00625                user_ix[user_j] = arg[0];
00626                user_r[user_j].clear();
00627                for_jac_sparse.begin(arg[0]);
00628                i = for_jac_sparse.next_element();
00629                while( i < user_q )
00630                {    user_r[user_j].insert(i);
00631                     i = for_jac_sparse.next_element();
00632                }
00633                if( user_j == 0 )
00634                     user_state = user_start;
00635                break;
00636 
00637                case UsrrpOp:
00638                // parameter result in an atomic operation sequence
00639                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00640                CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
00641                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00642                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00643                --user_i;
00644                user_s[user_i] = false;
00645                user_u[user_i].clear();
00646                if( user_i == 0 )
00647                     user_state = user_arg;
00648                break;
00649 
00650                case UsrrvOp:
00651                // variable result in an atomic operation sequence
00652                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00653                CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
00654                --user_i;
00655                user_s[user_i] = RevJac[i_var];
00656                user_u[user_i].clear();
00657                rev_hes_sparse.begin(i_var);
00658                i = rev_hes_sparse.next_element();
00659                while( i < user_q )
00660                {    user_u[user_i].insert(i);
00661                     i = rev_hes_sparse.next_element();
00662                }
00663                if( user_i == 0 )
00664                     user_state = user_arg;
00665                break;
00666 
00667                // -------------------------------------------------
00668 
00669                default:
00670                CPPAD_ASSERT_UNKNOWN(0);
00671           }
00672 # if CPPAD_REV_HES_SWEEP_TRACE
00673           for(j = 0; j < limit; j++)
00674           {    zf_value[j] = false;
00675                zh_value[j] = false;
00676           }
00677           for_jac_sparse.begin(i_var);;
00678           j = for_jac_sparse.next_element();;
00679           while( j < limit )
00680           {    zf_value[j] = true;
00681                j = for_jac_sparse.next_element();
00682           }
00683           rev_hes_sparse.begin(i_var);;
00684           j = rev_hes_sparse.next_element();;
00685           while( j < limit )
00686           {    zh_value[j] = true;
00687                j = rev_hes_sparse.next_element();
00688           }
00689           // should also print RevJac[i_var], but printOp does not
00690           // yet allow for this.
00691           printOp(
00692                std::cout, 
00693                play,
00694                i_var,
00695                op, 
00696                arg,
00697                1, 
00698                &zf_value, 
00699                1, 
00700                &zh_value
00701           );
00702 # endif
00703      }
00704      // values corresponding to BeginOp
00705      CPPAD_ASSERT_UNKNOWN( i_op == 0 );
00706      CPPAD_ASSERT_UNKNOWN( i_var == 0 );
00707 
00708      return;
00709 }
00710 /*! \} */
00711 CPPAD_END_NAMESPACE
00712 
00713 // preprocessor symbols that are local to this file
00714 # undef CPPAD_REV_HES_SWEEP_TRACE
00715 
00716 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines