source: trunk/cppad/local/op_code.hpp @ 3320

Last change on this file since 3320 was 3320, checked in by bradbell, 6 years ago
  1. g++ 4.8.2 has shadow warnings by default, but eigen and fadbad do not

these warnings, so supress then in these cases.

  1. Move check that arguments come before result into on place,

CPPAD_ASSERT_ARG_BEFORE_RESULT (only one argument case so far).

main.cpp: fix shadowing of index variable.
CMakeLists.txt: adapt to change in teuchos library name.
sparse_jacobian.cpp: fix a shadowed variable.
check_svn_id.sh: ignore svn_commit.sh.
gpl_license.sh: ignore svn_commit.sh.

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