source: trunk/cppad/local/forward1sweep.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: 26.6 KB
Line 
1/* $Id: forward1sweep.hpp 3680 2015-05-07 19:17:37Z 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# if CPPAD_COMPILER_HAS_ACOSH
363                        case AcoshOp:
364                        // sqrt(x * x - 1), acosh(x)
365                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
366                        forward_acosh_op(p, q, i_var, arg[0], J, taylor);
367                        break;
368# endif
369                        // -------------------------------------------------
370
371                        case AsinOp:
372                        // sqrt(1 - x * x), asin(x)
373                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
374                        forward_asin_op(p, q, i_var, arg[0], J, taylor);
375                        break;
376                        // -------------------------------------------------
377
378# if CPPAD_COMPILER_HAS_ASINH
379                        case AsinhOp:
380                        // sqrt(1 + x * x), asinh(x)
381                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
382                        forward_asinh_op(p, q, i_var, arg[0], J, taylor);
383                        break;
384# endif
385                        // -------------------------------------------------
386
387                        case AtanOp:
388                        // 1 + x * x, atan(x)
389                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
390                        forward_atan_op(p, q, i_var, arg[0], J, taylor);
391                        break;
392                        // -------------------------------------------------
393
394                        case CExpOp:
395                        forward_cond_op(
396                                p, q, i_var, arg, num_par, parameter, J, taylor
397                        );
398                        break;
399                        // ---------------------------------------------------
400
401                        case CosOp:
402                        // sin(x), cos(x)
403                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
404                        forward_cos_op(p, q, i_var, arg[0], J, taylor);
405                        break;
406                        // ---------------------------------------------------
407
408                        case CoshOp:
409                        // sinh(x), cosh(x)
410                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
411                        forward_cosh_op(p, q, i_var, arg[0], J, taylor);
412                        break;
413                        // -------------------------------------------------
414
415                        case CSkipOp:
416                        // CSkipOp has a variable number of arguments and
417                        // forward_next thinks it has no arguments.
418                        // we must inform forward_next of this special case.
419                        if( p == 0 )
420                        {       forward_cskip_op_0(
421                                        i_var, arg, num_par, parameter, J, taylor, cskip_op
422                                );
423                        }
424                        play->forward_cskip(op, arg, i_op, i_var);
425                        break;
426                        // -------------------------------------------------
427
428                        case CSumOp:
429                        // CSumOp has a variable number of arguments and
430                        // forward_next thinks it has no arguments.
431                        // we must inform forward_next of this special case.
432                        forward_csum_op(
433                                p, q, i_var, arg, num_par, parameter, J, taylor
434                        );
435                        play->forward_csum(op, arg, i_op, i_var);
436                        break;
437                        // -------------------------------------------------
438
439                        case DisOp:
440                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
441                        break;
442                        // -------------------------------------------------
443
444                        case DivvvOp:
445                        forward_divvv_op(p, q, i_var, arg, parameter, J, taylor);
446                        break;
447                        // -------------------------------------------------
448
449                        case DivpvOp:
450                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
451                        forward_divpv_op(p, q, i_var, arg, parameter, J, taylor);
452                        break;
453                        // -------------------------------------------------
454
455                        case DivvpOp:
456                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
457                        forward_divvp_op(p, q, i_var, arg, parameter, J, taylor);
458                        break;
459                        // -------------------------------------------------
460
461                        case EndOp:
462                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
463                        more_operators = false;
464                        break;
465                        // -------------------------------------------------
466
467                        case EqpvOp:
468                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
469                        {       forward_eqpv_op_0(
470                                        compare_change_number, arg, parameter, J, taylor
471                                );
472                                if( compare_change_count == compare_change_number )
473                                        compare_change_op_index = i_op;
474                        }
475                        break;
476                        // -------------------------------------------------
477
478                        case EqvvOp:
479                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
480                        {       forward_eqvv_op_0(
481                                        compare_change_number, arg, parameter, J, taylor
482                                );
483                                if( compare_change_count == compare_change_number )
484                                        compare_change_op_index = i_op;
485                        }
486                        break;
487                        // -------------------------------------------------
488
489# if CPPAD_COMPILER_HAS_ERF
490                        case ErfOp:
491                        CPPAD_ASSERT_UNKNOWN( CPPAD_COMPILER_HAS_ERF );
492                        // 2DO: implement zero order version of this function
493                        forward_erf_op(p, q, i_var, arg, parameter, J, taylor);
494                        break;
495# endif
496                        // -------------------------------------------------
497
498                        case ExpOp:
499                        forward_exp_op(p, q, i_var, arg[0], J, taylor);
500                        break;
501                        // ---------------------------------------------------
502
503                        case InvOp:
504                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
505                        break;
506                        // -------------------------------------------------
507
508                        case LdpOp:
509                        if( p == 0 )
510                        {       forward_load_p_op_0(
511                                        play,
512                                        i_var,
513                                        arg,
514                                        parameter,
515                                        J,
516                                        taylor,
517                                        isvar_by_ind.data(),
518                                        index_by_ind.data(),
519                                        var_by_load_op.data()
520                                );
521                                if( p < q ) forward_load_op(
522                                        play,
523                                        op,
524                                        p+1,
525                                        q,
526                                        r,
527                                        J,
528                                        i_var,
529                                        arg,
530                                        var_by_load_op.data(),
531                                        taylor
532                                );
533                        }
534                        else    forward_load_op(
535                                play,
536                                op,
537                                p,
538                                q,
539                                r,
540                                J,
541                                i_var,
542                                arg,
543                                var_by_load_op.data(),
544                                taylor
545                        );
546                        break;
547                        // -------------------------------------------------
548
549                        case LdvOp:
550                        if( p == 0 )
551                        {       forward_load_v_op_0(
552                                        play,
553                                        i_var,
554                                        arg,
555                                        parameter,
556                                        J,
557                                        taylor,
558                                        isvar_by_ind.data(),
559                                        index_by_ind.data(),
560                                        var_by_load_op.data()
561                                );
562                                if( p < q ) forward_load_op(
563                                        play,
564                                        op,
565                                        p+1,
566                                        q,
567                                        r,
568                                        J,
569                                        i_var,
570                                        arg,
571                                        var_by_load_op.data(),
572                                        taylor
573                                );
574                        }
575                        else    forward_load_op(
576                                play,
577                                op,
578                                p,
579                                q,
580                                r,
581                                J,
582                                i_var,
583                                arg,
584                                var_by_load_op.data(),
585                                taylor
586                        );
587                        break;
588                        // -------------------------------------------------
589
590                        case LepvOp:
591                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
592                        {       forward_lepv_op_0(
593                                        compare_change_number, arg, parameter, J, taylor
594                                );
595                                if( compare_change_count == compare_change_number )
596                                        compare_change_op_index = i_op;
597                        }
598                        break;
599
600                        case LevpOp:
601                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
602                        {       forward_levp_op_0(
603                                        compare_change_number, arg, parameter, J, taylor
604                                );
605                                if( compare_change_count == compare_change_number )
606                                        compare_change_op_index = i_op;
607                        }
608                        break;
609                        // -------------------------------------------------
610
611                        case LevvOp:
612                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
613                        {       forward_levv_op_0(
614                                        compare_change_number, arg, parameter, J, taylor
615                                );
616                                if( compare_change_count == compare_change_number )
617                                        compare_change_op_index = i_op;
618                        }
619                        break;
620                        // -------------------------------------------------
621
622                        case LogOp:
623                        forward_log_op(p, q, i_var, arg[0], J, taylor);
624                        break;
625                        // -------------------------------------------------
626
627                        case LtpvOp:
628                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
629                        {       forward_ltpv_op_0(
630                                        compare_change_number, arg, parameter, J, taylor
631                                );
632                                if( compare_change_count == compare_change_number )
633                                        compare_change_op_index = i_op;
634                        }
635                        break;
636
637                        case LtvpOp:
638                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
639                        {       forward_ltvp_op_0(
640                                        compare_change_number, arg, parameter, J, taylor
641                                );
642                                if( compare_change_count == compare_change_number )
643                                        compare_change_op_index = i_op;
644                        }
645                        break;
646                        // -------------------------------------------------
647
648                        case LtvvOp:
649                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
650                        {       forward_ltvv_op_0(
651                                        compare_change_number, arg, parameter, J, taylor
652                                );
653                                if( compare_change_count == compare_change_number )
654                                        compare_change_op_index = i_op;
655                        }
656                        break;
657                        // -------------------------------------------------
658
659                        case MulvvOp:
660                        forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
661                        break;
662                        // -------------------------------------------------
663
664                        case MulpvOp:
665                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
666                        forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
667                        break;
668                        // -------------------------------------------------
669
670                        case NepvOp:
671                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
672                        {       forward_nepv_op_0(
673                                        compare_change_number, arg, parameter, J, taylor
674                                );
675                                if( compare_change_count == compare_change_number )
676                                        compare_change_op_index = i_op;
677                        }
678                        break;
679                        // -------------------------------------------------
680
681                        case NevvOp:
682                        if( ( p == 0 ) & ( compare_change_count > 0 ) )
683                        {       forward_nevv_op_0(
684                                        compare_change_number, arg, parameter, J, taylor
685                                );
686                                if( compare_change_count == compare_change_number )
687                                        compare_change_op_index = i_op;
688                        }
689                        break;
690                        // -------------------------------------------------
691
692                        case ParOp:
693                        i = p;
694                        if( i == 0 )
695                        {       forward_par_op_0(
696                                        i_var, arg, num_par, parameter, J, taylor
697                                );
698                                i++;
699                        }
700                        while(i <= q)
701                        {       taylor[ i_var * J + i] = Base(0);
702                                i++;
703                        }
704                        break;
705                        // -------------------------------------------------
706
707                        case PowvpOp:
708                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
709                        forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
710                        break;
711                        // -------------------------------------------------
712
713                        case PowpvOp:
714                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
715                        forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
716                        break;
717                        // -------------------------------------------------
718
719                        case PowvvOp:
720                        forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
721                        break;
722                        // -------------------------------------------------
723
724                        case PriOp:
725                        if( (p == 0) & print ) forward_pri_0(s_out,
726                                arg, num_text, text, num_par, parameter, J, taylor
727                        );
728                        break;
729                        // -------------------------------------------------
730
731                        case SignOp:
732                        // sign(x)
733                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
734                        forward_sign_op(p, q, i_var, arg[0], J, taylor);
735                        break;
736                        // -------------------------------------------------
737
738                        case SinOp:
739                        // cos(x), sin(x)
740                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
741                        forward_sin_op(p, q, i_var, arg[0], J, taylor);
742                        break;
743                        // -------------------------------------------------
744
745                        case SinhOp:
746                        // cosh(x), sinh(x)
747                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
748                        forward_sinh_op(p, q, i_var, arg[0], J, taylor);
749                        break;
750                        // -------------------------------------------------
751
752                        case SqrtOp:
753                        forward_sqrt_op(p, q, i_var, arg[0], J, taylor);
754                        break;
755                        // -------------------------------------------------
756
757                        case StppOp:
758                        if( p == 0 )
759                        {       forward_store_pp_op_0(
760                                        i_var,
761                                        arg,
762                                        num_par,
763                                        J,
764                                        taylor,
765                                        isvar_by_ind.data(),
766                                        index_by_ind.data()
767                                );
768                        }
769                        break;
770                        // -------------------------------------------------
771
772                        case StpvOp:
773                        if( p == 0 )
774                        {       forward_store_pv_op_0(
775                                        i_var,
776                                        arg,
777                                        num_par,
778                                        J,
779                                        taylor,
780                                        isvar_by_ind.data(),
781                                        index_by_ind.data()
782                                );
783                        }
784                        break;
785                        // -------------------------------------------------
786
787                        case StvpOp:
788                        if( p == 0 )
789                        {       forward_store_vp_op_0(
790                                        i_var,
791                                        arg,
792                                        num_par,
793                                        J,
794                                        taylor,
795                                        isvar_by_ind.data(),
796                                        index_by_ind.data()
797                                );
798                        }
799                        break;
800                        // -------------------------------------------------
801
802                        case StvvOp:
803                        if( p == 0 )
804                        {       forward_store_vv_op_0(
805                                        i_var,
806                                        arg,
807                                        num_par,
808                                        J,
809                                        taylor,
810                                        isvar_by_ind.data(),
811                                        index_by_ind.data()
812                                );
813                        }
814                        break;
815                        // -------------------------------------------------
816
817                        case SubvvOp:
818                        forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
819                        break;
820                        // -------------------------------------------------
821
822                        case SubpvOp:
823                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
824                        forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
825                        break;
826                        // -------------------------------------------------
827
828                        case SubvpOp:
829                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
830                        forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
831                        break;
832                        // -------------------------------------------------
833
834                        case TanOp:
835                        // tan(x)^2, tan(x)
836                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
837                        forward_tan_op(p, q, i_var, arg[0], J, taylor);
838                        break;
839                        // -------------------------------------------------
840
841                        case TanhOp:
842                        // tanh(x)^2, tanh(x)
843                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
844                        forward_tanh_op(p, q, i_var, arg[0], J, taylor);
845                        break;
846                        // -------------------------------------------------
847
848                        case UserOp:
849                        // start or end an atomic operation sequence
850                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
851                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
852                        if( user_state == user_start )
853                        {       user_index = arg[0];
854                                user_id    = arg[1];
855                                user_n     = arg[2];
856                                user_m     = arg[3];
857                                user_atom  = atomic_base<Base>::class_object(user_index);
858# ifndef NDEBUG
859                                if( user_atom == CPPAD_NULL )
860                                {       std::string msg =
861                                                atomic_base<Base>::class_name(user_index)
862                                                + ": atomic_base function has been deleted";
863                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
864                                }
865# endif
866                                if(user_tx.size() != user_n * user_q1)
867                                        user_tx.resize(user_n * user_q1);
868                                if(user_ty.size() != user_m * user_q1)
869                                        user_ty.resize(user_m * user_q1);
870                                if(user_iy.size() != user_m)
871                                        user_iy.resize(user_m);
872                                user_j     = 0;
873                                user_i     = 0;
874                                user_state = user_arg;
875                        }
876                        else
877                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
878                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
879                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
880                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
881                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
882
883                                // call users function for this operation
884                                user_atom->set_id(user_id);
885                                CPPAD_ATOMIC_CALL(
886                                        p, q, user_vx, user_vy, user_tx, user_ty
887                                );
888# ifndef NDEBUG
889                                if( ! user_ok )
890                                {       std::string msg =
891                                                atomic_base<Base>::class_name(user_index)
892                                                + ": atomic_base.forward: returned false";
893                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
894                                }
895# endif
896                                for(i = 0; i < user_m; i++)
897                                        if( user_iy[i] > 0 )
898                                                for(k = p; k <= q; k++)
899                                                        taylor[ user_iy[i] * J + k ] =
900                                                                user_ty[ i * user_q1 + k ];
901# if CPPAD_FORWARD1SWEEP_TRACE
902                                user_state = user_trace;
903# else
904                                user_state = user_start;
905# endif
906                        }
907                        break;
908
909                        case UsrapOp:
910                        // parameter argument in an atomic operation sequence
911                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
912                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
913                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
914                        user_tx[user_j * user_q1 + 0] = parameter[ arg[0]];
915                        for(k = 1; k < user_q1; k++)
916                                user_tx[user_j * user_q1 + k] = Base(0);
917                        ++user_j;
918                        if( user_j == user_n )
919                                user_state = user_ret;
920                        break;
921
922                        case UsravOp:
923                        // variable argument in an atomic operation sequence
924                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
925                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
926                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
927                        for(k = 0; k < user_q1; k++)
928                                user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k];
929                        ++user_j;
930                        if( user_j == user_n )
931                                user_state = user_ret;
932                        break;
933
934                        case UsrrpOp:
935                        // parameter result in an atomic operation sequence
936                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
937                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
938                        user_iy[user_i] = 0;
939                        user_ty[user_i * user_q1 + 0] = parameter[ arg[0]];
940                        for(k = 1; k < p; k++)
941                                user_ty[user_i * user_q1 + k] = Base(0);
942                        user_i++;
943                        if( user_i == user_m )
944                                user_state = user_end;
945                        break;
946
947                        case UsrrvOp:
948                        // variable result in an atomic operation sequence
949                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
950                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
951                        user_iy[user_i] = i_var;
952                        for(k = 0; k < p; k++)
953                                user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k];
954                        user_i++;
955                        if( user_i == user_m )
956                                user_state = user_end;
957                        break;
958                        // -------------------------------------------------
959
960                        default:
961                        CPPAD_ASSERT_UNKNOWN(0);
962                }
963# if CPPAD_FORWARD1SWEEP_TRACE
964                if( user_state == user_trace )
965                {       user_state = user_start;
966
967                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
968                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
969                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
970                        {       size_t i_tmp   = (i_op + i) - user_m;
971                                printOp(
972                                        std::cout,
973                                        play,
974                                        i_tmp,
975                                        user_iy[i],
976                                        UsrrvOp,
977                                        CPPAD_NULL
978                                );
979                                Base* Z_tmp = taylor + user_iy[i] * J;
980                                printOpResult(
981                                        std::cout,
982                                        q + 1,
983                                        Z_tmp,
984                                        0,
985                                        (Base *) CPPAD_NULL
986                                );
987                                std::cout << std::endl;
988                        }
989                }
990                Base*           Z_tmp   = taylor + J * i_var;
991                const addr_t*   arg_tmp = arg;
992                if( op == CSumOp )
993                        arg_tmp = arg - arg[-1] - 4;
994                if( op == CSkipOp )
995                        arg_tmp = arg - arg[-1] - 7;
996                if( op != UsrrvOp )
997                {
998                        printOp(
999                                std::cout,
1000                                play,
1001                                i_op,
1002                                i_var,
1003                                op,
1004                                arg_tmp
1005                        );
1006                        if( NumRes(op) > 0 ) printOpResult(
1007                                std::cout,
1008                                q + 1,
1009                                Z_tmp,
1010                                0,
1011                                (Base *) CPPAD_NULL
1012                        );
1013                        std::cout << std::endl;
1014                }
1015        }
1016        std::cout << std::endl;
1017# else
1018        }
1019# endif
1020        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
1021        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
1022
1023        if( (p == 0) & (compare_change_count == 0) )
1024                compare_change_number = 0;
1025        return;
1026}
1027
1028// preprocessor symbols that are local to this file
1029# undef CPPAD_FORWARD1SWEEP_TRACE
1030# undef CPPAD_ATOMIC_CALL
1031
1032} // END_CPPAD_NAMESPACE
1033# endif
Note: See TracBrowser for help on using the repository browser.