CppAD: A C++ Algorithmic Differentiation Package  20130918
op_code.hpp
Go to the documentation of this file.
00001 /* $Id$ */
00002 # ifndef CPPAD_OP_CODE_INCLUDED
00003 # define CPPAD_OP_CODE_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 # include <string>
00016 # include <sstream>
00017 # include <iomanip>
00018 
00019 # include <cppad/local/define.hpp>
00020 # include <cppad/local/cppad_assert.hpp>
00021 
00022 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
00023 # include <cppad/thread_alloc.hpp>
00024 
00025 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
00026 /*!
00027 \file op_code.hpp
00028 Defines the OpCode enum type and functions related to it.
00029 
00030 */
00031 
00032 
00033 /*!
00034 Type used to distinguish different AD< \a Base > atomic operations.
00035 
00036 Each of the operators ends with the characters Op. Ignoring the Op at the end,
00037 the operators appear in alphabetical order. Binary operation where both
00038 operands have type AD< \a Base > use the following convention for thier endings:
00039 \verbatim
00040     Ending  Left-Operand  Right-Operand
00041       pvOp     parameter       variable  
00042       vpOp      variable      parameter  
00043       vvOp      variable       variable  
00044 \endverbatim
00045 For example, AddpvOp represents the addition operator where the left
00046 operand is a parameter and the right operand is a variable.
00047 */
00048 // alphabetical order is checked by bin/check_op_code.sh
00049 enum OpCode {
00050      AbsOp,    //  abs(variable)
00051      AcosOp,   // asin(variable)
00052      AddpvOp,  //      parameter  + variable
00053      AddvvOp,  //      variable   + variable
00054      AsinOp,   // asin(variable)
00055      AtanOp,   // atan(variable)
00056      BeginOp,  // used to mark the beginning of the tape
00057      CExpOp,   // CondExpRel(left, right, trueCase, falseCase)
00058      // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
00059      // arg[1] & 1 = is left a variable
00060      // arg[1] & 2 = is right a variable
00061      // arg[1] & 4 = is trueCase a variable
00062      // arg[1] & 8 = is falseCase a variable
00063      // arg[2]     = index correspoding to left 
00064      // arg[3]     = index correspoding to right 
00065      // arg[4]     = index correspoding to trueCase 
00066      // arg[5]     = index correspoding to falseCase 
00067      ComOp,    // Compare(cop, result, left, right)
00068      CosOp,    //  cos(variable)
00069      CoshOp,   // cosh(variable)
00070      CSkipOp,  // Conditional skip
00071      // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
00072      // arg[1] & 1 = is left a variable
00073      // arg[1] & 2 = is right a variable
00074      // arg[2]     = index correspoding to left 
00075      // arg[3]     = index correspoding to right 
00076      // arg[4] = number of operations to skip if CExpOp comparision is true
00077      // arg[5] = number of operations to skip if CExpOp comparision is false
00078      // arg[6] -> arg[5+arg[4]]               = skip operations if true
00079      // arg[6+arg[4]] -> arg[5+arg[4]+arg[5]] = skip operations if false
00080      // arg[6+arg[4]+arg[5]] = arg[4] + arg[5]
00081      CSumOp,   // Cummulative summation 
00082      // arg[0] = number of addition variables in summation
00083      // arg[1] = number of subtraction variables in summation
00084      // arg[2] = index of parameter that initializes summation
00085      // arg[3] -> arg[2+arg[0]] = index for positive variables
00086      // arg[3+arg[0]] -> arg[2+arg[0]+arg[1]] = index for minus variables 
00087      // arg[3+arg[0]+arg[1]] = arg[0] + arg[1]
00088      DisOp,    //  discrete::eval(index, variable)
00089      DivpvOp,  //      parameter  / variable
00090      DivvpOp,  //      variable   / parameter
00091      DivvvOp,  //      variable   / variable
00092      EndOp,    //  used to mark the end of the tape
00093      ExpOp,    //  exp(variable)
00094      InvOp,    //                             independent variable
00095      LdpOp,    //    z[parameter]
00096      LdvOp,    //    z[variable]
00097      LogOp,    //  log(variable)
00098      MulpvOp,  //      parameter  * variable
00099      MulvvOp,  //      variable   * variable
00100      ParOp,    //      parameter
00101      PowpvOp,  //  pow(parameter,   variable)
00102      PowvpOp,  //  pow(variable,    parameter)
00103      PowvvOp,  //  pow(variable,    variable)
00104      PriOp,    //  PrintFor(text, parameter or variable, parameter or variable)
00105      SignOp,   // sign(variable)
00106      SinOp,    //  sin(variable)
00107      SinhOp,   // sinh(variable)
00108      SqrtOp,   // sqrt(variable)
00109      StppOp,   //    z[parameter] = parameter
00110      StpvOp,   //    z[parameter] = variable
00111      StvpOp,   //    z[variable]  = parameter
00112      StvvOp,   //    z[variable]  = variable
00113      SubpvOp,  //      parameter  - variable
00114      SubvpOp,  //      variable   - parameter
00115      SubvvOp,  //      variable   - variable
00116      TanOp,    //  tan(variable)
00117      TanhOp,   //  tan(variable)
00118      // user atomic operation codes
00119      UserOp,   //  start of a user atomic operaiton
00120      // arg[0] = index of the operation if atomic_base<Base> class
00121      // arg[1] = extra information passed trough by deprecated old atomic class
00122      // arg[2] = number of arguments to this atomic function
00123      // arg[3] = number of results for this atomic function
00124      UsrapOp,  //  this user atomic argument is a parameter
00125      UsravOp,  //  this user atomic argument is a variable
00126      UsrrpOp,  //  this user atomic result is a parameter
00127      UsrrvOp,  //  this user atomic result is a variable
00128      NumberOp
00129 };
00130 // Note that bin/check_op_code.sh assumes the pattern '^\tNumberOp$' occurs
00131 // at the end of this list and only at the end of this list.
00132 
00133 /*!
00134 Number of arguments for a specified operator.
00135 
00136 \return
00137 Number of arguments corresponding to the specified operator.
00138 
00139 \param op 
00140 Operator for which we are fetching the number of arugments.
00141 
00142 \par NumArgTable
00143 this table specifes the number of arguments stored for each
00144 occurance of the operator that is the i-th value in the OpCode enum type.
00145 For example, for the first three OpCode enum values we have
00146 \verbatim
00147 OpCode   j   NumArgTable[j]  Meaning
00148 AbsOp    0                1  index of variable we are taking absolute value of
00149 AcosOp   1                1  index of variable we are taking cosine of
00150 AddpvOp  1                2  indices of parameter and variable we are adding
00151 \endverbatim
00152 Note that the meaning of the arguments depends on the operator.
00153 */
00154 inline size_t NumArg( OpCode op)
00155 {    CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
00156 
00157      // agreement with OpCode is checked by bin/check_op_code.sh
00158      static const size_t NumArgTable[] = {
00159           1, // AbsOp
00160           1, // AcosOp
00161           2, // AddpvOp
00162           2, // AddvvOp
00163           1, // AsinOp
00164           1, // AtanOp
00165           1, // BeginOp  offset first real argument to have index 1
00166           6, // CExpOp
00167           4, // ComOp
00168           1, // CosOp
00169           1, // CoshOp
00170           0, // CSkipOp  (actually has a variable number of arguments, not zero)
00171           0, // CSumOp   (actually has a variable number of arguments, not zero)
00172           2, // DisOp
00173           2, // DivpvOp
00174           2, // DivvpOp
00175           2, // DivvvOp
00176           0, // EndOp
00177           1, // ExpOp
00178           0, // InvOp
00179           3, // LdpOp
00180           3, // LdvOp
00181           1, // LogOp
00182           2, // MulpvOp
00183           2, // MulvvOp
00184           1, // ParOp
00185           2, // PowpvOp
00186           2, // PowvpOp
00187           2, // PowvvOp
00188           5, // PriOp
00189           1, // SignOp
00190           1, // SinOp
00191           1, // SinhOp
00192           1, // SqrtOp
00193           3, // StppOp
00194           3, // StpvOp
00195           3, // StvpOp
00196           3, // StvvOp
00197           2, // SubpvOp
00198           2, // SubvpOp
00199           2, // SubvvOp
00200           1, // TanOp
00201           1, // TanhOp
00202           4, // UserOp
00203           1, // UsrapOp
00204           1, // UsravOp
00205           1, // UsrrpOp
00206           0  // UsrrvOp
00207      };
00208 # ifndef NDEBUG
00209      // only do these checks once to save time
00210      static bool first = true;
00211      if( first )
00212      {    CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) ==
00213                sizeof(NumArgTable) / sizeof(NumArgTable[0])
00214           );
00215           CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) <=
00216                std::numeric_limits<CPPAD_OP_CODE_TYPE>::max()
00217           );
00218           first = false;
00219      }
00220      // do this check every time
00221      CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
00222 # endif
00223 
00224      return NumArgTable[op];
00225 }
00226 
00227 /*!
00228 Number of variables resulting from the specified operation.
00229 
00230 \param op
00231 Operator for which we are fecching the number of results.
00232 
00233 \par NumResTable
00234 table specifes the number of varibles that result for each
00235 occurance of the operator that is the i-th value in the OpCode enum type.
00236 For example, for the first three OpCode enum values we have
00237 \verbatim
00238 OpCode   j   NumResTable[j]  Meaning
00239 AbsOp    0                1  variable that is the result of the absolute value
00240 AcosOp   1                2  acos(x) and sqrt(1-x*x) are required for this op
00241 AddpvOp  1                1  variable that is the result of the addition
00242 \endverbatim
00243 */
00244 inline size_t NumRes(OpCode op)
00245 {    CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
00246 
00247      // agreement with OpCode is checked by bin/check_op_code.sh
00248      static const size_t NumResTable[] = {
00249           1, // AbsOp
00250           2, // AcosOp
00251           1, // AddpvOp
00252           1, // AddvvOp
00253           2, // AsinOp
00254           2, // AtanOp
00255           1, // BeginOp  offsets first variable to have index one (not zero)
00256           1, // CExpOp
00257           0, // ComOp
00258           2, // CosOp
00259           2, // CoshOp
00260           0, // CSkipOp
00261           1, // CSumOp
00262           1, // DisOp
00263           1, // DivpvOp
00264           1, // DivvpOp
00265           1, // DivvvOp
00266           0, // EndOp
00267           1, // ExpOp
00268           1, // InvOp
00269           1, // LdpOp
00270           1, // LdvOp
00271           1, // LogOp
00272           1, // MulpvOp
00273           1, // MulvvOp
00274           1, // ParOp
00275           3, // PowpvOp
00276           3, // PowvpOp
00277           3, // PowvvOp
00278           0, // PriOp
00279           1, // SignOp
00280           2, // SinOp
00281           2, // SinhOp
00282           1, // SqrtOp
00283           0, // StppOp
00284           0, // StpvOp
00285           0, // StvpOp
00286           0, // StvvOp
00287           1, // SubpvOp
00288           1, // SubvpOp
00289           1, // SubvvOp
00290           2, // TanOp
00291           2, // TanhOp
00292           0, // UserOp
00293           0, // UsrapOp
00294           0, // UsravOp
00295           0, // UsrrpOp
00296           1, // UsrrvOp
00297           0  // Last entry not used: avoids g++ 4.3.2 warn when pycppad builds
00298      };
00299      // check ensuring conversion to size_t is as expected
00300      CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) == 
00301           sizeof(NumResTable) / sizeof(NumResTable[0]) - 1
00302      );
00303      // this test ensures that all indices are within the table
00304      CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
00305 
00306      return NumResTable[op];
00307 }
00308 
00309 
00310 /*!
00311 Fetch the name for a specified operation.
00312 
00313 \return
00314 name of the specified operation.
00315 
00316 \param op 
00317 Operator for which we are fetching the name
00318 */
00319 inline const char* OpName(OpCode op)
00320 {    // agreement with OpCode is checked by bin/check_op_code.sh
00321      static const char *OpNameTable[] = {
00322           "Abs"   ,
00323           "Acos"  ,
00324           "Addpv" ,
00325           "Addvv" ,
00326           "Asin"  ,
00327           "Atan"  ,
00328           "Begin" ,
00329           "CExp"  ,
00330           "Com"   ,
00331           "Cos"   ,
00332           "Cosh"  ,
00333           "CSkip" ,
00334           "CSum"  ,
00335           "Dis"   ,
00336           "Divpv" ,
00337           "Divvp" ,
00338           "Divvv" ,
00339           "End"   ,
00340           "Exp"   ,
00341           "Inv"   ,
00342           "Ldp"   ,
00343           "Ldv"   ,
00344           "Log"   ,
00345           "Mulpv" ,
00346           "Mulvv" ,
00347           "Par"   ,
00348           "Powpv" ,
00349           "Powvp" ,
00350           "Powvv" ,
00351           "Pri"   ,
00352           "Sign"  ,
00353           "Sin"   ,
00354           "Sinh"  ,
00355           "Sqrt"  ,
00356           "Stpp"  ,
00357           "Stpv"  ,
00358           "Stvp"  ,
00359           "Stvv"  ,
00360           "Subpv" ,
00361           "Subvp" ,
00362           "Subvv" ,
00363           "Tan"   ,
00364           "Tanh"  ,
00365           "User"  ,
00366           "Usrap" ,
00367           "Usrav" ,
00368           "Usrrp" ,
00369           "Usrrv"  
00370      };
00371      // check ensuring conversion to size_t is as expected
00372      CPPAD_ASSERT_UNKNOWN( 
00373           size_t(NumberOp) == sizeof(OpNameTable)/sizeof(OpNameTable[0]) 
00374      );
00375      // this test ensures that all indices are within the table
00376      CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
00377 
00378      return OpNameTable[op];
00379 }
00380 
00381 /*!
00382 Prints a single field corresponding to an operator.
00383 
00384 A specified leader is printed in front of the value
00385 and then the value is left justified in the following width character.
00386 
00387 \tparam Type
00388 is the type of the value we are printing.
00389 
00390 \param os
00391 is the stream that we are printing to.
00392 
00393 \param leader
00394 are characters printed before the value.
00395 
00396 \param value
00397 is the value being printed.
00398 
00399 \param width
00400 is the number of character to print the value in.
00401 If the value does not fit in the width, the value is replace
00402 by width '*' characters.
00403 */
00404 template <class Type>
00405 void printOpField(
00406      std::ostream      &os , 
00407      const char *   leader ,
00408      const Type     &value , 
00409      size_t          width )
00410 {
00411      std::ostringstream buffer;
00412      std::string        str;
00413 
00414      // first print the leader
00415      os << leader;
00416 
00417      // print the value into an internal buffer
00418      buffer << std::setw(width) << value;
00419      str = buffer.str();
00420 
00421      // length of the string
00422      size_t len = str.size();
00423      if( len > width )
00424      {    size_t i;
00425           for(i = 0; i < width-1; i++)
00426                os << str[i];
00427           os << "*";
00428           return;
00429      }
00430 
00431      // count number of spaces at begining
00432      size_t nspace = 0; 
00433      while(str[nspace] == ' ' && nspace < len)
00434           nspace++;
00435 
00436      // left justify the string
00437      size_t i = nspace;
00438      while( i < len )
00439           os << str[i++];
00440 
00441      i = width - len + nspace;
00442      while(i--)
00443           os << " "; 
00444 }
00445 
00446 /*!
00447 Prints a single operator, its operands, and the corresponding result values.
00448 
00449 \tparam Base
00450 Is the base type for these AD< \a Base > operations.
00451 
00452 \tparam Value
00453 Determines the type of the values that we are printing.
00454 
00455 \param os
00456 is the output stream that the information is printed on.
00457 
00458 \param Rec
00459 2DO: change this name from Rec to play (becuase it is a player 
00460 and not a recorder).
00461 Is the entire recording for the tape that this operator is in.
00462 
00463 \param i_op
00464 is the index for the operator corresponding to this operation.
00465 
00466 \param i_var
00467 is the index for the variable corresponding to the result of this operation
00468 (ignored if NumRes(op) == 0).
00469 
00470 \param op
00471 The operator code (OpCode) for this operation.
00472 
00473 \param ind
00474 is the vector of argument indices for this operation
00475 (must have NumArg(op) elements).
00476 
00477 \param nfz
00478 is the number of forward sweep calculated values of type Value
00479 that correspond to this operation
00480 (ignored if NumRes(op) == 0).
00481 
00482 \param fz
00483 points to the first forward calculated value
00484 that correspond to this operation
00485 (ignored if NumRes(op) == 0).
00486 
00487 \param nrz
00488 is the number of reverse sweep calculated values of type Value
00489 that correspond to this operation
00490 (ignored if NumRes(op) == 0).
00491 
00492 \param rz
00493 points to the first reverse calculated value
00494 that correspond to this operation
00495 (ignored if NumRes(op) == 0).
00496 
00497 \par 2DO
00498 print the operator index (in addition to the variables index).
00499 */
00500 template <class Base, class Value>
00501 void printOp(
00502      std::ostream          &os     , 
00503      const player<Base>   *Rec     ,
00504      size_t                 i_op   , 
00505      size_t                 i_var  , 
00506      OpCode                 op     ,
00507      const addr_t          *ind    ,
00508      size_t                 nfz    ,
00509      const  Value          *fz     ,
00510      size_t                 nrz    ,
00511      const  Value          *rz     )
00512 {    size_t i;
00513      CPPAD_ASSERT_KNOWN(
00514           ! thread_alloc::in_parallel() ,
00515           "cannot print trace of AD operations in parallel mode"
00516      );
00517      static const char *CompareOpName[] = 
00518           { "Lt", "Le", "Eq", "Ge", "Gt", "Ne" };
00519 
00520      // print operator
00521      printOpField(os,  "o=",      i_op,  5);
00522      printOpField(os,  "v=",      i_var, 5);
00523      if( op == CExpOp || op == CSkipOp || op == ComOp )
00524      {    printOpField(os, "", OpName(op), 5); 
00525           printOpField(os, "", CompareOpName[ ind[0] ], 3);
00526      }
00527      else printOpField(os, "", OpName(op), 8); 
00528 
00529      // print other fields
00530      size_t ncol = 5;
00531      switch( op )
00532      {
00533           case CSkipOp:
00534           /*
00535           ind[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
00536           ind[1] & 1 = is left a variable
00537           ind[1] & 2 = is right a variable
00538           ind[2]     = index correspoding to left 
00539           ind[3]     = index correspoding to right 
00540           ind[4] = number of operations to skip if CExpOp comparision is true
00541           ind[5] = number of operations to skip if CExpOp comparision is false
00542           ind[6] -> ind[5+ind[4]]               = skip operations if true
00543           ind[6+ind[4]] -> ind[5+ind[4]+ind[5]] = skip operations if false
00544           ind[6+ind[4]+ind[5]] = ind[4] + ind[5]
00545           */
00546           CPPAD_ASSERT_UNKNOWN( ind[6+ind[4]+ind[5]] == ind[4]+ind[5] );
00547           CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
00548           if( ind[1] & 1 )
00549                printOpField(os, " vl=", ind[2], ncol);
00550           else printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
00551           if( ind[1] & 2 )
00552                printOpField(os, " vr=", ind[3], ncol);
00553           else printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
00554           if( size_t(ind[4]) < 3 )
00555           {    for(i = 0; i < size_t(ind[4]); i++)
00556                     printOpField(os, " ot=", ind[6+i], ncol);
00557           }
00558           else
00559           {    printOpField(os, "\n\tot=", ind[6+0], ncol);
00560                for(i = 1; i < size_t(ind[4]); i++)
00561                     printOpField(os, " ot=", ind[6+i], ncol);
00562           }
00563           if( size_t(ind[5]) < 3 )
00564           {    for(i = 0; i < size_t(ind[5]); i++)
00565                     printOpField(os, " of=", ind[6+ind[4]+i], ncol);
00566           }
00567           else
00568           {    printOpField(os, "\n\tof=", ind[6+ind[4]+0], ncol);
00569                {    for(i = 1; i < size_t(ind[5]); i++)
00570                          printOpField(os, " of=", ind[6+ind[4]+i], ncol);
00571                }
00572           }
00573           break;
00574 
00575           case CSumOp:
00576           /*
00577           ind[0] = number of addition variables in summation
00578           ind[1] = number of subtraction variables in summation
00579           ind[2] = index of parameter that initializes summation
00580           ind[3], ... , ind[2+ind[0]] = index for positive variables
00581           ind[3+ind[0]], ..., ind[2+ind[0]+ind[1]] = negative variables 
00582           ind[3+ind[0]+ind[1]] == ind[0] + ind[1]
00583           */
00584           CPPAD_ASSERT_UNKNOWN( ind[3+ind[0]+ind[1]] == ind[0]+ind[1] );
00585           printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
00586           for(i = 0; i < size_t(ind[0]); i++)
00587                 printOpField(os, " +v=", ind[3+i], ncol);
00588           for(i = 0; i < size_t(ind[1]); i++)
00589                 printOpField(os, " -v=", ind[3+ind[0]+i], ncol);
00590           break;
00591 
00592           case LdpOp:
00593           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00594           printOpField(os, "off=", ind[0], ncol);
00595           printOpField(os, "idx=", ind[1], ncol);
00596           break;
00597 
00598           case LdvOp:
00599           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00600           printOpField(os, "off=", ind[0], ncol);
00601           printOpField(os, "  v=", ind[1], ncol);
00602           break;
00603 
00604           case StppOp:
00605           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00606           printOpField(os, "off=", ind[0], ncol);
00607           printOpField(os, "idx=", ind[1], ncol);
00608           printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
00609           break;
00610 
00611           case StpvOp:
00612           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00613           printOpField(os, "off=", ind[0], ncol);
00614           printOpField(os, "idx=", ind[1], ncol);
00615           printOpField(os, " vr=", ind[2], ncol);
00616           break;
00617 
00618           case StvpOp:
00619           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00620           printOpField(os, "off=", ind[0], ncol);
00621           printOpField(os, " vl=", ind[1], ncol);
00622           printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
00623           break;
00624 
00625           case StvvOp:
00626           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
00627           printOpField(os, "off=", ind[0], ncol);
00628           printOpField(os, " vl=", ind[1], ncol);
00629           printOpField(os, " vr=", ind[2], ncol);
00630           break;
00631 
00632           case AddvvOp:
00633           case DivvvOp:
00634           case MulvvOp:
00635           case PowvvOp:
00636           case SubvvOp:
00637           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
00638           printOpField(os, " vl=", ind[0], ncol);
00639           printOpField(os, " vr=", ind[1], ncol);
00640           break;
00641 
00642           case AddpvOp:
00643           case SubpvOp:
00644           case MulpvOp:
00645           case PowpvOp:
00646           case DivpvOp:
00647           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
00648           printOpField(os, " pl=", Rec->GetPar(ind[0]), ncol);
00649           printOpField(os, " vr=", ind[1], ncol);
00650           break;
00651 
00652           case DivvpOp:
00653           case PowvpOp:
00654           case SubvpOp:
00655           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
00656           printOpField(os, " vl=", ind[0], ncol);
00657           printOpField(os, " pr=", Rec->GetPar(ind[1]), ncol);
00658           break;
00659 
00660           case AbsOp:
00661           case AcosOp:
00662           case AsinOp:
00663           case AtanOp:
00664           case CosOp:
00665           case CoshOp:
00666           case ExpOp:
00667           case LogOp:
00668           case SignOp:
00669           case SinOp:
00670           case SinhOp:
00671           case SqrtOp:
00672           case UsravOp:
00673           case TanOp:
00674           case TanhOp:
00675           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00676           printOpField(os, "  v=", ind[0], ncol);
00677           break;
00678 
00679           case ParOp:
00680           case UsrapOp:
00681           case UsrrpOp:
00682           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00683           printOpField(os, "  p=", Rec->GetPar(ind[0]), ncol);
00684           break;
00685 
00686           case UserOp:
00687           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
00688           {    std::string name =  atomic_base<Base>::class_name(ind[0]);
00689                printOpField(os, " f=",   name.c_str(), ncol);
00690                printOpField(os, " i=", ind[1], ncol);
00691                printOpField(os, " n=", ind[2], ncol);
00692                printOpField(os, " m=", ind[3], ncol);
00693           }
00694           break;
00695 
00696           case PriOp:
00697           CPPAD_ASSERT_NARG_NRES(op, 5, 0);
00698           if( ind[0] & 1 )
00699                printOpField(os, " v=", ind[1], ncol);
00700           else printOpField(os, " p=", Rec->GetPar(ind[1]), ncol);
00701           os << "before=\"" << Rec->GetTxt(ind[2]) << "\"";
00702           if( ind[0] & 2 )
00703                printOpField(os, " v=", ind[3], ncol);
00704           else printOpField(os, " p=", Rec->GetPar(ind[3]), ncol);
00705           os << "after=\"" << Rec->GetTxt(ind[4]) << "\"";
00706           break;
00707 
00708           case BeginOp:
00709           // argument not used (created by independent)
00710           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
00711           break;
00712 
00713           case EndOp:
00714           case InvOp:
00715           case UsrrvOp:
00716           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );
00717           break;
00718 
00719           case DisOp:
00720           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
00721           {    const char* name = discrete<Base>::name(ind[0]);
00722                printOpField(os, " f=", name, ncol);
00723                printOpField(os, " x=", ind[1], ncol);
00724           }
00725           break;
00726      
00727 
00728           case CExpOp:
00729           CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
00730           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );
00731           if( ind[1] & 1 )
00732                printOpField(os, " vl=", ind[2], ncol);
00733           else printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
00734           if( ind[1] & 2 )
00735                printOpField(os, " vr=", ind[3], ncol);
00736           else printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
00737           if( ind[1] & 4 )
00738                printOpField(os, " vt=", ind[4], ncol);
00739           else printOpField(os, " pt=", Rec->GetPar(ind[4]), ncol);
00740           if( ind[1] & 8 )
00741                printOpField(os, " vf=", ind[5], ncol);
00742           else printOpField(os, " pf=", Rec->GetPar(ind[5]), ncol);
00743           break;
00744 
00745           case ComOp:
00746           CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
00747           CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
00748           if( ind[1] & 1 )
00749                printOpField(os, "res=", 1, ncol);
00750           else printOpField(os, "res=", 0, ncol);
00751           if( ind[1] & 2 )
00752                printOpField(os, " vl=", ind[2], ncol);
00753           else printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
00754           if( ind[1] & 4 )
00755                printOpField(os, " vr=", ind[3], ncol);
00756           else printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
00757           break;
00758 
00759           default:
00760           CPPAD_ASSERT_UNKNOWN(0);
00761      }
00762      size_t k;
00763      if( NumRes(op) > 0 && (op != BeginOp) )
00764      { 
00765           for(k = 0; k < nfz; k++)
00766                std::cout << "| fz[" << k << "]=" << fz[k];
00767           for(k = 0; k < nrz; k++)
00768                std::cout << "| rz[" << k << "]=" << rz[k];
00769      }
00770      std::cout << std::endl;
00771 }
00772 
00773 } // END_CPPAD_NAMESPACE
00774 # endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines