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

Last change on this file since 3675 was 3675, checked in by bradbell, 5 years ago

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: d54457d7204aae2cedec24a81bc6a97b1ec67d89
end hash code: bf9459823c22b7b496d632ebde31ca166a1cc81b

commit bf9459823c22b7b496d632ebde31ca166a1cc81b
Author: Brad Bell <bradbell@…>
Date: Tue May 5 06:53:28 2015 -0700

New doxygen requires GENERATE_HTML (default has changed from YES to NO).


doxyfile.sh: set GENERATE_HTML to YES.
cskip_op.hpp: fix error in doxygen command, remove trailing white space.

commit 158a03f245d13ec00b5474a428645f6712c9ea9f
Author: Brad Bell <bradbell@…>
Date: Tue May 5 06:09:24 2015 -0700

Remove trailing white space.

commit d501584454b6d99e639fafcaeead55f0158965f6
Author: Brad Bell <bradbell@…>
Date: Tue May 5 06:04:14 2015 -0700

  1. Add the inverse hyperbolic sine function asinh.
  2. Change the asin test name from Asin to asin.


base_require.hpp: remove spelling commands that are no longer used.
remove include: remove include commands that are no longer needed.
asin.cpp: use machine epsilon to gauge accuracy of this test result.

  • Property svn:keywords set to Id
