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