source: branches/opt_cond_exp/cppad/local/op_code.hpp @ 2978

Last change on this file since 2978 was 2978, checked in by bradbell, 7 years ago

Change conditional skip to skipping operations instead of skipping variables.

  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: op_code.hpp 2978 2013-10-20 15:38:57Z bradbell $ */
2# ifndef CPPAD_OP_CODE_INCLUDED
3# define CPPAD_OP_CODE_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 Bradley M. Bell
7
8CppAD is distributed under multiple licenses. This distribution is under
9the terms of the
10                    Eclipse Public License Version 1.0.
11
12A copy of this license is included in the COPYING file of this distribution.
13Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14-------------------------------------------------------------------------- */
15# include <string>
16# include <sstream>
17# include <iomanip>
18
19# include <cppad/local/define.hpp>
20# include <cppad/local/cppad_assert.hpp>
21
22// needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
23# include <cppad/thread_alloc.hpp>
24
25namespace CppAD { // BEGIN_CPPAD_NAMESPACE
26/*!
27\defgroup op_code_hpp op_code.hpp
28\{
29\file op_code.hpp
30Defines the OpCode enum type and functions related to it.
31
32*/
33
34
35/*!
36Type used to distinguish different AD< \a Base > atomic operations.
37
38Each of the operators ends with the characters Op. Ignoring the Op at the end,
39the operators appear in alphabetical order. Binary operation where both
40operands have type AD< \a Base > use the following convention for thier endings:
41\verbatim
42    Ending  Left-Operand  Right-Operand
43      pvOp     parameter       variable 
44      vpOp      variable      parameter 
45      vvOp      variable       variable 
46\endverbatim
47For example, AddpvOp represents the addition operator where the left
48operand is a parameter and the right operand is a variable.
49*/
50enum OpCode {
51        AbsOp,    //  abs(variable)
52        AcosOp,   // asin(variable)
53        AddpvOp,  //      parameter  + variable
54        AddvvOp,  //      variable   + variable
55        AsinOp,   // asin(variable)
56        AtanOp,   // atan(variable)
57        BeginOp,  // used to mark the beginning of the tape
58        CExpOp,   // CondExpRel(left, right, trueCase, falseCase)
59        // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
60        // arg[1] & 1 = is left a variable
61        // arg[1] & 2 = is right a variable
62        // arg[1] & 4 = is trueCase a variable
63        // arg[1] & 8 = is falseCase a variable
64        // arg[2]     = index correspoding to left
65        // arg[3]     = index correspoding to right
66        // arg[4]     = index correspoding to trueCase
67        // arg[5]     = index correspoding to falseCase
68        ComOp,    // Compare(cop, result, left, right)
69        CosOp,    //  cos(variable)
70        CoshOp,   // cosh(variable)
71        CSkipOp,  // Conditional skip
72        // arg[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
73        // arg[1] & 1 = is left a variable
74        // arg[1] & 2 = is right a variable
75        // arg[2]     = index correspoding to left
76        // arg[3]     = index correspoding to right
77        // arg[4] = number of operations to skip if CExpOp comparision is true
78        // arg[5] = number of operations to skip if CExpOp comparision is false
79        // arg[6] -> arg[5+arg[4]]               = skip operations if true
80        // arg[6+arg[4]] -> arg[5+arg[4]+arg[5]] = skip operations if false
81        // arg[6+arg[4]+arg[5]] = arg[4] + arg[5]
82        CSumOp,   // Cummulative summation
83        // arg[0] = number of addition variables in summation
84        // arg[1] = number of subtraction variables in summation
85        // arg[2] = index of parameter that initializes summation
86        // arg[3] -> arg[2+arg[0]] = index for positive variables
87        // arg[3+arg[0]] -> arg[2+arg[0]+arg[1]] = index for minus variables
88        // arg[3+arg[0]+arg[1]] = arg[0] + arg[1]
89        DisOp,    //  discrete::eval(index, variable)
90        DivpvOp,  //      parameter  / variable
91        DivvpOp,  //      variable   / parameter
92        DivvvOp,  //      variable   / variable
93        EndOp,    //  used to mark the end of the tape
94        ExpOp,    //  exp(variable)
95        InvOp,    //                             independent variable
96        LdpOp,    //    z[parameter]
97        LdvOp,    //    z[variable]
98        LogOp,    //  log(variable)
99        MulpvOp,  //      parameter  * variable
100        MulvvOp,  //      variable   * variable
101        ParOp,    //      parameter
102        PowpvOp,  //  pow(parameter,   variable)
103        PowvpOp,  //  pow(variable,    parameter)
104        PowvvOp,  //  pow(variable,    variable)
105        PriOp,    //  PrintFor(text, parameter or variable, parameter or variable)
106        SignOp,   // sign(variable)
107        SinOp,    //  sin(variable)
108        SinhOp,   // sinh(variable)
109        SqrtOp,   // sqrt(variable)
110        StppOp,   //    z[parameter] = parameter
111        StpvOp,   //    z[parameter] = variable
112        StvpOp,   //    z[variable]  = parameter
113        StvvOp,   //    z[variable]  = variable
114        SubpvOp,  //      parameter  - variable
115        SubvpOp,  //      variable   - parameter
116        SubvvOp,  //      variable   - variable
117        TanOp,    //  tan(variable)
118        TanhOp,   //  tan(variable)
119        // user atomic operation codes
120        UserOp,   //  start of a user atomic operaiton
121        // arg[0] = index of the operation if atomic_base<Base> class
122        // arg[1] = extra information passed trough by deprecated old atomic class
123        // arg[2] = number of arguments to this atomic function
124        // arg[3] = number of results for this atomic function
125        UsrapOp,  //  this user atomic argument is a parameter
126        UsravOp,  //  this user atomic argument is a variable
127        UsrrpOp,  //  this user atomic result is a parameter
128        UsrrvOp,  //  this user atomic result is a variable
129        NumberOp
130};
131// Note that bin/check_op_code.sh assumes the pattern '^\tNumberOp$' occurs
132// at the end of this list and only at the end of this list.
133
134/*!
135Table containing number of arguments for the corresponding operator.
136
137The i-th element in this table specifes the number of arguments stored for each
138occurance of the operator that is the i-th value in the OpCode enum type.
139For example, for the first three OpCode enum values we have
140\verbatim
141OpCode   j   NumArgTable[j]  Meaning
142AbsOp    0                1  index of variable we are taking absolute value of
143AcosOp   1                1  index of variable we are taking cosine of
144AddpvOp  1                2  indices of parameter and variable we are adding
145\endverbatim
146Note that the meaning of the arguments depends on the operator.
147*/
148const size_t NumArgTable[] = {
149        1, // AbsOp
150        1, // AcosOp
151        2, // AddpvOp
152        2, // AddvvOp
153        1, // AsinOp
154        1, // AtanOp
155        0, // BeginOp
156        6, // CExpOp
157        4, // ComOp
158        1, // CosOp
159        1, // CoshOp
160        0, // CSkipOp  (actually has a variable number of arguments, not zero)
161        0, // CSumOp   (actually has a variable number of arguments, not zero)
162        2, // DisOp
163        2, // DivpvOp
164        2, // DivvpOp
165        2, // DivvvOp
166        0, // EndOp
167        1, // ExpOp
168        0, // InvOp
169        3, // LdpOp
170        3, // LdvOp
171        1, // LogOp
172        2, // MulpvOp
173        2, // MulvvOp
174        1, // ParOp
175        2, // PowpvOp
176        2, // PowvpOp
177        2, // PowvvOp
178        5, // PriOp
179        1, // SignOp
180        1, // SinOp
181        1, // SinhOp
182        1, // SqrtOp
183        3, // StppOp
184        3, // StpvOp
185        3, // StvpOp
186        3, // StvvOp
187        2, // SubpvOp
188        2, // SubvpOp
189        2, // SubvvOp
190        1, // TanOp
191        1, // TanhOp
192        4, // UserOp
193        1, // UsrapOp
194        1, // UsravOp
195        1, // UsrrpOp
196        0  // UsrrvOp
197};
198
199/*!
200Fetch the number of arguments for a specified operator.
201
202\return
203Number of arguments corresponding to the specified operator.
204
205\param op
206Operator for which we are fetching the number of arugments.
207
208- Check that argument taple size equal to NumberOp
209- Check that \c CPPAD_OP_CODE_TYPE can support all the operator codes.
210- Check that \c op is a valid operator value.
211*/
212inline size_t NumArg( OpCode op)
213{       CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
214# ifndef NDEBUG
215        // only do these checks once to save time
216        static bool first = true;
217        if( first )
218        {       CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) ==
219                        sizeof(NumArgTable) / sizeof(NumArgTable[0])
220                );
221                CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) <=
222                        std::numeric_limits<CPPAD_OP_CODE_TYPE>::max()
223                );
224                first = false;
225        }
226        // do this check every time
227        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
228# endif
229
230        return NumArgTable[(size_t) op];
231}
232
233/*!
234Number of variables resulting from the corresponding operation.
235
236The i-th element in this table specifes the number of varibles for each
237occurance of the operator that is the i-th value in the OpCode enum type.
238For example, for the first three OpCode enum values we have
239\verbatim
240OpCode   j   NumResTable[j]  Meaning
241AbsOp    0                1  variable that is the result of the absolute value
242AcosOp   1                2  acos(x) and sqrt(1-x*x) are required for this op
243AddpvOp  1                1  variable that is the result of the addition
244\endverbatim
245*/
246// alphabetical order (ignoring the Op at the end)
247const size_t NumResTable[] = {
248        1, // AbsOp
249        2, // AcosOp
250        1, // AddpvOp
251        1, // AddvvOp
252        2, // AsinOp
253        2, // AtanOp
254        1, // BeginOp  offsets first variable to have index one (not zero)
255        1, // CExpOp
256        0, // ComOp
257        2, // CosOp
258        2, // CoshOp
259        0, // CSkipOp
260        1, // CSumOp
261        1, // DisOp
262        1, // DivpvOp
263        1, // DivvpOp
264        1, // DivvvOp
265        0, // EndOp
266        1, // ExpOp
267        1, // InvOp
268        1, // LdpOp
269        1, // LdvOp
270        1, // LogOp
271        1, // MulpvOp
272        1, // MulvvOp
273        1, // ParOp
274        3, // PowpvOp
275        3, // PowvpOp
276        3, // PowvvOp
277        0, // PriOp
278        1, // SignOp
279        2, // SinOp
280        2, // SinhOp
281        1, // SqrtOp
282        0, // StppOp
283        0, // StpvOp
284        0, // StvpOp
285        0, // StvvOp
286        1, // SubpvOp
287        1, // SubvpOp
288        1, // SubvvOp
289        2, // TanOp
290        2, // TanhOp
291        0, // UserOp
292        0, // UsrapOp
293        0, // UsravOp
294        0, // UsrrpOp
295        1, // UsrrvOp
296        0  // Last entry not used: avoids warning by g++ 4.3.2 when pycppad builds
297};
298
299/*!
300Fetch the number of variables resulting from the specified operation.
301
302\return
303number of variables resulting from the specified operator.
304
305\param op
306Operator for which we are fetching the number of result variables.
307*/
308inline size_t NumRes(OpCode op)
309{       // check ensuring conversion to size_t is as expected
310        CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) == 
311                sizeof(NumResTable) / sizeof(NumResTable[0]) - 1
312        );
313        // this test ensures that all indices are within the table
314        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
315
316        return NumResTable[(size_t) op];
317}
318
319/*!
320Prints a single field corresponding to an operator.
321
322A specified leader is printed in front of the value
323and then the value is left justified in the following width character.
324
325\tparam Type
326is the type of the value we are printing.
327
328\param os
329is the stream that we are printing to.
330
331\param leader
332are characters printed before the value.
333
334\param value
335is the value being printed.
336
337\param width
338is the number of character to print the value in.
339If the value does not fit in the width, the value is replace
340by width '*' characters.
341*/
342template <class Type>
343void printOpField(
344        std::ostream      &os , 
345        const char *   leader ,
346        const Type     &value , 
347        size_t          width )
348{
349        std::ostringstream buffer;
350        std::string        str;
351
352        // first print the leader
353        os << leader;
354
355        // print the value into an internal buffer
356        buffer << std::setw(width) << value;
357        str = buffer.str();
358
359        // length of the string
360        size_t len = str.size();
361        if( len > width )
362        {       size_t i;
363                for(i = 0; i < width-1; i++)
364                        os << str[i];
365                os << "*";
366                return;
367        }
368
369        // count number of spaces at begining
370        size_t nspace = 0; 
371        while(str[nspace] == ' ' && nspace < len)
372                nspace++;
373
374        // left justify the string
375        size_t i = nspace;
376        while( i < len )
377                os << str[i++];
378
379        i = width - len + nspace;
380        while(i--)
381                os << " "; 
382}
383
384/*!
385Prints a single operator, its operands, and the corresponding result values.
386
387\tparam Base
388Is the base type for these AD< \a Base > operations.
389
390\tparam Value
391Determines the type of the values that we are printing.
392
393\param os
394is the output stream that the information is printed on.
395
396\param Rec
397Is the entire recording for the tape that this operator is in.
398
399\param i_var
400is the index for the variable corresponding to the result of this operation
401(ignored if NumRes(op) == 0).
402
403\param op
404The operator code (OpCode) for this operation.
405
406\param ind
407is the vector of argument indices for this operation
408(must have NumArg(op) elements).
409
410\param nfz
411is the number of forward sweep calculated values of type Value
412that correspond to this operation
413(ignored if NumRes(op) == 0).
414
415\param fz
416points to the first forward calculated value
417that correspond to this operation
418(ignored if NumRes(op) == 0).
419
420\param nrz
421is the number of reverse sweep calculated values of type Value
422that correspond to this operation
423(ignored if NumRes(op) == 0).
424
425\param rz
426points to the first reverse calculated value
427that correspond to this operation
428(ignored if NumRes(op) == 0).
429
430\par 2DO
431print the operator index (in addition to the variables index).
432*/
433template <class Base, class Value>
434void printOp(
435        std::ostream          &os     , 
436        const player<Base>   *Rec     ,
437        size_t                 i_var  , 
438        OpCode                 op     ,
439        const addr_t          *ind    ,
440        size_t                 nfz    ,
441        const  Value          *fz     ,
442        size_t                 nrz    ,
443        const  Value          *rz     )
444{       size_t i;
445       
446        CPPAD_ASSERT_KNOWN(
447                ! thread_alloc::in_parallel() ,
448                "cannot print trace of AD operations in parallel mode"
449        );
450        static const char *CompareOpName[] = 
451                { "Lt", "Le", "Eq", "Ge", "Gt", "Ne" };
452        static const char *OpName[] = {
453                "Abs"   ,
454                "Acos"  ,
455                "Addpv" ,
456                "Addvv" ,
457                "Asin"  ,
458                "Atan"  ,
459                "Begin" ,
460                "CExp"  ,
461                "Com"   ,
462                "Cos"   ,
463                "Cosh"  ,
464                "CSkip" ,
465                "CSum"  ,
466                "Dis"   ,
467                "Divpv" ,
468                "Divvp" ,
469                "Divvv" ,
470                "End"   ,
471                "Exp"   ,
472                "Inv"   ,
473                "Ldp"   ,
474                "Ldv"   ,
475                "Log"   ,
476                "Mulpv" ,
477                "Mulvv" ,
478                "Par"   ,
479                "Powpv" ,
480                "Powvp" ,
481                "Powvv" ,
482                "Pri"   ,
483                "Sign"  ,
484                "Sin"   ,
485                "Sinh"  ,
486                "Sqrt"  ,
487                "Stpp"  ,
488                "Stpv"  ,
489                "Stvp"  ,
490                "Stvv"  ,
491                "Subpv" ,
492                "Subvp" ,
493                "Subvv" ,
494                "Tan"   ,
495                "Tanh"  ,
496                "User"  ,
497                "Usrap" ,
498                "Usrav" ,
499                "Usrrp" ,
500                "Usrrv"
501        };
502        CPPAD_ASSERT_UNKNOWN( 
503                size_t(NumberOp) == sizeof(OpName) / sizeof(OpName[0])
504        );
505
506        // print operator
507        printOpField(os,  "i=",      i_var, 5);
508        if( op == CExpOp )
509        {       printOpField(os, "op=", OpName[op], 4); 
510                printOpField(os, "", CompareOpName[ ind[0] ], 3);
511        }
512        else if( op == CSkipOp )
513        {       printOpField(os, "op=", OpName[op], 5); 
514                printOpField(os, "", CompareOpName[ ind[0] ], 3);
515        }
516        else if( op == ComOp )
517        {       printOpField(os, "op=", OpName[op], 3); 
518                printOpField(os, "", CompareOpName[ ind[0] ], 4);
519        }
520        else    printOpField(os, "op=", OpName[op], 7); 
521
522        // print other fields
523        size_t ncol = 5;
524        switch( op )
525        {
526                case CSkipOp:
527                /*
528                ind[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
529                ind[1] & 1 = is left a variable
530                ind[1] & 2 = is right a variable
531                ind[2]     = index correspoding to left
532                ind[3]     = index correspoding to right
533                ind[4] = number of operations to skip if CExpOp comparision is true
534                ind[5] = number of operations to skip if CExpOp comparision is false
535                ind[6] -> ind[5+ind[4]]               = skip operations if true
536                ind[6+ind[4]] -> ind[5+ind[4]+ind[5]] = skip operations if false
537                ind[6+ind[4]+ind[5]] = ind[4] + ind[5]
538                */
539                CPPAD_ASSERT_UNKNOWN( ind[6+ind[4]+ind[5]] == ind[4]+ind[5] );
540                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
541                if( ind[1] & 1 )
542                        printOpField(os, " vl=", ind[2], ncol);
543                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
544                if( ind[1] & 2 )
545                        printOpField(os, " vr=", ind[3], ncol);
546                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
547                for(i = 0; i < size_t(ind[4]); i++)
548                         printOpField(os, " st=", ind[6+i], ncol);
549                for(i = 0; i < size_t(ind[5]); i++)
550                         printOpField(os, " sf=", ind[6+ind[4]+i], ncol);
551                break;
552
553                case CSumOp:
554                /*
555                ind[0] = number of addition variables in summation
556                ind[1] = number of subtraction variables in summation
557                ind[2] = index of parameter that initializes summation
558                ind[3], ... , ind[2+ind[0]] = index for positive variables
559                ind[3+ind[0]], ..., ind[2+ind[0]+ind[1]] = negative variables
560                ind[3+ind[0]+ind[1]] == ind[0] + ind[1]
561                */
562                CPPAD_ASSERT_UNKNOWN( ind[3+ind[0]+ind[1]] == ind[0]+ind[1] );
563                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
564                for(i = 0; i < size_t(ind[0]); i++)
565                         printOpField(os, " +v=", ind[3+i], ncol);
566                for(i = 0; i < size_t(ind[1]); i++)
567                         printOpField(os, " -v=", ind[3+ind[0]+i], ncol);
568                break;
569
570                case LdpOp:
571                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
572                printOpField(os, "off=", ind[0], ncol);
573                printOpField(os, "idx=", ind[1], ncol);
574                break;
575
576                case LdvOp:
577                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
578                printOpField(os, "off=", ind[0], ncol);
579                printOpField(os, "  v=", ind[1], ncol);
580                break;
581
582                case StppOp:
583                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
584                printOpField(os, "off=", ind[0], ncol);
585                printOpField(os, "idx=", ind[1], ncol);
586                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
587                break;
588
589                case StpvOp:
590                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
591                printOpField(os, "off=", ind[0], ncol);
592                printOpField(os, "idx=", ind[1], ncol);
593                printOpField(os, " vr=", ind[2], ncol);
594                break;
595
596                case StvpOp:
597                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
598                printOpField(os, "off=", ind[0], ncol);
599                printOpField(os, " vl=", ind[1], ncol);
600                printOpField(os, " pr=", Rec->GetPar(ind[2]), ncol);
601                break;
602
603                case StvvOp:
604                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
605                printOpField(os, "off=", ind[0], ncol);
606                printOpField(os, " vl=", ind[1], ncol);
607                printOpField(os, " vr=", ind[2], ncol);
608                break;
609
610                case AddvvOp:
611                case DivvvOp:
612                case MulvvOp:
613                case PowvvOp:
614                case SubvvOp:
615                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
616                printOpField(os, " vl=", ind[0], ncol);
617                printOpField(os, " vr=", ind[1], ncol);
618                break;
619
620                case AddpvOp:
621                case SubpvOp:
622                case MulpvOp:
623                case PowpvOp:
624                case DivpvOp:
625                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
626                printOpField(os, " pl=", Rec->GetPar(ind[0]), ncol);
627                printOpField(os, " vr=", ind[1], ncol);
628                break;
629
630                case DivvpOp:
631                case PowvpOp:
632                case SubvpOp:
633                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
634                printOpField(os, " vl=", ind[0], ncol);
635                printOpField(os, " pr=", Rec->GetPar(ind[1]), ncol);
636                break;
637
638                case AbsOp:
639                case AcosOp:
640                case AsinOp:
641                case AtanOp:
642                case CosOp:
643                case CoshOp:
644                case ExpOp:
645                case LogOp:
646                case SignOp:
647                case SinOp:
648                case SinhOp:
649                case SqrtOp:
650                case UsravOp:
651                case TanOp:
652                case TanhOp:
653                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
654                printOpField(os, "  v=", ind[0], ncol);
655                break;
656
657                case ParOp:
658                case UsrapOp:
659                case UsrrpOp:
660                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
661                printOpField(os, "  p=", Rec->GetPar(ind[0]), ncol);
662                break;
663
664                case UserOp:
665                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
666                {       std::string name =  atomic_base<Base>::class_name(ind[0]);
667                        printOpField(os, " f=",   name.c_str(), ncol);
668                        printOpField(os, " i=", ind[1], ncol);
669                        printOpField(os, " n=", ind[2], ncol);
670                        printOpField(os, " m=", ind[3], ncol);
671                }
672                break;
673
674                case PriOp:
675                CPPAD_ASSERT_NARG_NRES(op, 5, 0);
676                if( ind[0] & 1 )
677                        printOpField(os, " v=", ind[1], ncol);
678                else    printOpField(os, " p=", Rec->GetPar(ind[1]), ncol);
679                os << "before=\"" << Rec->GetTxt(ind[2]) << "\"";
680                if( ind[0] & 2 )
681                        printOpField(os, " v=", ind[3], ncol);
682                else    printOpField(os, " p=", Rec->GetPar(ind[3]), ncol);
683                os << "after=\"" << Rec->GetTxt(ind[4]) << "\"";
684                break;
685
686                case BeginOp:
687                case EndOp:
688                case InvOp:
689                case UsrrvOp:
690                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );
691                break;
692
693                case DisOp:
694                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
695                {       const char* name = discrete<Base>::name(ind[0]);
696                        printOpField(os, " f=", name, ncol);
697                        printOpField(os, " x=", ind[1], ncol);
698                }
699                break;
700       
701
702                case CExpOp:
703                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
704                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );
705                if( ind[1] & 1 )
706                        printOpField(os, " vl=", ind[2], ncol);
707                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
708                if( ind[1] & 2 )
709                        printOpField(os, " vr=", ind[3], ncol);
710                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
711                if( ind[1] & 4 )
712                        printOpField(os, " vt=", ind[4], ncol);
713                else    printOpField(os, " pt=", Rec->GetPar(ind[4]), ncol);
714                if( ind[1] & 8 )
715                        printOpField(os, " vf=", ind[5], ncol);
716                else    printOpField(os, " pf=", Rec->GetPar(ind[5]), ncol);
717                break;
718
719                case ComOp:
720                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
721                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
722                if( ind[1] & 1 )
723                        printOpField(os, "res=", 1, ncol);
724                else    printOpField(os, "res=", 0, ncol);
725                if( ind[1] & 2 )
726                        printOpField(os, " vl=", ind[2], ncol);
727                else    printOpField(os, " pl=", Rec->GetPar(ind[2]), ncol);
728                if( ind[1] & 4 )
729                        printOpField(os, " vr=", ind[3], ncol);
730                else    printOpField(os, " pr=", Rec->GetPar(ind[3]), ncol);
731                break;
732
733                default:
734                CPPAD_ASSERT_UNKNOWN(0);
735        }
736        size_t k;
737        if( NumRes(op) > 0 && (op != BeginOp) )
738        { 
739                for(k = 0; k < nfz; k++)
740                        std::cout << "| fz[" << k << "]=" << fz[k];
741                for(k = 0; k < nrz; k++)
742                        std::cout << "| rz[" << k << "]=" << rz[k];
743        }
744        std::cout << std::endl;
745}
746
747/*! \} */
748} // END_CPPAD_NAMESPACE
749# endif
Note: See TracBrowser for help on using the repository browser.