File size: 25.8 KB
Line 
1/* $Id: op_code.hpp 3675 2015-05-05 14:26:18Z bradbell $ */
2# ifndef CPPAD_OP_CODE_INCLUDED
3# define CPPAD_OP_CODE_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 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        AsinhOp,  // asinh(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        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        EqpvOp,   //  parameter  == variable
94        EqvvOp,   //  variable   == variable
95        ErfOp,    //  erf(variable)
96        ExpOp,    //  exp(variable)
97        InvOp,    //                             independent variable
98        LdpOp,    //    z[parameter]
99        LdvOp,    //    z[variable]
100        LepvOp,   //  parameter <= variable
101        LevpOp,   //  variable  <= parameter
102        LevvOp,   //  variable  <= variable
103        LogOp,    //  log(variable)
104        LtpvOp,   //  parameter < variable
105        LtvpOp,   //  variable  < parameter
106        LtvvOp,   //  variable  < variable
107        MulpvOp,  //      parameter  * variable
108        MulvvOp,  //      variable   * variable
109        NepvOp,   //  parameter  != variable
110        NevvOp,   //  variable   != variable
111        ParOp,    //      parameter
112        PowpvOp,  //  pow(parameter,   variable)
113        PowvpOp,  //  pow(variable,    parameter)
114        PowvvOp,  //  pow(variable,    variable)
115        PriOp,    //  PrintFor(text, parameter or variable, parameter or variable)
116        SignOp,   // sign(variable)
117        SinOp,    //  sin(variable)
118        SinhOp,   // sinh(variable)
119        SqrtOp,   // sqrt(variable)
120        StppOp,   //    z[parameter] = parameter
121        StpvOp,   //    z[parameter] = variable
122        StvpOp,   //    z[variable]  = parameter
123        StvvOp,   //    z[variable]  = variable
124        SubpvOp,  //      parameter  - variable
125        SubvpOp,  //      variable   - parameter
126        SubvvOp,  //      variable   - variable
127        TanOp,    //  tan(variable)
128        TanhOp,   //  tan(variable)
129        // user atomic operation codes
130        UserOp,   //  start of a user atomic operaiton
131        // arg[0] = index of the operation if atomic_base<Base> class
132        // arg[1] = extra information passed trough by deprecated old atomic class
133        // arg[2] = number of arguments to this atomic function
134        // arg[3] = number of results for this atomic function
135        UsrapOp,  //  this user atomic argument is a parameter
136        UsravOp,  //  this user atomic argument is a variable
137        UsrrpOp,  //  this user atomic result is a parameter
138        UsrrvOp,  //  this user atomic result is a variable
139        NumberOp
140};
141// Note that bin/check_op_code.sh assumes the pattern '^\tNumberOp$' occurs
142// at the end of this list and only at the end of this list.
143
144/*!
145Number of arguments for a specified operator.
146
147\return
148Number of arguments corresponding to the specified operator.
149
150\param op
151Operator for which we are fetching the number of arugments.
152
153\par NumArgTable
154this table specifes the number of arguments stored for each
155occurance of the operator that is the i-th value in the OpCode enum type.
156For example, for the first three OpCode enum values we have
157\verbatim
158OpCode   j   NumArgTable[j]  Meaning
159AbsOp    0                1  index of variable we are taking absolute value of
160AcosOp   1                1  index of variable we are taking cosine of
161AddpvOp  1                2  indices of parameter and variable we are adding
162\endverbatim
163Note that the meaning of the arguments depends on the operator.
164*/
165inline size_t NumArg( OpCode op)
166{       CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
167
168        // agreement with OpCode is checked by bin/check_op_code.sh
169        static const size_t NumArgTable[] = {
170                1, // AbsOp
171                1, // AcosOp
172                2, // AddpvOp
173                2, // AddvvOp
174                1, // AsinOp
175                1, // AsinhOp
176                1, // AtanOp
177                1, // BeginOp  offset first real argument to have index 1
178                6, // CExpOp
179                1, // CosOp
180                1, // CoshOp
181                0, // CSkipOp  (actually has a variable number of arguments, not zero)
182                0, // CSumOp   (actually has a variable number of arguments, not zero)
183                2, // DisOp
184                2, // DivpvOp
185                2, // DivvpOp
186                2, // DivvvOp
187                0, // EndOp
188                2, // EqpvOp
189                2, // EqvvOp
190                3, // ErfOp
191                1, // ExpOp
192                0, // InvOp
193                3, // LdpOp
194                3, // LdvOp
195                2, // LepvOp
196                2, // LevpOp
197                2, // LevvOp
198                1, // LogOp
199                2, // LtpvOp
200                2, // LtvpOp
201                2, // LtvvOp
202                2, // MulpvOp
203                2, // MulvvOp
204                2, // NepvOp
205                2, // NevvOp
206                1, // ParOp
207                2, // PowpvOp
208                2, // PowvpOp
209                2, // PowvvOp
210                5, // PriOp
211                1, // SignOp
212                1, // SinOp
213                1, // SinhOp
214                1, // SqrtOp
215                3, // StppOp
216                3, // StpvOp
217                3, // StvpOp
218                3, // StvvOp
219                2, // SubpvOp
220                2, // SubvpOp
221                2, // SubvvOp
222                1, // TanOp
223                1, // TanhOp
224                4, // UserOp
225                1, // UsrapOp
226                1, // UsravOp
227                1, // UsrrpOp
228                0  // UsrrvOp
229        };
230# ifndef NDEBUG
231        // only do these checks once to save time
232        static bool first = true;
233        if( first )
234        {       CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) ==
235                        sizeof(NumArgTable) / sizeof(NumArgTable[0])
236                );
237                CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) <=
238                        std::numeric_limits<CPPAD_OP_CODE_TYPE>::max()
239                );
240                first = false;
241        }
242        // do this check every time
243        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
244# endif
245
246        return NumArgTable[op];
247}
248
249/*!
250Number of variables resulting from the specified operation.
251
252\param op
253Operator for which we are fecching the number of results.
254
255\par NumResTable
256table specifes the number of varibles that result for each
257occurance of the operator that is the i-th value in the OpCode enum type.
258For example, for the first three OpCode enum values we have
259\verbatim
260OpCode   j   NumResTable[j]  Meaning
261AbsOp    0                1  variable that is the result of the absolute value
262AcosOp   1                2  acos(x) and sqrt(1-x*x) are required for this op
263AddpvOp  1                1  variable that is the result of the addition
264\endverbatim
265*/
266inline size_t NumRes(OpCode op)
267{       CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL;
268
269        // agreement with OpCode is checked by bin/check_op_code.sh
270        static const size_t NumResTable[] = {
271                1, // AbsOp
272                2, // AcosOp
273                1, // AddpvOp
274                1, // AddvvOp
275                2, // AsinOp
276                2, // AsinhOp
277                2, // AtanOp
278                1, // BeginOp  offsets first variable to have index one (not zero)
279                1, // CExpOp
280                2, // CosOp
281                2, // CoshOp
282                0, // CSkipOp
283                1, // CSumOp
284                1, // DisOp
285                1, // DivpvOp
286                1, // DivvpOp
287                1, // DivvvOp
288                0, // EndOp
289                0, // EqpvOp
290                0, // EqvvOp
291                5, // ErfOp
292                1, // ExpOp
293                1, // InvOp
294                1, // LdpOp
295                1, // LdvOp
296                0, // LepvOp
297                0, // LevpOp
298                0, // LevvOp
299                1, // LogOp
300                0, // LtpvOp
301                0, // LtvpOp
302                0, // LtvvOp
303                1, // MulpvOp
304                1, // MulvvOp
305                0, // NepvOp
306                0, // NevvOp
307                1, // ParOp
308                3, // PowpvOp
309                3, // PowvpOp
310                3, // PowvvOp
311                0, // PriOp
312                1, // SignOp
313                2, // SinOp
314                2, // SinhOp
315                1, // SqrtOp
316                0, // StppOp
317                0, // StpvOp
318                0, // StvpOp
319                0, // StvvOp
320                1, // SubpvOp
321                1, // SubvpOp
322                1, // SubvvOp
323                2, // TanOp
324                2, // TanhOp
325                0, // UserOp
326                0, // UsrapOp
327                0, // UsravOp
328                0, // UsrrpOp
329                1, // UsrrvOp
330                0  // Last entry not used: avoids g++ 4.3.2 warn when pycppad builds
331        };
332        // check ensuring conversion to size_t is as expected
333        CPPAD_ASSERT_UNKNOWN( size_t(NumberOp) ==
334                sizeof(NumResTable) / sizeof(NumResTable[0]) - 1
335        );
336        // this test ensures that all indices are within the table
337        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
338
339        return NumResTable[op];
340}
341
342
343/*!
344Fetch the name for a specified operation.
345
346\return
347name of the specified operation.
348
349\param op
350Operator for which we are fetching the name
351*/
352inline const char* OpName(OpCode op)
353{       // agreement with OpCode is checked by bin/check_op_code.sh
354        static const char *OpNameTable[] = {
355                "Abs"   ,
356                "Acos"  ,
357                "Addpv" ,
358                "Addvv" ,
359                "Asin"  ,
360                "Asinh"  ,
361                "Atan"  ,
362                "Begin" ,
363                "CExp"  ,
364                "Cos"   ,
365                "Cosh"  ,
366                "CSkip" ,
367                "CSum"  ,
368                "Dis"   ,
369                "Divpv" ,
370                "Divvp" ,
371                "Divvv" ,
372                "End"   ,
373                "Eqpv"  ,
374                "Eqvv"  ,
375                "Erf"   ,
376                "Exp"   ,
377                "Inv"   ,
378                "Ldp"   ,
379                "Ldv"   ,
380                "Lepv"  ,
381                "Levp"  ,
382                "Levv"  ,
383                "Log"   ,
384                "Ltpv"  ,
385                "Ltvp"  ,
386                "Ltvv"  ,
387                "Mulpv" ,
388                "Mulvv" ,
389                "Nepv"  ,
390                "Nevv"  ,
391                "Par"   ,
392                "Powpv" ,
393                "Powvp" ,
394                "Powvv" ,
395                "Pri"   ,
396                "Sign"  ,
397                "Sin"   ,
398                "Sinh"  ,
399                "Sqrt"  ,
400                "Stpp"  ,
401                "Stpv"  ,
402                "Stvp"  ,
403                "Stvv"  ,
404                "Subpv" ,
405                "Subvp" ,
406                "Subvv" ,
407                "Tan"   ,
408                "Tanh"  ,
409                "User"  ,
410                "Usrap" ,
411                "Usrav" ,
412                "Usrrp" ,
413                "Usrrv"
414        };
415        // check ensuring conversion to size_t is as expected
416        CPPAD_ASSERT_UNKNOWN(
417                size_t(NumberOp) == sizeof(OpNameTable)/sizeof(OpNameTable[0])
418        );
419        // this test ensures that all indices are within the table
420        CPPAD_ASSERT_UNKNOWN( size_t(op) < size_t(NumberOp) );
421
422        return OpNameTable[op];
423}
424
425/*!
426Prints a single field corresponding to an operator.
427
428A specified leader is printed in front of the value
429and then the value is left justified in the following width character.
430
431\tparam Type
432is the type of the value we are printing.
433
434\param os
435is the stream that we are printing to.
436
437\param leader
438are characters printed before the value.
439
440\param value
441is the value being printed.
442
443\param width
444is the number of character to print the value in.
445If the value does not fit in the width, the value is replace
446by width '*' characters.
447*/
448template <class Type>
449void printOpField(
450        std::ostream      &os ,
451        const char *   leader ,
452        const Type     &value ,
453        size_t          width )
454{
455        std::ostringstream buffer;
456        std::string        str;
457
458        // first print the leader
459        os << leader;
460
461        // print the value into an internal buffer
462        buffer << std::setw(width) << value;
463        str = buffer.str();
464
465        // length of the string
466        size_t len = str.size();
467        if( len > width )
468        {       size_t i;
469                for(i = 0; i < width-1; i++)
470                        os << str[i];
471                os << "*";
472                return;
473        }
474
475        // count number of spaces at begining
476        size_t nspace = 0;
477        while(str[nspace] == ' ' && nspace < len)
478                nspace++;
479
480        // left justify the string
481        size_t i = nspace;
482        while( i < len )
483                os << str[i++];
484
485        i = width - len + nspace;
486        while(i--)
487                os << " ";
488}
489
490/*!
491Prints a single operator and its operands
492
493\tparam Base
494Is the base type for these AD< \a Base > operations.
495
496\param os
497is the output stream that the information is printed on.
498
499\param play
500Is the entire recording for the tape that this operator is in.
501
502\param i_op
503is the index for the operator corresponding to this operation.
504
505\param i_var
506is the index for the variable corresponding to the result of this operation
507(if NumRes(op) > 0).
508
509\param op
510The operator code (OpCode) for this operation.
511
512\param ind
513is the vector of argument indices for this operation
514(must have NumArg(op) elements).
515*/
516template <class Base>
517void printOp(
518        std::ostream&          os     ,
519        const player<Base>*    play   ,
520        size_t                 i_op   ,
521        size_t                 i_var  ,
522        OpCode                 op     ,
523        const addr_t*          ind    )
524{       size_t i;
525        CPPAD_ASSERT_KNOWN(
526                ! thread_alloc::in_parallel() ,
527                "cannot print trace of AD operations in parallel mode"
528        );
529        static const char *CompareOpName[] =
530                { "Lt", "Le", "Eq", "Ge", "Gt", "Ne" };
531
532        // print operator
533        printOpField(os,  "o=",      i_op,  5);
534        if( NumRes(op) > 0 && op != BeginOp )
535                printOpField(os,  "v=",      i_var, 5);
536        else    printOpField(os,  "v=",      "",    5);
537        if( op == CExpOp || op == CSkipOp )
538        {       printOpField(os, "", OpName(op), 5);
539                printOpField(os, "", CompareOpName[ ind[0] ], 3);
540        }
541        else    printOpField(os, "", OpName(op), 8);
542
543        // print other fields
544        size_t ncol = 5;
545        switch( op )
546        {
547                case CSkipOp:
548                /*
549                ind[0]     = the Rel operator: Lt, Le, Eq, Ge, Gt, or Ne
550                ind[1] & 1 = is left a variable
551                ind[1] & 2 = is right a variable
552                ind[2]     = index correspoding to left
553                ind[3]     = index correspoding to right
554                ind[4] = number of operations to skip if CExpOp comparision is true
555                ind[5] = number of operations to skip if CExpOp comparision is false
556                ind[6] -> ind[5+ind[4]]               = skip operations if true
557                ind[6+ind[4]] -> ind[5+ind[4]+ind[5]] = skip operations if false
558                ind[6+ind[4]+ind[5]] = ind[4] + ind[5]
559                */
560                CPPAD_ASSERT_UNKNOWN( ind[6+ind[4]+ind[5]] == ind[4]+ind[5] );
561                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
562                if( ind[1] & 1 )
563                        printOpField(os, " vl=", ind[2], ncol);
564                else    printOpField(os, " pl=", play->GetPar(ind[2]), ncol);
565                if( ind[1] & 2 )
566                        printOpField(os, " vr=", ind[3], ncol);
567                else    printOpField(os, " pr=", play->GetPar(ind[3]), ncol);
568                if( size_t(ind[4]) < 3 )
569                {       for(i = 0; i < size_t(ind[4]); i++)
570                                printOpField(os, " ot=", ind[6+i], ncol);
571                }
572                else
573                {       printOpField(os, "\n\tot=", ind[6+0], ncol);
574                        for(i = 1; i < size_t(ind[4]); i++)
575                                printOpField(os, " ot=", ind[6+i], ncol);
576                }
577                if( size_t(ind[5]) < 3 )
578                {       for(i = 0; i < size_t(ind[5]); i++)
579                                printOpField(os, " of=", ind[6+ind[4]+i], ncol);
580                }
581                else
582                {       printOpField(os, "\n\tof=", ind[6+ind[4]+0], ncol);
583                        {       for(i = 1; i < size_t(ind[5]); i++)
584                                        printOpField(os, " of=", ind[6+ind[4]+i], ncol);
585                        }
586                }
587                break;
588
589                case CSumOp:
590                /*
591                ind[0] = number of addition variables in summation
592                ind[1] = number of subtraction variables in summation
593                ind[2] = index of parameter that initializes summation
594                ind[3], ... , ind[2+ind[0]] = index for positive variables
595                ind[3+ind[0]], ..., ind[2+ind[0]+ind[1]] = negative variables
596                ind[3+ind[0]+ind[1]] == ind[0] + ind[1]
597                */
598                CPPAD_ASSERT_UNKNOWN( ind[3+ind[0]+ind[1]] == ind[0]+ind[1] );
599                printOpField(os, " pr=", play->GetPar(ind[2]), ncol);
600                for(i = 0; i < size_t(ind[0]); i++)
601                         printOpField(os, " +v=", ind[3+i], ncol);
602                for(i = 0; i < size_t(ind[1]); i++)
603                         printOpField(os, " -v=", ind[3+ind[0]+i], ncol);
604                break;
605
606                case LdpOp:
607                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
608                printOpField(os, "off=", ind[0], ncol);
609                printOpField(os, "idx=", ind[1], ncol);
610                break;
611
612                case LdvOp:
613                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
614                printOpField(os, "off=", ind[0], ncol);
615                printOpField(os, "  v=", ind[1], ncol);
616                break;
617
618                case StppOp:
619                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
620                printOpField(os, "off=", ind[0], ncol);
621                printOpField(os, "idx=", ind[1], ncol);
622                printOpField(os, " pr=", play->GetPar(ind[2]), ncol);
623                break;
624
625                case StpvOp:
626                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
627                printOpField(os, "off=", ind[0], ncol);
628                printOpField(os, "idx=", ind[1], ncol);
629                printOpField(os, " vr=", ind[2], ncol);
630                break;
631
632                case StvpOp:
633                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
634                printOpField(os, "off=", ind[0], ncol);
635                printOpField(os, " vl=", ind[1], ncol);
636                printOpField(os, " pr=", play->GetPar(ind[2]), ncol);
637                break;
638
639                case StvvOp:
640                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
641                printOpField(os, "off=", ind[0], ncol);
642                printOpField(os, " vl=", ind[1], ncol);
643                printOpField(os, " vr=", ind[2], ncol);
644                break;
645
646                case AddvvOp:
647                case DivvvOp:
648                case LevvOp:
649                case LtvvOp:
650                case EqvvOp:
651                case NevvOp:
652                case MulvvOp:
653                case PowvvOp:
654                case SubvvOp:
655                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
656                printOpField(os, " vl=", ind[0], ncol);
657                printOpField(os, " vr=", ind[1], ncol);
658                break;
659
660                case AddpvOp:
661                case LepvOp:
662                case LtpvOp:
663                case EqpvOp:
664                case NepvOp:
665                case SubpvOp:
666                case MulpvOp:
667                case PowpvOp:
668                case DivpvOp:
669                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
670                printOpField(os, " pl=", play->GetPar(ind[0]), ncol);
671                printOpField(os, " vr=", ind[1], ncol);
672                break;
673
674                case DivvpOp:
675                case LevpOp:
676                case LtvpOp:
677                case PowvpOp:
678                case SubvpOp:
679                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
680                printOpField(os, " vl=", ind[0], ncol);
681                printOpField(os, " pr=", play->GetPar(ind[1]), ncol);
682                break;
683
684                case AbsOp:
685                case AcosOp:
686                case AsinOp:
687                case AsinhOp:
688                case AtanOp:
689                case CosOp:
690                case CoshOp:
691                case ExpOp:
692                case LogOp:
693                case SignOp:
694                case SinOp:
695                case SinhOp:
696                case SqrtOp:
697                case UsravOp:
698                case TanOp:
699                case TanhOp:
700                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
701                printOpField(os, "  v=", ind[0], ncol);
702                break;
703
704                case ErfOp:
705                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
706                // ind[1] points to the parameter 0
707                // ind[2] points to the parameter 2 / sqrt(pi)
708                printOpField(os, "  v=", ind[0], ncol);
709                break;
710
711                case ParOp:
712                case UsrapOp:
713                case UsrrpOp:
714                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
715                printOpField(os, "  p=", play->GetPar(ind[0]), ncol);
716                break;
717
718                case UserOp:
719                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 4 );
720                {       std::string name =  atomic_base<Base>::class_name(ind[0]);
721                        printOpField(os, " f=",   name.c_str(), ncol);
722                        printOpField(os, " i=", ind[1], ncol);
723                        printOpField(os, " n=", ind[2], ncol);
724                        printOpField(os, " m=", ind[3], ncol);
725                }
726                break;
727
728                case PriOp:
729                CPPAD_ASSERT_NARG_NRES(op, 5, 0);
730                if( ind[0] & 1 )
731                        printOpField(os, " v=", ind[1], ncol);
732                else    printOpField(os, " p=", play->GetPar(ind[1]), ncol);
733                os << "before=\"" << play->GetTxt(ind[2]) << "\"";
734                if( ind[0] & 2 )
735                        printOpField(os, " v=", ind[3], ncol);
736                else    printOpField(os, " p=", play->GetPar(ind[3]), ncol);
737                os << "after=\"" << play->GetTxt(ind[4]) << "\"";
738                break;
739
740                case BeginOp:
741                // argument not used (created by independent)
742                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
743                break;
744
745                case EndOp:
746                case InvOp:
747                case UsrrvOp:
748                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 0 );
749                break;
750
751                case DisOp:
752                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 2 );
753                {       const char* name = discrete<Base>::name(ind[0]);
754                        printOpField(os, " f=", name, ncol);
755                        printOpField(os, " x=", ind[1], ncol);
756                }
757                break;
758
759
760                case CExpOp:
761                CPPAD_ASSERT_UNKNOWN(ind[1] != 0);
762                CPPAD_ASSERT_UNKNOWN( NumArg(op) == 6 );
763                if( ind[1] & 1 )
764                        printOpField(os, " vl=", ind[2], ncol);
765                else    printOpField(os, " pl=", play->GetPar(ind[2]), ncol);
766                if( ind[1] & 2 )
767                        printOpField(os, " vr=", ind[3], ncol);
768                else    printOpField(os, " pr=", play->GetPar(ind[3]), ncol);
769                if( ind[1] & 4 )
770                        printOpField(os, " vt=", ind[4], ncol);
771                else    printOpField(os, " pt=", play->GetPar(ind[4]), ncol);
772                if( ind[1] & 8 )
773                        printOpField(os, " vf=", ind[5], ncol);
774                else    printOpField(os, " pf=", play->GetPar(ind[5]), ncol);
775                break;
776
777                default:
778                CPPAD_ASSERT_UNKNOWN(0);
779        }
780}
781
782/*!
783Prints the result values correspnding to an operator.
784
785\tparam Base
786Is the base type for these AD< \a Base > operations.
787
788\tparam Value
789Determines the type of the values that we are printing.
790
791\param os
792is the output stream that the information is printed on.
793
794\param nfz
795is the number of forward sweep calculated values of type Value
796that correspond to this operation
797(ignored if NumRes(op) == 0).
798
799\param fz
800points to the first forward calculated value
801that correspond to this operation
802(ignored if NumRes(op) == 0).
803
804\param nrz
805is the number of reverse sweep calculated values of type Value
806that correspond to this operation
807(ignored if NumRes(op) == 0).
808
809\param rz
810points to the first reverse calculated value
811that correspond to this operation
812(ignored if NumRes(op) == 0).
813*/
814template <class Value>
815void printOpResult(
816        std::ostream          &os     ,
817        size_t                 nfz    ,
818        const  Value          *fz     ,
819        size_t                 nrz    ,
820        const  Value          *rz     )
821{
822        size_t k;
823        for(k = 0; k < nfz; k++)
824                os << "| fz[" << k << "]=" << fz[k];
825        for(k = 0; k < nrz; k++)
826                os << "| rz[" << k << "]=" << rz[k];
827}
828
829/*!
830If NDEBUG is not defined, assert that arguments come before result.
831
832\param op
833Operator for which we are checking order.
834All the operators are checked except for those of the form UserOp or Usr..Op.
835
836\param result
837is the variable index for the result.
838
839\param arg
840is a vector of lenght NumArg(op) pointing to the arguments
841for this operation.
842*/
843inline void assert_arg_before_result(
844        OpCode op, const addr_t* arg, size_t result
845)
846{
847        switch( op )
848        {
849
850                // These cases are not included below
851                case UserOp:
852                case UsrapOp:
853                case UsravOp:
854                case UsrrpOp:
855                case UsrrvOp:
856                break;
857                // ------------------------------------------------------------------
858
859                // 0 arguments
860                case CSkipOp:
861                case CSumOp:
862                case EndOp:
863                case InvOp:
864                break;
865                // ------------------------------------------------------------------
866
867                // 1 argument, but is not used
868                case BeginOp:
869                break;
870
871                // 1 argument , 1 result
872                case AbsOp:
873                case ExpOp:
874                case LogOp:
875                case ParOp:
876                case SignOp:
877                case SqrtOp:
878                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < result );
879                break;
880
881                // 1 argument, 2 results
882                case AcosOp:
883                case AsinOp:
884                case AsinhOp:
885                case AtanOp:
886                case CosOp:
887                case CoshOp:
888                case SinOp:
889                case SinhOp:
890                case TanOp:
891                case TanhOp:
892                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) + 1 < result );
893                break;
894
895                // 1 argument, 5 results
896                case ErfOp:
897                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) + 4 < result );
898                break;
899                // ------------------------------------------------------------------
900                // 2 arguments, no results
901                case LepvOp:
902                case LtpvOp:
903                case EqpvOp:
904                case NepvOp:
905                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= result );
906                break;
907                //
908                case LevpOp:
909                case LtvpOp:
910                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= result );
911                break;
912                //
913                case LevvOp:
914                case LtvvOp:
915                case EqvvOp:
916                case NevvOp:
917                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= result );
918                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= result );
919                break;
920
921                // 2 arguments (both variables), 1 results
922                case AddvvOp:
923                case DivvvOp:
924                case MulvvOp:
925                case SubvvOp:
926                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < result );
927                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < result );
928                break;
929
930                // 2 arguments (first variables), 1 results
931                case DivvpOp:
932                case SubvpOp:
933                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < result );
934                break;
935
936                // 2 arguments (second variables), 1 results
937                case AddpvOp:
938                case DisOp:
939                case DivpvOp:
940                case MulpvOp:
941                case SubpvOp:
942                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < result );
943                break;
944
945                // 2 arguments (both variables), 3 results
946                case PowvvOp:
947                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) + 2 < result );
948                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) + 2 < result );
949                break;
950
951                // 2 arguments (first variable), 3 results
952                case PowvpOp:
953                CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) + 2 < result );
954                break;
955
956                // 2 arguments (second variable), 3 results
957                case PowpvOp:
958                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) + 2 < result );
959                break;
960                // ------------------------------------------------------------------
961
962                // 3 arguments, none variables
963                case LdpOp:
964                case StppOp:
965                break;
966
967                // 3 arguments, second variable, 1 result
968                case LdvOp:
969                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < result );
970                break;
971
972                // 3 arguments, third variable, no result
973                case StpvOp:
974                CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= result );
975                break;
976
977                // 3 arguments, second variable, no result
978                case StvpOp:
979                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= result );
980                break;
981
982                // 3 arguments, second and third variable, no result
983                case StvvOp:
984                CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= result );
985                CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) <= result );
986                break;
987                // ------------------------------------------------------------------
988
989                // 5 arguments, no result
990                case PriOp:
991                if( arg[0] & 1 )
992                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) <= result );
993                }
994                if( arg[0] & 2 )
995                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) <= result );
996                }
997                break;
998                // ------------------------------------------------------------------
999
1000                // 6 arguments, 1 result
1001                case CExpOp:
1002                if( arg[1] & 1 )
1003                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < result );
1004                }
1005                if( arg[1] & 2 )
1006                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[3]) < result );
1007                }
1008                if( arg[1] & 4 )
1009                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[4]) < result );
1010                }
1011                if( arg[1] & 8 )
1012                {       CPPAD_ASSERT_UNKNOWN( size_t(arg[5]) < result );
1013                }
1014                break;
1015                // ------------------------------------------------------------------
1016
1017                default:
1018                CPPAD_ASSERT_UNKNOWN(false);
1019                break;
1020
1021        }
1022        return;
1023}
1024
1025} // END_CPPAD_NAMESPACE
1026# endif
Note: See TracBrowser for help on using the repository browser.