CppAD: A C++ Algorithmic Differentiation Package  20130918
reverse_sweep.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_REVERSE_SWEEP_INCLUDED
00003 # define CPPAD_REVERSE_SWEEP_INCLUDED
00004 
00005 /* --------------------------------------------------------------------------
00006 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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 
00017 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00018 /*!
00019 \file reverse_sweep.hpp
00020 Compute derivatives of arbitrary order Taylor coefficients.
00021 */
00022 
00023 /*
00024 \def CPPAD_ATOMIC_CALL
00025 This avoids warnings when NDEBUG is defined and user_ok is not used.
00026 If \c NDEBUG is defined, this resolves to
00027 \code
00028      user_atom->reverse
00029 \endcode
00030 otherwise, it respolves to
00031 \code
00032      user_ok = user_atom->reverse
00033 \endcode
00034 This maco is undefined at the end of this file to facillitate is 
00035 use with a different definition in other files.
00036 */
00037 # ifdef NDEBUG
00038 # define CPPAD_ATOMIC_CALL user_atom->reverse
00039 # else
00040 # define CPPAD_ATOMIC_CALL user_ok = user_atom->reverse
00041 # endif
00042 
00043 /*!
00044 \def CPPAD_REVERSE_SWEEP_TRACE
00045 This value is either zero or one. 
00046 Zero is the normal operational value.
00047 If it is one, a trace of every reverse_sweep computation is printed.
00048 */
00049 # define CPPAD_REVERSE_SWEEP_TRACE 0
00050 
00051 /*!
00052 Compute derivative of arbitrary order forward mode Taylor coefficients.
00053 
00054 \tparam Base
00055 base type for the operator; i.e., this operation sequence was recorded
00056 using AD< \a Base > and computations by this routine are done using type 
00057 \a Base.
00058 
00059 \param d
00060 is the highest order Taylor coefficients that 
00061 we are computing the derivative of.
00062 
00063 \param n
00064 is the number of independent variables on the tape.
00065 
00066 \param numvar
00067 is the total number of variables on the tape.
00068 This is also equal to the number of rows in the matrix \a Taylor; i.e.,
00069 play->num_var_rec().
00070 
00071 \param play
00072 The information stored in \a play
00073 is a recording of the operations corresponding to the function
00074 \f[
00075      F : {\bf R}^n \rightarrow {\bf R}^m
00076 \f]
00077 where \f$ n \f$ is the number of independent variables and
00078 \f$ m \f$ is the number of dependent variables.
00079 We define the function 
00080 \f$ G : {\bf R}^{n \times d} \rightarrow {\bf R} \f$ by
00081 \f[
00082 G( u ) = \frac{1}{d !} \frac{ \partial^d }{ \partial t^d } 
00083 \left[ 
00084      \sum_{i=1}^m w_i  F_i ( u^{(0)} + u^{(1)} t + \cdots + u^{(d)} t^d )
00085 \right]_{t=0}
00086 \f]
00087 Note that the scale factor  1 / a d  converts 
00088 the \a d-th partial derivative to the \a d-th order Taylor coefficient.
00089 This routine computes the derivative of \f$ G(u) \f$
00090 with respect to all the Taylor coefficients
00091 \f$ u^{(k)} \f$ for \f$ k = 0 , ... , d \f$.
00092 The vector \f$ w \in {\bf R}^m \f$, and
00093 value of \f$ u \in {\bf R}^{n \times d} \f$
00094 at which the derivative is computed,
00095 are defined below.
00096 \n
00097 \n
00098 The object \a play is effectly constant.
00099 There is an exception to this,
00100 while palying back the tape
00101 the object \a play holds information about the current location
00102 with in the tape and this changes during palyback. 
00103 
00104 \param J
00105 Is the number of columns in the coefficient matrix \a Taylor.
00106 This must be greater than or equal \a d + 1.
00107 
00108 \param Taylor
00109 For i = 1 , ... , \a numvar, and for k = 0 , ... , \a d,
00110 \a Taylor [ i * J + k ]
00111 is the k-th order Taylor coefficient corresponding to 
00112 variable with index i on the tape.
00113 The value \f$ u \in {\bf R}^{n \times d} \f$,
00114 at which the derivative is computed,
00115 is defined by
00116 \f$ u_j^{(k)} \f$ = \a Taylor [ j * J + k ]
00117 for j = 1 , ... , \a n, and for k = 0 , ... , \a d.
00118 
00119 \param K
00120 Is the number of columns in the partial derivative matrix \a Partial.
00121 It must be greater than or equal \a d + 1.
00122 
00123 \param Partial
00124 \b Input:
00125 The last \f$ m \f$ rows of \a Partial are inputs.
00126 The vector \f$ v \f$, used to define \f$ G(u) \f$,
00127 is specified by these rows. 
00128 For i = 0 , ... , m - 1, \a Partial [ ( \a numvar - m + i ) * K + d ] = v_i.
00129 For i = 0 , ... , m - 1 and for k = 0 , ... , d - 1, 
00130 \a Partial [ ( \a numvar - m + i ) * K + k ] = 0.
00131 \n
00132 \n
00133 \b Temporary:
00134 For i = n+1 , ... , \a numvar - 1 and for k = 0 , ... , d, 
00135 the value of \a Partial [ i * K + k ] is used for temporary work space
00136 and its output value is not defined. 
00137 \n
00138 \n
00139 \b Output:
00140 For j = 1 , ... , n and for k = 0 , ... , d, 
00141 \a Partial [ j * K + k ] 
00142 is the partial derivative of \f$ G( u ) \f$ with 
00143 respect to \f$ u_j^{(k)} \f$.
00144 
00145 \param cskip_op
00146 Is a vector with size play->num_op_rec().
00147 If cskip_op[i] is true, the operator index i in the recording
00148 does not affect any of the dependent variable (given the value
00149 of the independent variables).
00150 
00151 \param var_by_load_op
00152 is a vector with size play->num_load_op_rec().
00153 Is the variable index corresponding to each load instruction.
00154 In the case where the index is zero,
00155 the instruction corresponds to a parameter (not variable).
00156 
00157 \par Assumptions
00158 The first operator on the tape is a BeginOp,
00159 and the next \a n operators are InvOp operations for the 
00160 corresponding independent variables.
00161 */
00162 template <class Base>
00163 void ReverseSweep(
00164      size_t                      d,
00165      size_t                      n,
00166      size_t                      numvar,
00167      player<Base>*               play,
00168      size_t                      J,
00169      const Base*                 Taylor,
00170      size_t                      K,
00171      Base*                       Partial,
00172      bool*                       cskip_op,
00173      const pod_vector<addr_t>&   var_by_load_op
00174 )
00175 {
00176      OpCode           op;
00177      size_t         i_op;
00178      size_t        i_var;
00179 
00180      const addr_t*   arg = CPPAD_NULL;
00181 
00182      // check numvar argument
00183      CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
00184      CPPAD_ASSERT_UNKNOWN( numvar > 0 );
00185 
00186      // length of the parameter vector (used by CppAD assert macros)
00187      const size_t num_par = play->num_par_rec();
00188 
00189      // pointer to the beginning of the parameter vector
00190      const Base* parameter = CPPAD_NULL;
00191      if( num_par > 0 )
00192           parameter = play->GetPar();
00193 
00194      // work space used by UserOp.
00195      const size_t user_k  = d;    // highest order we are differentiating
00196      const size_t user_k1 = d+1;  // number of orders for this calculation
00197      vector<size_t> user_ix;      // variable indices for argument vector
00198      vector<Base> user_tx;        // argument vector Taylor coefficients
00199      vector<Base> user_ty;        // result vector Taylor coefficients
00200      vector<Base> user_px;        // partials w.r.t argument vector
00201      vector<Base> user_py;        // partials w.r.t. result vector
00202      size_t user_index = 0;       // indentifier for this atomic operation
00203      size_t user_id    = 0;       // user identifier for this call to operator
00204      size_t user_i     = 0;       // index in result vector
00205      size_t user_j     = 0;       // index in argument vector
00206      size_t user_m     = 0;       // size of result vector
00207      size_t user_n     = 0;       // size of arugment vector
00208      //
00209      atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
00210 # ifndef NDEBUG
00211      bool               user_ok   = false;      // atomic op return value
00212 # endif
00213      //
00214      // next expected operator in a UserOp sequence
00215      enum { user_start, user_arg, user_ret, user_end } user_state = user_end;
00216 
00217      // temporary indices
00218      size_t j, ell;
00219 
00220      // Initialize
00221      play->reverse_start(op, arg, i_op, i_var);
00222      CPPAD_ASSERT_UNKNOWN( op == EndOp );
00223 # if CPPAD_REVERSE_SWEEP_TRACE
00224      std::cout << std::endl;
00225 # endif
00226      bool more_operators = true;
00227      while(more_operators)
00228      {    // next op
00229           play->reverse_next(op, arg, i_op, i_var);
00230           CPPAD_ASSERT_UNKNOWN((i_op >  n) | (op == InvOp) | (op == BeginOp));
00231           CPPAD_ASSERT_UNKNOWN((i_op <= n) | (op != InvOp) | (op != BeginOp));
00232           CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
00233 
00234           // check if we are skipping this operation
00235           while( cskip_op[i_op] )
00236           {    if( op == CSumOp )
00237                {    // CSumOp has a variable number of arguments
00238                     play->reverse_csum(op, arg, i_op, i_var);
00239                }
00240                play->reverse_next(op, arg, i_op, i_var);
00241                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
00242           }
00243 
00244           // rest of informaiton depends on the case
00245 # if CPPAD_REVERSE_SWEEP_TRACE
00246           size_t       i_tmp  = i_var;
00247           const Base*  Z_tmp  = Taylor + i_var * J;
00248           const Base*  pZ_tmp = Partial + i_var * K;
00249 
00250           printOp(
00251                std::cout, 
00252                play,
00253                i_op,
00254                i_tmp,
00255                op, 
00256                arg,
00257                d + 1, 
00258                Z_tmp, 
00259                d + 1, 
00260                pZ_tmp 
00261           );
00262 # endif
00263 
00264           switch( op )
00265           {
00266 
00267                case AbsOp:
00268                reverse_abs_op(
00269                     d, i_var, arg[0], J, Taylor, K, Partial
00270                );
00271                break;
00272                // --------------------------------------------------
00273 
00274                case AddvvOp:
00275                reverse_addvv_op(
00276                     d, i_var, arg, parameter, J, Taylor, K, Partial
00277                );
00278                break;
00279                // --------------------------------------------------
00280 
00281                case AddpvOp:
00282                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00283                reverse_addpv_op(
00284                     d, i_var, arg, parameter, J, Taylor, K, Partial
00285                );
00286                break;
00287                // --------------------------------------------------
00288 
00289                case AcosOp:
00290                         // sqrt(1 - x * x), acos(x)
00291                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00292                reverse_acos_op(
00293                     d, i_var, arg[0], J, Taylor, K, Partial
00294                );
00295                break;
00296                // --------------------------------------------------
00297 
00298                case AsinOp:
00299                         // sqrt(1 - x * x), asin(x)
00300                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00301                reverse_asin_op(
00302                     d, i_var, arg[0], J, Taylor, K, Partial
00303                );
00304                break;
00305                // --------------------------------------------------
00306 
00307                case AtanOp:
00308                         // 1 + x * x, atan(x)
00309                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00310                reverse_atan_op(
00311                     d, i_var, arg[0], J, Taylor, K, Partial
00312                );
00313                break;
00314                // -------------------------------------------------
00315 
00316                case BeginOp:
00317                CPPAD_ASSERT_NARG_NRES(op, 1, 1);
00318                more_operators = false;
00319                break;
00320                // --------------------------------------------------
00321 
00322                case CSkipOp:
00323                // CSkipOp has a variable number of arguments and
00324                // forward_next thinks it one has one argument.
00325                // we must inform reverse_next of this special case.
00326                play->reverse_cskip(op, arg, i_op, i_var);
00327                break;
00328                // -------------------------------------------------
00329 
00330                case CSumOp:
00331                // CSumOp has a variable number of arguments and
00332                // reverse_next thinks it one has one argument.
00333                // We must inform reverse_next of this special case.
00334                play->reverse_csum(op, arg, i_op, i_var);
00335                reverse_csum_op(
00336                     d, i_var, arg, K, Partial
00337                );
00338                // end of a cummulative summation
00339                break;
00340                // -------------------------------------------------
00341 
00342                case CExpOp:
00343                reverse_cond_op(
00344                     d, 
00345                     i_var, 
00346                     arg, 
00347                     num_par, 
00348                     parameter, 
00349                     J, 
00350                     Taylor,
00351                     K, 
00352                     Partial
00353                );
00354                break;
00355                // --------------------------------------------------
00356 
00357                case ComOp:
00358                break;
00359                // --------------------------------------------------
00360 
00361                case CosOp:
00362                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00363                reverse_cos_op(
00364                     d, i_var, arg[0], J, Taylor, K, Partial
00365                );
00366                break;
00367                // --------------------------------------------------
00368 
00369                case CoshOp:
00370                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00371                reverse_cosh_op(
00372                     d, i_var, arg[0], J, Taylor, K, Partial
00373                );
00374                break;
00375                // --------------------------------------------------
00376 
00377                case DisOp:
00378                // Derivative of discrete operation is zero so no
00379                // contribution passes through this operation. 
00380                break;
00381                // --------------------------------------------------
00382 
00383                case DivvvOp:
00384                reverse_divvv_op(
00385                     d, i_var, arg, parameter, J, Taylor, K, Partial
00386                );
00387                break;
00388                // --------------------------------------------------
00389 
00390                case DivpvOp:
00391                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00392                reverse_divpv_op(
00393                     d, i_var, arg, parameter, J, Taylor, K, Partial
00394                );
00395                break;
00396                // --------------------------------------------------
00397 
00398                case DivvpOp:
00399                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00400                reverse_divvp_op(
00401                     d, i_var, arg, parameter, J, Taylor, K, Partial
00402                );
00403                break;
00404                // --------------------------------------------------
00405 
00406                case ExpOp:
00407                reverse_exp_op(
00408                     d, i_var, arg[0], J, Taylor, K, Partial
00409                );
00410                break;
00411                // --------------------------------------------------
00412                case LdpOp:
00413                reverse_load_op(
00414           op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
00415                );
00416                break;
00417                // -------------------------------------------------
00418 
00419                case LdvOp:
00420                reverse_load_op(
00421           op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
00422                );
00423                break;
00424                // -------------------------------------------------
00425 
00426                case InvOp:
00427                break;
00428                // --------------------------------------------------
00429 
00430                case LogOp:
00431                reverse_log_op(
00432                     d, i_var, arg[0], J, Taylor, K, Partial
00433                );
00434                break;
00435                // --------------------------------------------------
00436 
00437                case MulvvOp:
00438                reverse_mulvv_op(
00439                     d, i_var, arg, parameter, J, Taylor, K, Partial
00440                );
00441                break;
00442                // --------------------------------------------------
00443 
00444                case MulpvOp:
00445                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00446                reverse_mulpv_op(
00447                     d, i_var, arg, parameter, J, Taylor, K, Partial
00448                );
00449                break;
00450                // --------------------------------------------------
00451 
00452                case ParOp:
00453                break;
00454                // --------------------------------------------------
00455 
00456                case PowvpOp:
00457                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00458                reverse_powvp_op(
00459                     d, i_var, arg, parameter, J, Taylor, K, Partial
00460                );
00461                break;
00462                // -------------------------------------------------
00463 
00464                case PowpvOp:
00465                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00466                reverse_powpv_op(
00467                     d, i_var, arg, parameter, J, Taylor, K, Partial
00468                );
00469                break;
00470                // -------------------------------------------------
00471 
00472                case PowvvOp:
00473                reverse_powvv_op(
00474                     d, i_var, arg, parameter, J, Taylor, K, Partial
00475                );
00476                break;
00477                // --------------------------------------------------
00478 
00479                case PriOp:
00480                // no result so nothing to do
00481                break;
00482                // --------------------------------------------------
00483 
00484                case SignOp:
00485                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00486                reverse_sign_op(
00487                     d, i_var, arg[0], J, Taylor, K, Partial
00488                );
00489                break;
00490                // -------------------------------------------------
00491 
00492                case SinOp:
00493                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00494                reverse_sin_op(
00495                     d, i_var, arg[0], J, Taylor, K, Partial
00496                );
00497                break;
00498                // -------------------------------------------------
00499 
00500                case SinhOp:
00501                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00502                reverse_sinh_op(
00503                     d, i_var, arg[0], J, Taylor, K, Partial
00504                );
00505                break;
00506                // --------------------------------------------------
00507 
00508                case SqrtOp:
00509                reverse_sqrt_op(
00510                     d, i_var, arg[0], J, Taylor, K, Partial
00511                );
00512                break;
00513                // --------------------------------------------------
00514 
00515                case StppOp:
00516                break;
00517                // --------------------------------------------------
00518 
00519                case StpvOp:
00520                break;
00521                // -------------------------------------------------
00522 
00523                case StvpOp:
00524                break;
00525                // -------------------------------------------------
00526 
00527                case StvvOp:
00528                break;
00529                // --------------------------------------------------
00530 
00531                case SubvvOp:
00532                reverse_subvv_op(
00533                     d, i_var, arg, parameter, J, Taylor, K, Partial
00534                );
00535                break;
00536                // --------------------------------------------------
00537 
00538                case SubpvOp:
00539                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00540                reverse_subpv_op(
00541                     d, i_var, arg, parameter, J, Taylor, K, Partial
00542                );
00543                break;
00544                // --------------------------------------------------
00545 
00546                case SubvpOp:
00547                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00548                reverse_subvp_op(
00549                     d, i_var, arg, parameter, J, Taylor, K, Partial
00550                );
00551                break;
00552                // -------------------------------------------------
00553 
00554                case TanOp:
00555                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00556                reverse_tan_op(
00557                     d, i_var, arg[0], J, Taylor, K, Partial
00558                );
00559                break;
00560                // -------------------------------------------------
00561 
00562                case TanhOp:
00563                CPPAD_ASSERT_UNKNOWN( i_var < numvar );
00564                reverse_tanh_op(
00565                     d, i_var, arg[0], J, Taylor, K, Partial
00566                );
00567                break;
00568                // --------------------------------------------------
00569 
00570                case UserOp:
00571                // start or end an atomic operation sequence
00572                CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
00573                CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
00574                if( user_state == user_end )
00575                {    user_index = arg[0];
00576                     user_id    = arg[1];
00577                     user_n     = arg[2];
00578                     user_m     = arg[3];
00579                     user_atom  = atomic_base<Base>::class_object(user_index);
00580 # ifndef NDEBUG
00581                     if( user_atom == CPPAD_NULL )
00582                     {    std::string msg = 
00583                               atomic_base<Base>::class_name(user_index)
00584                               + ": atomic_base function has been deleted";
00585                          CPPAD_ASSERT_KNOWN(false, msg.c_str() );
00586                     }
00587 # endif
00588                     if(user_ix.size() != user_n)
00589                          user_ix.resize(user_n);
00590                     if(user_tx.size() != user_n * user_k1)
00591                     {    user_tx.resize(user_n * user_k1);
00592                          user_px.resize(user_n * user_k1);
00593                     }
00594                     if(user_ty.size() != user_m * user_k1)
00595                     {    user_ty.resize(user_m * user_k1);
00596                          user_py.resize(user_m * user_k1);
00597                     }
00598                     user_j     = user_n;
00599                     user_i     = user_m;
00600                     user_state = user_ret;
00601                }
00602                else
00603                {    CPPAD_ASSERT_UNKNOWN( user_state == user_start );
00604                     CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
00605                     CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
00606                     CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
00607                     CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
00608 
00609                     // call users function for this operation
00610                     user_atom->set_id(user_id);
00611                     CPPAD_ATOMIC_CALL(
00612                          user_k, user_tx, user_ty, user_px, user_py
00613                     );
00614 # ifndef NDEBUG
00615                     if( ! user_ok )
00616                     {    std::string msg = 
00617                               atomic_base<Base>::class_name(user_index)
00618                               + ": atomic_base.reverse: returned false";
00619                          CPPAD_ASSERT_KNOWN(false, msg.c_str() );
00620                     }
00621 # endif
00622                     for(j = 0; j < user_n; j++) if( user_ix[j] > 0 )
00623                     {    for(ell = 0; ell < user_k1; ell++)
00624                               Partial[user_ix[j] * K + ell] +=
00625                                    user_px[j * user_k1 + ell];
00626                     }
00627                     user_state = user_end;
00628                }
00629                break;
00630 
00631                case UsrapOp:
00632                // parameter argument in an atomic operation sequence
00633                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00634                CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
00635                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00636                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00637                --user_j;
00638                user_ix[user_j] = 0;
00639                user_tx[user_j * user_k1 + 0] = parameter[ arg[0]];
00640                for(ell = 1; ell < user_k1; ell++)
00641                     user_tx[user_j * user_k1 + ell] = Base(0.);
00642                
00643                if( user_j == 0 )
00644                     user_state = user_start;
00645                break;
00646 
00647                case UsravOp:
00648                // variable argument in an atomic operation sequence
00649                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00650                CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
00651                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00652                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
00653                CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
00654                --user_j;
00655                user_ix[user_j] = arg[0];
00656                for(ell = 0; ell < user_k1; ell++)
00657                     user_tx[user_j*user_k1 + ell] = Taylor[ arg[0] * J + ell];
00658                if( user_j == 0 )
00659                     user_state = user_start;
00660                break;
00661 
00662                case UsrrpOp:
00663                // parameter result in an atomic operation sequence
00664                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00665                CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
00666                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00667                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00668                --user_i;
00669                for(ell = 0; ell < user_k1; ell++)
00670                {    user_py[user_i * user_k1 + ell] = Base(0.);
00671                     user_ty[user_i * user_k1 + ell] = Base(0.);
00672                }
00673                user_ty[user_i * user_k1 + 0] = parameter[ arg[0] ];
00674                if( user_i == 0 )
00675                     user_state = user_arg;
00676                break;
00677 
00678                case UsrrvOp:
00679                // variable result in an atomic operation sequence
00680                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00681                CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
00682                --user_i;
00683                for(ell = 0; ell < user_k1; ell++)
00684                {    user_py[user_i * user_k1 + ell] =
00685                               Partial[i_var * K + ell];
00686                     user_ty[user_i * user_k1 + ell] =
00687                               Taylor[i_var * J + ell];
00688                }
00689                if( user_i == 0 )
00690                     user_state = user_arg;
00691                break;
00692                // ------------------------------------------------------------
00693 
00694                default:
00695                CPPAD_ASSERT_UNKNOWN(false);
00696           }
00697      }
00698 # if CPPAD_REVERSE_SWEEP_TRACE
00699      std::cout << std::endl;
00700 # endif
00701      // values corresponding to BeginOp
00702      CPPAD_ASSERT_UNKNOWN( i_op == 0 );
00703      CPPAD_ASSERT_UNKNOWN( i_var == 0 );
00704 }
00705 
00706 } // END_CPPAD_NAMESPACE
00707 
00708 // preprocessor symbols that are local to this file
00709 # undef CPPAD_REVERSE_SWEEP_TRACE
00710 # undef CPPAD_ATOMIC_CALL
00711 
00712 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines