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

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

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 071875a4beba3363e5fa9752426aec4762cd1caa
end hash code: 0bef506513a519e1073c6279d5c4cba9e5c3b180

commit 0bef506513a519e1073c6279d5c4cba9e5c3b180
Author: Brad Bell <bradbell@…>
Date: Thu May 7 12:14:32 2015 -0700

Add the acosh function (as an atomic operation when defined by compiler).

commit b3264fa17b2f65b65800423a0e243c9c3ccfe06a
Author: Brad Bell <bradbell@…>
Date: Wed May 6 20:25:38 2015 -0700

CMakeLists.txt: Change so test only check for compliation.

commit dcbac4d4f20cc383f2bd9edb02036659df40b791
Author: Brad Bell <bradbell@…>
Date: Wed May 6 15:06:28 2015 -0700

asinh.cpp: check higher orders, relax accuracy on test.

commit 5f8881993fedd18cccc3c74831133a8f8a9d17b0
Author: Brad Bell <bradbell@…>
Date: Wed May 6 14:36:18 2015 -0700

Change Acos to acos.
acos.cpp: remove trailing white space.

commit e828fa1f7c4c3848c727f14b1b7a8030071ee705
Author: Brad Bell <bradbell@…>
Date: Wed May 6 12:07:35 2015 -0700

Change Acos to acos.
acos.cpp: remove redundant index commands, remove trailing with space.

commit 3d16e5b9fe1bdafa4ad01d1d466bb72b792650fa
Author: Brad Bell <bradbell@…>
Date: Wed May 6 11:30:49 2015 -0700

op_code.hpp: Minor edits to AcosOp? commnets.

commit 58beaaad149b4ac29fae44589d7f8900bf8f4c40
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:51:43 2015 -0700

for_jac_sweep.hpp: Add missing AsinhOp? case.

commit 623c134870c522ae5e80bcf0f89d230902594c80
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:27:39 2015 -0700

Fix comment about AsinhOp? operator.

commit 226b14f6f4810f5abf1ca247aae541963efaf4d6
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:14:08 2015 -0700

Add derivative of F to make order zero case clearer.
acos_reverse.omh: Fix some sign errors.
asin_reverse.omh: Fix typo.
acos_forward.omh: Simplify by distributing minus sign.

commit 4682f4ee73e33b600b180086576e986f636a24dc
Author: Brad Bell <bradbell@…>
Date: Wed May 6 08:15:50 2015 -0700

acos_forward.omh: fix sign that depends on acos versus acosh.

commit 906ae10adf019ddda7f57dd165aab08fc55289c4
Author: Brad Bell <bradbell@…>
Date: Wed May 6 07:09:47 2015 -0700

  1. Fix inclusion of some temporary files in package (e.g., git_commit.sh).
  2. Simplify and improve using git ls-files and ls bin/check_*.
  3. Remove trailing white space.

commit 5096f4706a547bd76caa3766aa2c62802ef7f0bf
Author: Brad Bell <bradbell@…>
Date: Wed May 6 06:41:20 2015 -0700

Combine base type documentation for erf, asinh
(will add more functions to this list list).

commit b3535db5ad95bee90672abcaa686032d23bce2fc
Author: Brad Bell <bradbell@…>
Date: Tue May 5 18:01:11 2015 -0700

  1. Change Arc Cosine/Sine? to Inverse Cosine/Sine?.
  2. Change arcsin-> asin and arccos->acos.
  3. Remove index commands that are duplicates of words in titles.


acos_reverse.omh: Add acosh case to this page.

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