CppAD: A C++ Algorithmic Differentiation Package  20130918
forward1sweep.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_FORWARD1SWEEP_INCLUDED
00003 # define CPPAD_FORWARD1SWEEP_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 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00017 /*!
00018 \file forward1sweep.hpp
00019 Compute one Taylor coefficient for each order requested.
00020 */
00021 
00022 /*
00023 \def CPPAD_ATOMIC_CALL
00024 This avoids warnings when NDEBUG is defined and user_ok is not used.
00025 If NDEBUG is defined, this resolves to
00026 \code
00027      user_atom->forward
00028 \endcode
00029 otherwise, it respolves to
00030 \code
00031      user_ok = user_atom->forward
00032 \endcode
00033 This macro is undefined at the end of this file to facillitate its 
00034 use with a different definition in other files.
00035 */
00036 # ifdef NDEBUG
00037 # define CPPAD_ATOMIC_CALL user_atom->forward
00038 # else
00039 # define CPPAD_ATOMIC_CALL user_ok = user_atom->forward
00040 # endif
00041 
00042 /*!
00043 \def CPPAD_FORWARD1SWEEP_TRACE
00044 This value is either zero or one. 
00045 Zero is the normal operational value.
00046 If it is one, a trace of every forward1sweep computation is printed.
00047 */
00048 # define CPPAD_FORWARD1SWEEP_TRACE 0
00049 
00050 /*!
00051 Compute arbitrary order forward mode Taylor coefficients.
00052 
00053 <!-- replace forward0sweep_doc_define -->
00054 \tparam Base
00055 The type used during the forward mode computations; i.e., the corresponding
00056 recording of operations used the type AD<Base>.
00057 
00058 \param s_out
00059 Is the stream where output corresponding to PriOp operations will
00060 be written.
00061 
00062 \param print
00063 If print is false,
00064 suppress the output that is otherwise generated by the c PriOp instructions.
00065 
00066 \param n
00067 is the number of independent variables on the tape.
00068 
00069 \param numvar
00070 is the total number of variables on the tape.
00071 This is also equal to the number of rows in the matrix taylor; i.e.,
00072 play->num_var_rec().
00073 
00074 \param play
00075 The information stored in play
00076 is a recording of the operations corresponding to the function
00077 \f[
00078      F : {\bf R}^n \rightarrow {\bf R}^m
00079 \f]
00080 where \f$ n \f$ is the number of independent variables and
00081 \f$ m \f$ is the number of dependent variables.
00082 \n
00083 \n
00084 The object play is effectly constant.
00085 The exception to this is that while palying back the tape
00086 the object play holds information about the current location
00087 with in the tape and this changes during palyback. 
00088 
00089 \param J
00090 Is the number of columns in the coefficient matrix taylor.
00091 This must be greater than or equal one.
00092 
00093 <!-- end forward0sweep_doc_define -->
00094 
00095 \param cskip_op
00096 Is a vector with size play->num_op_rec().
00097 \n
00098 \n
00099 <tt>p = 0</tt>
00100 \n
00101 In this case,
00102 the input value of the elements does not matter.
00103 Upon return, if cskip_op[i] is true, the operator with index i
00104 does not affect any of the dependent variable 
00105 (given the value of the independent variables).
00106 \n
00107 \n
00108 <tt>p > 0</tt>
00109 \n
00110 In this case cskip_op is not modified and has the same meaning 
00111 as its return value above.
00112 
00113 \param var_by_load_op
00114 is a vector with size play->num_load_op_rec().
00115 \n
00116 \n
00117 <tt>p == 0</tt>
00118 \n
00119 In this case,
00120 The input value of the elements does not matter.
00121 Upon return, 
00122 it is the variable index corresponding the result for each load operator.
00123 In the case where the index is zero,
00124 the load operator results in a parameter (not a variable).
00125 Note that the is no variable with index zero on the tape.
00126 \n
00127 \n
00128 <tt>p > 0</tt>
00129 \n
00130 In this case var_by_load_op is not modified and has the meaning 
00131 as its return value above.
00132 
00133 \param p
00134 is the lowest order of the Taylor coefficients
00135 that are computed during this call. 
00136 
00137 \param q
00138 is the highest order of the Taylor coefficients
00139 that are computed during this call. 
00140 
00141 \param taylor
00142 \n
00143 \b Input:
00144 For <code>i = 1 , ... , numvar-1</code>,
00145 <code>k = 0 , ... , p-1</code>,
00146 <code>taylor[ J*i + k]</code>
00147 is the k-th order Taylor coefficient corresponding to 
00148 the i-th variable.
00149 \n
00150 \n
00151 \b Input:
00152 For <code>i = 1 , ... , n</code>,
00153 <code>k = p , ... , q</code>,
00154 <code>taylor[ J*j + k]</code>
00155 is the k-th order Taylor coefficient corresponding to 
00156 the i-th variable 
00157 (these are the independent varaibles).
00158 \n
00159 \n
00160 \b Output: 
00161 For <code>i = n+1 , ... , numvar-1</code>, and 
00162 <code>k = 0 , ... , p-1</code>,
00163 <code>taylor[ J*i + k]</code>
00164 is the k-th order Taylor coefficient corresponding to
00165 the i-th variable. 
00166 
00167 \return
00168 If p is not zero, the return value is zero.
00169 If p is zero,
00170 the return value is equal to the number of ComOp operations
00171 that have a different result from when the information in 
00172 a play was recorded.
00173 (Note that if NDEBUG is true, there are no ComOp operations
00174 in play and hence this return value is always zero.)
00175 */
00176 
00177 template <class Base>
00178 size_t forward1sweep(
00179      std::ostream&         s_out,
00180      const bool            print,
00181      const size_t          p,
00182      const size_t          q,
00183      const size_t          n,
00184      const size_t          numvar,
00185      player<Base>*         play,
00186      const size_t          J,
00187      Base*                 taylor,
00188      bool*                 cskip_op,
00189      pod_vector<addr_t>&   var_by_load_op
00190 )
00191 {
00192      CPPAD_ASSERT_UNKNOWN( p <= q );
00193      CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
00194      CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
00195 
00196      /*
00197      <!-- replace forward0sweep_code_define -->
00198      */
00199      // op code for current instruction
00200      OpCode op;
00201 
00202      // index for current instruction
00203      size_t i_op;
00204 
00205      // next variables 
00206      size_t i_var;
00207 
00208      // operation argument indices
00209      const addr_t*   arg = CPPAD_NULL;
00210 
00211      // initialize the comparision operator (ComOp) counter
00212      size_t compareCount = 0;
00213 
00214      // If this includes a zero calculation, initialize this information
00215      pod_vector<bool>   isvar_by_ind;
00216      pod_vector<size_t> index_by_ind;
00217      if( p == 0 )
00218      {    size_t i;
00219 
00220           // this includes order zero calculation, initialize vector indices
00221           size_t num = play->num_vec_ind_rec();
00222           if( num > 0 )
00223           {    isvar_by_ind.extend(num);
00224                index_by_ind.extend(num);
00225                for(i = 0; i < num; i++)
00226                {    index_by_ind[i] = play->GetVecInd(i);
00227                     isvar_by_ind[i] = false;
00228                }
00229           }
00230           // includes zero order, so initialize conditional skip flags
00231           num = play->num_op_rec();
00232           for(i = 0; i < num; i++)
00233                cskip_op[i] = false;
00234      }
00235 
00236      // work space used by UserOp.
00237      vector<bool> user_vx;        // empty vecotor
00238      vector<bool> user_vy;        // empty vecotor
00239      vector<Base> user_tx;        // argument vector Taylor coefficients 
00240      vector<Base> user_ty;        // result vector Taylor coefficients 
00241      size_t user_index = 0;       // indentifier for this atomic operation
00242      size_t user_id    = 0;       // user identifier for this call to operator
00243      size_t user_i     = 0;       // index in result vector
00244      size_t user_j     = 0;       // index in argument vector
00245      size_t user_m     = 0;       // size of result vector
00246      size_t user_n     = 0;       // size of arugment vector
00247      //
00248      atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
00249 # ifndef NDEBUG
00250      bool               user_ok   = false;      // atomic op return value
00251 # endif
00252      //
00253      // next expected operator in a UserOp sequence
00254      enum { user_start, user_arg, user_ret, user_end } user_state = user_start;
00255 
00256      // length of the parameter vector (used by CppAD assert macros)
00257      const size_t num_par = play->num_par_rec();
00258 
00259      // pointer to the beginning of the parameter vector
00260      const Base* parameter = CPPAD_NULL;
00261      if( num_par > 0 )
00262           parameter = play->GetPar();
00263 
00264      // length of the text vector (used by CppAD assert macros)
00265      const size_t num_text = play->num_text_rec();
00266 
00267      // pointer to the beginning of the text vector
00268      const char* text = CPPAD_NULL;
00269      if( num_text > 0 )
00270           text = play->GetTxt(0);
00271      /*
00272      <!-- end forward0sweep_code_define -->
00273      */
00274      // temporary indices
00275      size_t i, k;
00276 
00277      // number of orders for this user calculation
00278      // (not needed for order zero)
00279      const size_t user_q1 = q+1;
00280 
00281      // variable indices for results vector 
00282      // (done differently for order zero).
00283      vector<size_t> user_iy;      
00284 
00285      // skip the BeginOp at the beginning of the recording
00286      play->forward_start(op, arg, i_op, i_var);
00287      CPPAD_ASSERT_UNKNOWN( op == BeginOp );
00288 # if CPPAD_FORWARD1SWEEP_TRACE
00289      std::cout << std::endl;
00290 # endif
00291      bool more_operators = true;
00292      while(more_operators)
00293      {
00294           // this op
00295           play->forward_next(op, arg, i_op, i_var);
00296           CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) );  
00297           CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) );  
00298           CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
00299 
00300           // check if we are skipping this operation
00301           while( cskip_op[i_op] )
00302           {    if( op == CSumOp )
00303                {    // CSumOp has a variable number of arguments 
00304                     play->forward_csum(op, arg, i_op, i_var);
00305                }
00306                play->forward_next(op, arg, i_op, i_var);
00307                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
00308           }
00309 
00310           // action depends on the operator
00311           switch( op )
00312           {
00313                case AbsOp:
00314                forward_abs_op(p, q, i_var, arg[0], J, taylor);
00315                break;
00316                // -------------------------------------------------
00317 
00318                case AddvvOp:
00319                forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);
00320                break;
00321                // -------------------------------------------------
00322 
00323                case AddpvOp:
00324                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00325                forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);
00326                break;
00327                // -------------------------------------------------
00328 
00329                case AcosOp:
00330                // sqrt(1 - x * x), acos(x)
00331                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00332                forward_acos_op(p, q, i_var, arg[0], J, taylor);
00333                break;
00334                // -------------------------------------------------
00335 
00336                case AsinOp:
00337                // sqrt(1 - x * x), asin(x)
00338                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00339                forward_asin_op(p, q, i_var, arg[0], J, taylor);
00340                break;
00341                // -------------------------------------------------
00342 
00343                case AtanOp:
00344                // 1 + x * x, atan(x)
00345                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00346                forward_atan_op(p, q, i_var, arg[0], J, taylor);
00347                break;
00348                // -------------------------------------------------
00349 
00350                case CExpOp:
00351                forward_cond_op(
00352                     p, q, i_var, arg, num_par, parameter, J, taylor
00353                );
00354                break;
00355                // ---------------------------------------------------
00356 
00357                case ComOp:
00358                if( p == 0 ) forward_comp_op_0(
00359                compareCount, arg, num_par, parameter, J, taylor
00360                );
00361                break;
00362                // ---------------------------------------------------
00363 
00364                case CosOp:
00365                // sin(x), cos(x)
00366                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00367                forward_cos_op(p, q, i_var, arg[0], J, taylor);
00368                break;
00369                // ---------------------------------------------------
00370 
00371                case CoshOp:
00372                // sinh(x), cosh(x)
00373                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00374                forward_cosh_op(p, q, i_var, arg[0], J, taylor);
00375                break;
00376                // -------------------------------------------------
00377 
00378                case CSkipOp:
00379                // CSkipOp has a variable number of arguments and
00380                // forward_next thinks it has no arguments.
00381                // we must inform forward_next of this special case.
00382                if( p == 0 )
00383                {    forward_cskip_op_0(
00384                          i_var, arg, num_par, parameter, J, taylor, cskip_op
00385                     );
00386                }
00387                play->forward_cskip(op, arg, i_op, i_var);
00388                break;
00389                // -------------------------------------------------
00390 
00391                case CSumOp:
00392                // CSumOp has a variable number of arguments and
00393                // forward_next thinks it has no arguments.
00394                // we must inform forward_next of this special case.
00395                forward_csum_op(
00396                     p, q, i_var, arg, num_par, parameter, J, taylor
00397                );
00398                play->forward_csum(op, arg, i_op, i_var);
00399                break;
00400                // -------------------------------------------------
00401 
00402                case DisOp:
00403                i = p;
00404                if( i == 0 )
00405                {    forward_dis_op_0(i_var, arg, J, taylor);
00406                     i++;
00407                }
00408                while(i <= q)
00409                {    taylor[ i_var * J + i] = Base(0);
00410                     i++;
00411                }
00412                break;
00413                // -------------------------------------------------
00414 
00415                case DivvvOp:
00416                forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);
00417                break;
00418                // -------------------------------------------------
00419 
00420                case DivpvOp:
00421                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00422                forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);
00423                break;
00424                // -------------------------------------------------
00425 
00426                case DivvpOp:
00427                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00428                forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);
00429                break;
00430                // -------------------------------------------------
00431 
00432                case EndOp:
00433                CPPAD_ASSERT_NARG_NRES(op, 0, 0);
00434                more_operators = false;
00435                break;
00436                // -------------------------------------------------
00437 
00438                case ExpOp:
00439                forward_exp_op(p, q, i_var, arg[0], J, taylor);
00440                break;
00441                // -------------------------------------------------
00442 
00443                case InvOp:
00444                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );
00445                break;
00446                // -------------------------------------------------
00447 
00448                case LdpOp:
00449                if( p == 0 )
00450                {    forward_load_p_op_0(
00451                          play,
00452                          i_var, 
00453                          arg, 
00454                          parameter, 
00455                          J, 
00456                          taylor,
00457                          isvar_by_ind.data(),
00458                          index_by_ind.data(),
00459                          var_by_load_op.data()
00460                     );
00461                     if( p < q ) forward_load_op( 
00462                     op, p+1, q, i_var, arg, J, taylor, var_by_load_op.data()
00463                     );
00464                }
00465                else forward_load_op(
00466                     op, p, q, i_var, arg, J, taylor, var_by_load_op.data()
00467                );
00468                break;
00469                // -------------------------------------------------
00470 
00471                case LdvOp:
00472                if( p == 0 )
00473                {    forward_load_v_op_0(
00474                          play,
00475                          i_var, 
00476                          arg, 
00477                          parameter, 
00478                          J, 
00479                          taylor,
00480                          isvar_by_ind.data(),
00481                          index_by_ind.data(),
00482                          var_by_load_op.data()
00483                     );
00484                     if( p < q ) forward_load_op(
00485                     op, p+1, q, i_var, arg, J, taylor, var_by_load_op.data()
00486                     );
00487                }
00488                else forward_load_op( 
00489                op, p, q, i_var, arg, J, taylor, var_by_load_op.data()
00490                );
00491                break;
00492                // -------------------------------------------------
00493 
00494                case LogOp:
00495                forward_log_op(p, q, i_var, arg[0], J, taylor);
00496                break;
00497                // -------------------------------------------------
00498 
00499                case MulvvOp:
00500                forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
00501                break;
00502                // -------------------------------------------------
00503 
00504                case MulpvOp:
00505                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00506                forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
00507                break;
00508                // -------------------------------------------------
00509 
00510                case ParOp:
00511                i = p;
00512                if( i == 0 )
00513                {    forward_par_op_0(
00514                          i_var, arg, num_par, parameter, J, taylor
00515                     );
00516                     i++;
00517                }
00518                while(i <= q)
00519                {    taylor[ i_var * J + i] = Base(0); 
00520                     i++;
00521                }
00522                break;
00523                // -------------------------------------------------
00524 
00525                case PowvpOp:
00526                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00527                forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
00528                break;
00529                // -------------------------------------------------
00530 
00531                case PowpvOp:
00532                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00533                forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
00534                break;
00535                // -------------------------------------------------
00536 
00537                case PowvvOp:
00538                forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
00539                break;
00540                // -------------------------------------------------
00541 
00542                case PriOp:
00543                if( (p == 0) & print ) forward_pri_0(s_out,
00544                     i_var, arg, num_text, text, num_par, parameter, J, taylor
00545                );
00546                break;
00547                // -------------------------------------------------
00548 
00549                case SignOp:
00550                // sign(x)
00551                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00552                forward_sign_op(p, q, i_var, arg[0], J, taylor);
00553                break;
00554                // -------------------------------------------------
00555 
00556                case SinOp:
00557                // cos(x), sin(x)
00558                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00559                forward_sin_op(p, q, i_var, arg[0], J, taylor);
00560                break;
00561                // -------------------------------------------------
00562 
00563                case SinhOp:
00564                // cosh(x), sinh(x)
00565                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00566                forward_sinh_op(p, q, i_var, arg[0], J, taylor);
00567                break;
00568                // -------------------------------------------------
00569 
00570                case SqrtOp:
00571                forward_sqrt_op(p, q, i_var, arg[0], J, taylor);
00572                break;
00573                // -------------------------------------------------
00574 
00575                case StppOp:
00576                if( p == 0 )
00577                {    forward_store_pp_op_0(
00578                          i_var, 
00579                          arg, 
00580                          num_par, 
00581                          J, 
00582                          taylor,
00583                          isvar_by_ind.data(),
00584                          index_by_ind.data()
00585                     );
00586                }
00587                break;
00588                // -------------------------------------------------
00589 
00590                case StpvOp:
00591                if( p == 0 )
00592                {    forward_store_pv_op_0(
00593                          i_var, 
00594                          arg, 
00595                          num_par, 
00596                          J, 
00597                          taylor,
00598                          isvar_by_ind.data(),
00599                          index_by_ind.data()
00600                     );
00601                }
00602                break;
00603                // -------------------------------------------------
00604 
00605                case StvpOp:
00606                if( p == 0 )
00607                {    forward_store_vp_op_0(
00608                          i_var, 
00609                          arg, 
00610                          num_par, 
00611                          J, 
00612                          taylor,
00613                          isvar_by_ind.data(),
00614                          index_by_ind.data()
00615                     );
00616                }
00617                break;
00618                // -------------------------------------------------
00619 
00620                case StvvOp:
00621                if( p == 0 )
00622                {    forward_store_vv_op_0(
00623                          i_var, 
00624                          arg, 
00625                          num_par, 
00626                          J, 
00627                          taylor,
00628                          isvar_by_ind.data(),
00629                          index_by_ind.data()
00630                     );
00631                }
00632                break;
00633                // -------------------------------------------------
00634 
00635                case SubvvOp:
00636                forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
00637                break;
00638                // -------------------------------------------------
00639 
00640                case SubpvOp:
00641                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00642                forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
00643                break;
00644                // -------------------------------------------------
00645 
00646                case SubvpOp:
00647                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
00648                forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
00649                break;
00650                // -------------------------------------------------
00651 
00652                case TanOp:
00653                // tan(x)^2, tan(x)
00654                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00655                forward_tan_op(p, q, i_var, arg[0], J, taylor);
00656                break;
00657                // -------------------------------------------------
00658 
00659                case TanhOp:
00660                // tanh(x)^2, tanh(x)
00661                CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
00662                forward_tanh_op(p, q, i_var, arg[0], J, taylor);
00663                break;
00664                // -------------------------------------------------
00665 
00666                case UserOp:
00667                // start or end an atomic operation sequence
00668                CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
00669                CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
00670                if( user_state == user_start )
00671                {    user_index = arg[0];
00672                     user_id    = arg[1];
00673                     user_n     = arg[2];
00674                     user_m     = arg[3];
00675                     user_atom  = atomic_base<Base>::class_object(user_index);
00676 # ifndef NDEBUG
00677                     if( user_atom == CPPAD_NULL )
00678                     {    std::string msg = 
00679                               atomic_base<Base>::class_name(user_index)
00680                               + ": atomic_base function has been deleted";
00681                          CPPAD_ASSERT_KNOWN(false, msg.c_str() );
00682                     }
00683 # endif
00684                     if(user_tx.size() != user_n * user_q1)
00685                          user_tx.resize(user_n * user_q1);
00686                     if(user_ty.size() != user_m * user_q1)
00687                          user_ty.resize(user_m * user_q1);
00688                     if(user_iy.size() != user_m)
00689                          user_iy.resize(user_m);
00690                     user_j     = 0;
00691                     user_i     = 0;
00692                     user_state = user_arg;
00693                }
00694                else
00695                {    CPPAD_ASSERT_UNKNOWN( user_state == user_end );
00696                     CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
00697                     CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
00698                     CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
00699                     CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
00700 
00701                     // call users function for this operation
00702                     user_atom->set_id(user_id);
00703                     CPPAD_ATOMIC_CALL(
00704                          p, q, user_vx, user_vy, user_tx, user_ty
00705                     );
00706 # ifndef NDEBUG
00707                     if( ! user_ok )
00708                     {    std::string msg = 
00709                               atomic_base<Base>::class_name(user_index)
00710                               + ": atomic_base.forward: returned false";
00711                          CPPAD_ASSERT_KNOWN(false, msg.c_str() );
00712                     }
00713 # endif
00714                     for(i = 0; i < user_m; i++) 
00715                          if( user_iy[i] > 0 )
00716                               for(k = p; k <= q; k++)
00717                                    taylor[ user_iy[i] * J + k ] = 
00718                                         user_ty[ i * user_q1 + k ];
00719 
00720                     user_state = user_start;
00721                }
00722                break;
00723 
00724                case UsrapOp:
00725                // parameter argument in an atomic operation sequence
00726                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00727                CPPAD_ASSERT_UNKNOWN( user_j < user_n );
00728                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
00729                user_tx[user_j * user_q1 + 0] = parameter[ arg[0]];
00730                for(k = 1; k < user_q1; k++)
00731                     user_tx[user_j * user_q1 + k] = Base(0);
00732                ++user_j;
00733                if( user_j == user_n )
00734                     user_state = user_ret;
00735                break;
00736 
00737                case UsravOp:
00738                // variable argument in an atomic operation sequence
00739                CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
00740                CPPAD_ASSERT_UNKNOWN( user_j < user_n );
00741                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
00742                for(k = 0; k < user_q1; k++)
00743                     user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k];
00744                ++user_j;
00745                if( user_j == user_n )
00746                     user_state = user_ret;
00747                break;
00748 
00749                case UsrrpOp:
00750                // parameter result in an atomic operation sequence
00751                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00752                CPPAD_ASSERT_UNKNOWN( user_i < user_m );
00753                user_iy[user_i] = 0;
00754                user_ty[user_i * user_q1 + 0] = parameter[ arg[0]];
00755                for(k = 1; k < p; k++)
00756                     user_ty[user_i * user_q1 + k] = Base(0);
00757                user_i++;
00758                if( user_i == user_m )
00759                     user_state = user_end;
00760                break;
00761 
00762                case UsrrvOp:
00763                // variable result in an atomic operation sequence
00764                CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
00765                CPPAD_ASSERT_UNKNOWN( user_i < user_m );
00766                user_iy[user_i] = i_var;
00767                for(k = 0; k < p; k++)
00768                     user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k];
00769                user_i++;
00770                if( user_i == user_m )
00771                     user_state = user_end;
00772                break;
00773                // -------------------------------------------------
00774 
00775                default:
00776                CPPAD_ASSERT_UNKNOWN(0);
00777           }
00778 # if CPPAD_FORWARD1SWEEP_TRACE
00779           size_t       i_tmp  = i_var;
00780           Base*        Z_tmp  = taylor + J * i_var;
00781           printOp(
00782                std::cout, 
00783                play,
00784                i_op,
00785                i_tmp,
00786                op, 
00787                arg,
00788                q + 1, 
00789                Z_tmp, 
00790                0, 
00791                (Base *) CPPAD_NULL
00792           );
00793      }
00794      std::cout << std::endl;
00795 # else
00796      }
00797 # endif
00798      CPPAD_ASSERT_UNKNOWN( user_state == user_start );
00799      CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
00800 
00801      return compareCount;
00802 }
00803 
00804 // preprocessor symbols that are local to this file
00805 # undef CPPAD_FORWARD1SWEEP_TRACE
00806 # undef CPPAD_ATOMIC_CALL
00807 
00808 } // END_CPPAD_NAMESPACE
00809 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines