source: trunk/cppad/local/forward1sweep.hpp @ 3678

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

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

commit 5e2f77aac80262cd007effafcc48ecf2d313e467
Author: Brad Bell <bradbell@…>
Date: Tue May 5 09:43:28 2015 -0700

Properly handel case where compiler does not have asinh function.

  • Property svn:keywords set to Id
File size: 26.3 KB
Line 
1/* $Id: forward1sweep.hpp 3678 2015-05-05 16:51:11Z bradbell $ */
2# ifndef CPPAD_FORWARD1SWEEP_INCLUDED
3# define CPPAD_FORWARD1SWEEP_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
16namespace CppAD { // BEGIN_CPPAD_NAMESPACE
17/*!
18\file forward1sweep.hpp
19Compute one Taylor coefficient for each order requested.
20*/
21
22/*
23\def CPPAD_ATOMIC_CALL
24This avoids warnings when NDEBUG is defined and user_ok is not used.
25If NDEBUG is defined, this resolves to
26\code
27        user_atom->forward
28\endcode
29otherwise, it respolves to
30\code
31        user_ok = user_atom->forward
32\endcode
33This macro is undefined at the end of this file to facillitate its
34use with a different definition in other files.
35*/
36# ifdef NDEBUG
37# define CPPAD_ATOMIC_CALL user_atom->forward
38# else
39# define CPPAD_ATOMIC_CALL user_ok = user_atom->forward
40# endif
41
42/*!
43\def CPPAD_FORWARD1SWEEP_TRACE
44This value is either zero or one.
45Zero is the normal operational value.
46If it is one, a trace of every forward1sweep computation is printed.
47*/
48# define CPPAD_FORWARD1SWEEP_TRACE 0
49
50/*!
51Compute arbitrary order forward mode Taylor coefficients.
52
53<!-- replace forward0sweep_doc_define -->
54\tparam Base
55The type used during the forward mode computations; i.e., the corresponding
56recording of operations used the type AD<Base>.
57
58\param s_out
59Is the stream where output corresponding to PriOp operations will
60be written.
61
62\param print
63If print is false,
64suppress the output that is otherwise generated by the c PriOp instructions.
65
66\param n
67is the number of independent variables on the tape.
68
69\param numvar
70is the total number of variables on the tape.
71This is also equal to the number of rows in the matrix taylor; i.e.,
72play->num_var_rec().
73
74\param play
75The information stored in play
76is a recording of the operations corresponding to the function
77\f[
78        F : {\bf R}^n \rightarrow {\bf R}^m
79\f]
80where \f$ n \f$ is the number of independent variables and
81\f$ m \f$ is the number of dependent variables.
82\n
83\n
84The object play is effectly constant.
85The exception to this is that while palying back the tape
86the object play holds information about the current location
87with in the tape and this changes during palyback.
88
89\param J
90Is the number of columns in the coefficient matrix taylor.
91This must be greater than or equal one.
92
93<!-- end forward0sweep_doc_define -->
94
95\param cskip_op
96Is a vector with size play->num_op_rec().
97\n
98\n
99<tt>p = 0</tt>
100\n
101In this case,
102the input value of the elements does not matter.
103Upon return, if cskip_op[i] is true, the operator with index i
104does not affect any of the dependent variable
105(given the value of the independent variables).
106\n
107\n
108<tt>p > 0</tt>
109\n
110In this case cskip_op is not modified and has the same meaning
111as its return value above.
112
113\param var_by_load_op
114is a vector with size play->num_load_op_rec().
115\n
116\n
117<tt>p == 0</tt>
118\n
119In this case,
120The input value of the elements does not matter.
121Upon return,
122it is the variable index corresponding the result for each load operator.
123In the case where the index is zero,
124the load operator results in a parameter (not a variable).
125Note that the is no variable with index zero on the tape.
126\n
127\n
128<tt>p > 0</tt>
129\n
130In this case var_by_load_op is not modified and has the meaning
131as its return value above.
132
133\param p
134is the lowest order of the Taylor coefficients
135that are computed during this call.
136
137\param q
138is the highest order of the Taylor coefficients
139that are computed during this call.
140
141\param taylor
142\n
143\b Input:
144For <code>i = 1 , ... , numvar-1</code>,
145<code>k = 0 , ... , p-1</code>,
146<code>taylor[ J*i + k]</code>
147is the k-th order Taylor coefficient corresponding to
148the i-th variable.
149\n
150\n
151\b Input:
152For <code>i = 1 , ... , n</code>,
153<code>k = p , ... , q</code>,
154<code>taylor[ J*j + k]</code>
155is the k-th order Taylor coefficient corresponding to
156the i-th variable
157(these are the independent varaibles).
158\n
159\n
160\b Output:
161For <code>i = n+1 , ... , numvar-1</code>, and
162<code>k = 0 , ... , p-1</code>,
163<code>taylor[ J*i + k]</code>
164is the k-th order Taylor coefficient corresponding to
165the i-th variable.
166
167
168\param compare_change_count
169Is the count value for changing number and op_index during
170zero order foward mode.
171
172\param compare_change_number
173If p is non-zero, this value is not changed, otherwise:
174If compare_change_count is zero, this value is set to zero, otherwise:
175this value is set to the number of comparision operations
176that have a different result from when the information in
177play was recorded.
178
179\param compare_change_op_index
180if p is non-zero, this value is not changed, otherwise:
181If compare_change_count is zero, this value is set to zero.
182Otherwise it is the operator index (see forward_next) for the count-th
183comparision operation that has a different result from when the information in
184play was recorded.
185*/
186
187template <class Base>
188void forward1sweep(
189        std::ostream&         s_out,
190        const bool            print,
191        const size_t          p,
192        const size_t          q,
193        const size_t          n,
194        const size_t          numvar,
195        player<Base>*         play,
196        const size_t          J,
197        Base*                 taylor,
198        bool*                 cskip_op,
199        pod_vector<addr_t>&   var_by_load_op,
200        size_t                compare_change_count,
201        size_t&               compare_change_number,
202        size_t&               compare_change_op_index
203)
204{
205        // number of directions
206        const size_t r = 1;
207
208        CPPAD_ASSERT_UNKNOWN( p <= q );
209        CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
210        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
211
212        /*
213        <!-- replace forward0sweep_code_define -->
214        */
215        // op code for current instruction
216        OpCode op;
217
218        // index for current instruction
219        size_t i_op;
220
221        // next variables
222        size_t i_var;
223
224        // operation argument indices
225        const addr_t*   arg = CPPAD_NULL;
226
227        // initialize the comparision operator counter
228        if( p == 0 )
229        {       compare_change_number   = 0;
230                compare_change_op_index = 0;
231        }
232
233        // If this includes a zero calculation, initialize this information
234        pod_vector<bool>   isvar_by_ind;
235        pod_vector<size_t> index_by_ind;
236        if( p == 0 )
237        {       size_t i;
238
239                // this includes order zero calculation, initialize vector indices
240                size_t num = play->num_vec_ind_rec();
241                if( num > 0 )
242                {       isvar_by_ind.extend(num);
243                        index_by_ind.extend(num);
244                        for(i = 0; i < num; i++)
245                        {       index_by_ind[i] = play->GetVecInd(i);
246                                isvar_by_ind[i] = false;
247                        }
248                }
249                // includes zero order, so initialize conditional skip flags
250                num = play->num_op_rec();
251                for(i = 0; i < num; i++)
252                        cskip_op[i] = false;
253        }
254
255        // work space used by UserOp.
256        vector<bool> user_vx;        // empty vecotor
257        vector<bool> user_vy;        // empty vecotor
258        vector<Base> user_tx;        // argument vector Taylor coefficients
259        vector<Base> user_ty;        // result vector Taylor coefficients
260        size_t user_index = 0;       // indentifier for this atomic operation
261        size_t user_id    = 0;       // user identifier for this call to operator
262        size_t user_i     = 0;       // index in result vector
263        size_t user_j     = 0;       // index in argument vector
264        size_t user_m     = 0;       // size of result vector
265        size_t user_n     = 0;       // size of arugment vector
266        //
267        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
268# ifndef NDEBUG
269        bool               user_ok   = false;      // atomic op return value
270# endif
271        //
272        // next expected operator in a UserOp sequence
273        enum { user_start, user_arg, user_ret, user_end, user_trace }
274        user_state = user_start;
275
276        // length of the parameter vector (used by CppAD assert macros)
277        const size_t num_par = play->num_par_rec();
278
279        // pointer to the beginning of the parameter vector
280        const Base* parameter = CPPAD_NULL;
281        if( num_par > 0 )
282                parameter = play->GetPar();
283
284        // length of the text vector (used by CppAD assert macros)
285        const size_t num_text = play->num_text_rec();
286
287        // pointer to the beginning of the text vector
288        const char* text = CPPAD_NULL;
289        if( num_text > 0 )
290                text = play->GetTxt(0);
291        /*
292        <!-- end forward0sweep_code_define -->
293        */
294        // temporary indices
295        size_t i, k;
296
297        // number of orders for this user calculation
298        // (not needed for order zero)
299        const size_t user_q1 = q+1;
300
301        // variable indices for results vector
302        // (done differently for order zero).
303        vector<size_t> user_iy;
304
305        // skip the BeginOp at the beginning of the recording
306        play->forward_start(op, arg, i_op, i_var);
307        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
308# if CPPAD_FORWARD1SWEEP_TRACE
309        std::cout << std::endl;
310# endif
311        bool more_operators = true;
312        while(more_operators)
313        {
314                // this op
315                play->forward_next(op, arg, i_op, i_var);
316                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) );
317                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) );
318                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
319                CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var);
320
321                // check if we are skipping this operation
322                while( cskip_op[i_op] )
323                {       if( op == CSumOp )
324                        {       // CSumOp has a variable number of arguments
325                                play->forward_csum(op, arg, i_op, i_var);
326                        }
327                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
328                        // if( op == CSkipOp )
329                        // {    // CSkip has a variable number of arguments
330                        //      play->forward_cskip(op, arg, i_op, i_var);
331                        // }
332                        play->forward_next(op, arg, i_op, i_var);
333                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
334                }
335
336                // action depends on the operator
337                switch( op )
338                {
339                        case AbsOp:
340                        forward_abs_op(p, q, i_var, arg[0], J, taylor);
341                        break;
342                        // -------------------------------------------------
343
344                        case AddvvOp:
345                        forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);
346                        break;
347                        // -------------------------------------------------
348
349                        case AddpvOp:
350                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
351                        forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);
352                        break;
353                        // -------------------------------------------------
354
355                        case AcosOp:
356                        // sqrt(1 - x * x), acos(x)
357                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
358                        forward_acos_op(p, q, i_var, arg[0], J, taylor);
359                        break;
360                        // -------------------------------------------------
361
362                        case AsinOp:
363                        // sqrt(1 - x * x), asin(x)
364                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
365                        forward_asin_op(p, q, i_var, arg[0], J, taylor);
366                        break;
367                        // -------------------------------------------------
368
369# if CPPAD_COMPILER_HAS_ASINH
370                        case AsinhOp:
371                        // sqrt(1 + x * x), asin(x)
372                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
373                        forward_asinh_op(p, q, i_var, arg[0], J, taylor);
374                        break;
375# endif
376                        // -------------------------------------------------
377
378                        case AtanOp:
379                        // 1 + x * x, atan(x)
380                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
381                        forward_atan_op(p, q, i_var, arg[0], J, taylor);
382                        break;
383                        // -------------------------------------------------
384
385                        case CExpOp:
386                        forward_cond_op(
387                                p, q, i_var, arg, num_par, parameter, J, taylor
388                        );
389                        break;
390                        // ---------------------------------------------------
391
392                        case CosOp:
393                        // sin(x), cos(x)
394                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
395                        forward_cos_op(p, q, i_var, arg[0], J, taylor);
396                        break;
397                        // ---------------------------------------------------
398
399                        case CoshOp:
400                        // sinh(x), cosh(x)
401                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
402                        forward_cosh_op(p, q, i_var, arg[0], J, taylor);
403                        break;
404                        // -------------------------------------------------
405
406                        case CSkipOp:
407                        // CSkipOp has a variable number of arguments and
408                        // forward_next thinks it has no arguments.
409                        // we must inform forward_next of this special case.
410                        if( p == 0 )
411                        {       forward_cskip_op_0(
412                                        i_var, arg, num_par, parameter, J, taylor, cskip_op
413                                );
414                        }
415                        play->forward_cskip(op, arg, i_op, i_var);
416                        break;
417                        // -------------------------------------------------
418
419                        case CSumOp:
420                        // CSumOp has a variable number of arguments and
421                        // forward_next thinks it has no arguments.
422                        // we must inform forward_next of this special case.
423                        forward_csum_op(
424                                p, q, i_var, arg, num_par, parameter, J, taylor
425                        );
426                        play->forward_csum(op, arg, i_op, i_var);
427                        break;
428                        // -------------------------------------------------
429
430                        case DisOp:
431                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
432                        break;
433                        // -------------------------------------------------
434
435                        case DivvvOp:
436                        forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);
437                        break;
438                        // -------------------------------------------------
439
440                        case DivpvOp:
441                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
442                        forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);
443                        break;
444                        // -------------------------------------------------
445
446                        case DivvpOp:
447                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
448                        forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);
449                        break;
450                        // -------------------------------------------------
451
452                        case EndOp:
453                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
454                        more_operators = false;
455                        break;
456                        // -------------------------------------------------
457
458                        case EqpvOp:
459                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
460                        {       forward_eqpv_op_0(
461                                        compare_change_number, arg, parameter, J, taylor
462                                );
463                                if( compare_change_count == compare_change_number )
464                                        compare_change_op_index = i_op;
465                        }
466                        break;
467                        // -------------------------------------------------
468
469                        case EqvvOp:
470                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
471                        {       forward_eqvv_op_0(
472                                        compare_change_number, arg, parameter, J, taylor
473                                );
474                                if( compare_change_count == compare_change_number )
475                                        compare_change_op_index = i_op;
476                        }
477                        break;
478                        // -------------------------------------------------
479
480# if CPPAD_COMPILER_HAS_ERF
481                        case ErfOp:
482                        CPPAD_ASSERT_UNKNOWN( CPPAD_COMPILER_HAS_ERF );
483                        // 2DO: implement zero order version of this function
484                        forward_erf_op(p, q, i_var, arg, parameter, J, taylor);
485                        break;
486# endif
487                        // -------------------------------------------------
488
489                        case ExpOp:
490                        forward_exp_op(p, q, i_var, arg[0], J, taylor);
491                        break;
492                        // ---------------------------------------------------
493
494                        case InvOp:
495                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
496                        break;
497                        // -------------------------------------------------
498
499                        case LdpOp:
500                        if( p == 0 )
501                        {       forward_load_p_op_0(
502                                        play,
503                                        i_var,
504                                        arg,
505                                        parameter,
506                                        J,
507                                        taylor,
508                                        isvar_by_ind.data(),
509                                        index_by_ind.data(),
510                                        var_by_load_op.data()
511                                );
512                                if( p < q ) forward_load_op(
513                                        play,
514                                        op,
515                                        p+1,
516                                        q,
517                                        r,
518                                        J,
519                                        i_var,
520                                        arg,
521                                        var_by_load_op.data(),
522                                        taylor
523                                );
524                        }
525                        else    forward_load_op(
526                                play,
527                                op,
528                                p,
529                                q,
530                                r,
531                                J,
532                                i_var,
533                                arg,
534                                var_by_load_op.data(),
535                                taylor
536                        );
537                        break;
538                        // -------------------------------------------------
539
540                        case LdvOp:
541                        if( p == 0 )
542                        {       forward_load_v_op_0(
543                                        play,
544                                        i_var,
545                                        arg,
546                                        parameter,
547                                        J,
548                                        taylor,
549                                        isvar_by_ind.data(),
550                                        index_by_ind.data(),
551                                        var_by_load_op.data()
552                                );
553                                if( p < q ) forward_load_op(
554                                        play,
555                                        op,
556                                        p+1,
557                                        q,
558                                        r,
559                                        J,
560                                        i_var,
561                                        arg,
562                                        var_by_load_op.data(),
563                                        taylor
564                                );
565                        }
566                        else    forward_load_op(
567                                play,
568                                op,
569                                p,
570                                q,
571                                r,
572                                J,
573                                i_var,
574                                arg,
575                                var_by_load_op.data(),
576                                taylor
577                        );
578                        break;
579                        // -------------------------------------------------
580
581                        case LepvOp:
582                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
583                        {       forward_lepv_op_0(
584                                        compare_change_number, arg, parameter, J, taylor
585                                );
586                                if( compare_change_count == compare_change_number )
587                                        compare_change_op_index = i_op;
588                        }
589                        break;
590
591                        case LevpOp:
592                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
593                        {       forward_levp_op_0(
594                                        compare_change_number, arg, parameter, J, taylor
595                                );
596                                if( compare_change_count == compare_change_number )
597                                        compare_change_op_index = i_op;
598                        }
599                        break;
600                        // -------------------------------------------------
601
602                        case LevvOp:
603                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
604                        {       forward_levv_op_0(
605                                        compare_change_number, arg, parameter, J, taylor
606                                );
607                                if( compare_change_count == compare_change_number )
608                                        compare_change_op_index = i_op;
609                        }
610                        break;
611                        // -------------------------------------------------
612
613                        case LogOp:
614                        forward_log_op(p, q, i_var, arg[0], J, taylor);
615                        break;
616                        // -------------------------------------------------
617
618                        case LtpvOp:
619                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
620                        {       forward_ltpv_op_0(
621                                        compare_change_number, arg, parameter, J, taylor
622                                );
623                                if( compare_change_count == compare_change_number )
624                                        compare_change_op_index = i_op;
625                        }
626                        break;
627
628                        case LtvpOp:
629                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
630                        {       forward_ltvp_op_0(
631                                        compare_change_number, arg, parameter, J, taylor
632                                );
633                                if( compare_change_count == compare_change_number )
634                                        compare_change_op_index = i_op;
635                        }
636                        break;
637                        // -------------------------------------------------
638
639                        case LtvvOp:
640                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
641                        {       forward_ltvv_op_0(
642                                        compare_change_number, arg, parameter, J, taylor
643                                );
644                                if( compare_change_count == compare_change_number )
645                                        compare_change_op_index = i_op;
646                        }
647                        break;
648                        // -------------------------------------------------
649
650                        case MulvvOp:
651                        forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
652                        break;
653                        // -------------------------------------------------
654
655                        case MulpvOp:
656                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
657                        forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
658                        break;
659                        // -------------------------------------------------
660
661                        case NepvOp:
662                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
663                        {       forward_nepv_op_0(
664                                        compare_change_number, arg, parameter, J, taylor
665                                );
666                                if( compare_change_count == compare_change_number )
667                                        compare_change_op_index = i_op;
668                        }
669                        break;
670                        // -------------------------------------------------
671
672                        case NevvOp:
673                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
674                        {       forward_nevv_op_0(
675                                        compare_change_number, arg, parameter, J, taylor
676                                );
677                                if( compare_change_count == compare_change_number )
678                                        compare_change_op_index = i_op;
679                        }
680                        break;
681                        // -------------------------------------------------
682
683                        case ParOp:
684                        i = p;
685                        if( i == 0 )
686                        {       forward_par_op_0(
687                                        i_var, arg, num_par, parameter, J, taylor
688                                );
689                                i++;
690                        }
691                        while(i <= q)
692                        {       taylor[ i_var * J + i] = Base(0);
693                                i++;
694                        }
695                        break;
696                        // -------------------------------------------------
697
698                        case PowvpOp:
699                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
700                        forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
701                        break;
702                        // -------------------------------------------------
703
704                        case PowpvOp:
705                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
706                        forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
707                        break;
708                        // -------------------------------------------------
709
710                        case PowvvOp:
711                        forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
712                        break;
713                        // -------------------------------------------------
714
715                        case PriOp:
716                        if( (p == 0) & print ) forward_pri_0(s_out,
717                                arg, num_text, text, num_par, parameter, J, taylor
718                        );
719                        break;
720                        // -------------------------------------------------
721
722                        case SignOp:
723                        // sign(x)
724                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
725                        forward_sign_op(p, q, i_var, arg[0], J, taylor);
726                        break;
727                        // -------------------------------------------------
728
729                        case SinOp:
730                        // cos(x), sin(x)
731                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
732                        forward_sin_op(p, q, i_var, arg[0], J, taylor);
733                        break;
734                        // -------------------------------------------------
735
736                        case SinhOp:
737                        // cosh(x), sinh(x)
738                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
739                        forward_sinh_op(p, q, i_var, arg[0], J, taylor);
740                        break;
741                        // -------------------------------------------------
742
743                        case SqrtOp:
744                        forward_sqrt_op(p, q, i_var, arg[0], J, taylor);
745                        break;
746                        // -------------------------------------------------
747
748                        case StppOp:
749                        if( p == 0 )
750                        {       forward_store_pp_op_0(
751                                        i_var,
752                                        arg,
753                                        num_par,
754                                        J,
755                                        taylor,
756                                        isvar_by_ind.data(),
757                                        index_by_ind.data()
758                                );
759                        }
760                        break;
761                        // -------------------------------------------------
762
763                        case StpvOp:
764                        if( p == 0 )
765                        {       forward_store_pv_op_0(
766                                        i_var,
767                                        arg,
768                                        num_par,
769                                        J,
770                                        taylor,
771                                        isvar_by_ind.data(),
772                                        index_by_ind.data()
773                                );
774                        }
775                        break;
776                        // -------------------------------------------------
777
778                        case StvpOp:
779                        if( p == 0 )
780                        {       forward_store_vp_op_0(
781                                        i_var,
782                                        arg,
783                                        num_par,
784                                        J,
785                                        taylor,
786                                        isvar_by_ind.data(),
787                                        index_by_ind.data()
788                                );
789                        }
790                        break;
791                        // -------------------------------------------------
792
793                        case StvvOp:
794                        if( p == 0 )
795                        {       forward_store_vv_op_0(
796                                        i_var,
797                                        arg,
798                                        num_par,
799                                        J,
800                                        taylor,
801                                        isvar_by_ind.data(),
802                                        index_by_ind.data()
803                                );
804                        }
805                        break;
806                        // -------------------------------------------------
807
808                        case SubvvOp:
809                        forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
810                        break;
811                        // -------------------------------------------------
812
813                        case SubpvOp:
814                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
815                        forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
816                        break;
817                        // -------------------------------------------------
818
819                        case SubvpOp:
820                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
821                        forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
822                        break;
823                        // -------------------------------------------------
824
825                        case TanOp:
826                        // tan(x)^2, tan(x)
827                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
828                        forward_tan_op(p, q, i_var, arg[0], J, taylor);
829                        break;
830                        // -------------------------------------------------
831
832                        case TanhOp:
833                        // tanh(x)^2, tanh(x)
834                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
835                        forward_tanh_op(p, q, i_var, arg[0], J, taylor);
836                        break;
837                        // -------------------------------------------------
838
839                        case UserOp:
840                        // start or end an atomic operation sequence
841                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
842                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
843                        if( user_state == user_start )
844                        {       user_index = arg[0];
845                                user_id    = arg[1];
846                                user_n     = arg[2];
847                                user_m     = arg[3];
848                                user_atom  = atomic_base<Base>::class_object(user_index);
849# ifndef NDEBUG
850                                if( user_atom == CPPAD_NULL )
851                                {       std::string msg =
852                                                atomic_base<Base>::class_name(user_index)
853                                                + ": atomic_base function has been deleted";
854                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
855                                }
856# endif
857                                if(user_tx.size() != user_n * user_q1)
858                                        user_tx.resize(user_n * user_q1);
859                                if(user_ty.size() != user_m * user_q1)
860                                        user_ty.resize(user_m * user_q1);
861                                if(user_iy.size() != user_m)
862                                        user_iy.resize(user_m);
863                                user_j     = 0;
864                                user_i     = 0;
865                                user_state = user_arg;
866                        }
867                        else
868                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
869                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
870                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
871                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
872                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
873
874                                // call users function for this operation
875                                user_atom->set_id(user_id);
876                                CPPAD_ATOMIC_CALL(
877                                        p, q, user_vx, user_vy, user_tx, user_ty
878                                );
879# ifndef NDEBUG
880                                if( ! user_ok )
881                                {       std::string msg =
882                                                atomic_base<Base>::class_name(user_index)
883                                                + ": atomic_base.forward: returned false";
884                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
885                                }
886# endif
887                                for(i = 0; i < user_m; i++)
888                                        if( user_iy[i] > 0 )
889                                                for(k = p; k <= q; k++)
890                                                        taylor[ user_iy[i] * J + k ] =
891                                                                user_ty[ i * user_q1 + k ];
892# if CPPAD_FORWARD1SWEEP_TRACE
893                                user_state = user_trace;
894# else
895                                user_state = user_start;
896# endif
897                        }
898                        break;
899
900                        case UsrapOp:
901                        // parameter argument in an atomic operation sequence
902                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
903                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
904                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
905                        user_tx[user_j * user_q1 + 0] = parameter[ arg[0]];
906                        for(k = 1; k < user_q1; k++)
907                                user_tx[user_j * user_q1 + k] = Base(0);
908                        ++user_j;
909                        if( user_j == user_n )
910                                user_state = user_ret;
911                        break;
912
913                        case UsravOp:
914                        // variable argument in an atomic operation sequence
915                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
916                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
917                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
918                        for(k = 0; k < user_q1; k++)
919                                user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k];
920                        ++user_j;
921                        if( user_j == user_n )
922                                user_state = user_ret;
923                        break;
924
925                        case UsrrpOp:
926                        // parameter result in an atomic operation sequence
927                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
928                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
929                        user_iy[user_i] = 0;
930                        user_ty[user_i * user_q1 + 0] = parameter[ arg[0]];
931                        for(k = 1; k < p; k++)
932                                user_ty[user_i * user_q1 + k] = Base(0);
933                        user_i++;
934                        if( user_i == user_m )
935                                user_state = user_end;
936                        break;
937
938                        case UsrrvOp:
939                        // variable result in an atomic operation sequence
940                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
941                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
942                        user_iy[user_i] = i_var;
943                        for(k = 0; k < p; k++)
944                                user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k];
945                        user_i++;
946                        if( user_i == user_m )
947                                user_state = user_end;
948                        break;
949                        // -------------------------------------------------
950
951                        default:
952                        CPPAD_ASSERT_UNKNOWN(0);
953                }
954# if CPPAD_FORWARD1SWEEP_TRACE
955                if( user_state == user_trace )
956                {       user_state = user_start;
957
958                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
959                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
960                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
961                        {       size_t i_tmp   = (i_op + i) - user_m;
962                                printOp(
963                                        std::cout,
964                                        play,
965                                        i_tmp,
966                                        user_iy[i],
967                                        UsrrvOp,
968                                        CPPAD_NULL
969                                );
970                                Base* Z_tmp = taylor + user_iy[i] * J;
971                                printOpResult(
972                                        std::cout,
973                                        q + 1,
974                                        Z_tmp,
975                                        0,
976                                        (Base *) CPPAD_NULL
977                                );
978                                std::cout << std::endl;
979                        }
980                }
981                Base*           Z_tmp   = taylor + J * i_var;
982                const addr_t*   arg_tmp = arg;
983                if( op == CSumOp )
984                        arg_tmp = arg - arg[-1] - 4;
985                if( op == CSkipOp )
986                        arg_tmp = arg - arg[-1] - 7;
987                if( op != UsrrvOp )
988                {
989                        printOp(
990                                std::cout,
991                                play,
992                                i_op,
993                                i_var,
994                                op,
995                                arg_tmp
996                        );
997                        if( NumRes(op) > 0 ) printOpResult(
998                                std::cout,
999                                q + 1,
1000                                Z_tmp,
1001                                0,
1002                                (Base *) CPPAD_NULL
1003                        );
1004                        std::cout << std::endl;
1005                }
1006        }
1007        std::cout << std::endl;
1008# else
1009        }
1010# endif
1011        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
1012        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
1013
1014        if( (p == 0) & (compare_change_count == 0) )
1015                compare_change_number = 0;
1016        return;
1017}
1018
1019// preprocessor symbols that are local to this file
1020# undef CPPAD_FORWARD1SWEEP_TRACE
1021# undef CPPAD_ATOMIC_CALL
1022
1023} // END_CPPAD_NAMESPACE
1024# endif
Note: See TracBrowser for help on using the repository browser.