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