source: trunk/cppad/local/forward2sweep.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: 21.6 KB
Line 
1/* $Id: forward2sweep.hpp 3680 2015-05-07 19:17:37Z bradbell $ */
2# ifndef CPPAD_FORWARD2SWEEP_INCLUDED
3# define CPPAD_FORWARD2SWEEP_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 forward2sweep.hpp
19Compute one Taylor coefficient for each direction 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_FORWARD2SWEEP_TRACE
44This value is either zero or one.
45Zero is the normal operational value.
46If it is one, a trace of every forward2sweep computation is printed.
47*/
48# define CPPAD_FORWARD2SWEEP_TRACE 0
49
50/*!
51Compute multiple directions forward mode Taylor coefficients.
52
53\tparam Base
54The type used during the forward mode computations; i.e., the corresponding
55recording of operations used the type AD<Base>.
56
57\param q
58is the order of the Taylor coefficients
59that are computed during this call;
60<code>q > 0</code>.
61
62\param r
63is the number of Taylor coefficients
64that are computed during this call.
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\param taylor
94\n
95\b Input:
96For <code>i = 1 , ... , numvar-1</code>,
97<code>taylor[ (J-1)*r*i + i + 0 ]</code>
98is the zero order Taylor coefficient corresponding to
99the i-th variable and all directions.
100For <code>i = 1 , ... , numvar-1</code>,
101For <code>k = 1 , ... , q-1</code>,
102<code>ell = 0 , ... , r-1</code>,
103<code>taylor[ (J-1)*r*i + i + (k-1)*r + ell + 1 ]</code>
104is the k-th order Taylor coefficient corresponding to
105the i-th variabel and ell-th direction.
106\n
107\n
108\b Input:
109For <code>i = 1 , ... , n</code>,
110<code>ell = 0 , ... , r-1</code>,
111<code>taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ]</code>
112is the q-th order Taylor coefficient corresponding to
113the i-th variable and ell-th direction
114(these are the independent varaibles).
115\n
116\n
117\b Output:
118For <code>i = n+1 , ... , numvar-1</code>,
119<code>ell = 0 , ... , r-1</code>,
120<code>taylor[ (J-1)*r*i + i + (q-1)*r + ell + 1 ]</code>
121is the q-th order Taylor coefficient corresponding to
122the i-th variable and ell-th direction.
123
124\param cskip_op
125Is a vector with size play->num_op_rec().
126If cskip_op[i] is true, the operator with index i
127does not affect any of the dependent variable (given the value
128of the independent variables).
129
130\param var_by_load_op
131is a vector with size play->num_load_op_rec().
132It is the variable index corresponding to each the
133load instruction.
134In the case where the index is zero,
135the instruction corresponds to a parameter (not variable).
136
137*/
138
139template <class Base>
140void forward2sweep(
141        const size_t                q,
142        const size_t                r,
143        const size_t                n,
144        const size_t                numvar,
145              player<Base>*         play,
146        const size_t                J,
147              Base*                 taylor,
148        const bool*                 cskip_op,
149        const pod_vector<addr_t>&   var_by_load_op
150)
151{
152        CPPAD_ASSERT_UNKNOWN( q > 0 );
153        CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
154        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
155
156        // used to avoid compiler errors until all operators are implemented
157        size_t p = q;
158
159        // op code for current instruction
160        OpCode op;
161
162        // index for current instruction
163        size_t i_op;
164
165        // next variables
166        size_t i_var;
167
168        // operation argument indices
169        const addr_t*   arg = CPPAD_NULL;
170
171        // work space used by UserOp.
172        vector<bool> user_vx;        // empty vecotor
173        vector<bool> user_vy;        // empty vecotor
174        vector<Base> user_tx_one;    // argument vector Taylor coefficients
175        vector<Base> user_tx_all;
176        vector<Base> user_ty_one;    // result vector Taylor coefficients
177        vector<Base> user_ty_all;
178        size_t user_index = 0;       // indentifier for this atomic operation
179        size_t user_id    = 0;       // user identifier for this call to operator
180        size_t user_i     = 0;       // index in result vector
181        size_t user_j     = 0;       // index in argument vector
182        size_t user_m     = 0;       // size of result vector
183        size_t user_n     = 0;       // size of arugment vector
184        //
185        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
186# ifndef NDEBUG
187        bool               user_ok   = false;      // atomic op return value
188# endif
189        //
190        // next expected operator in a UserOp sequence
191        enum { user_start, user_arg, user_ret, user_end, user_trace }
192        user_state = user_start;
193
194        // length of the parameter vector (used by CppAD assert macros)
195        const size_t num_par = play->num_par_rec();
196
197        // pointer to the beginning of the parameter vector
198        const Base* parameter = CPPAD_NULL;
199        if( num_par > 0 )
200                parameter = play->GetPar();
201
202        // temporary indices
203        size_t i, j, k, ell;
204
205        // number of orders for this user calculation
206        // (not needed for order zero)
207        const size_t user_q1 = q+1;
208
209        // variable indices for results vector
210        // (done differently for order zero).
211        vector<size_t> user_iy;
212
213        // skip the BeginOp at the beginning of the recording
214        play->forward_start(op, arg, i_op, i_var);
215        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
216# if CPPAD_FORWARD2SWEEP_TRACE
217        std::cout << std::endl;
218        CppAD::vector<Base> Z_vec(q+1);
219# endif
220        bool more_operators = true;
221        while(more_operators)
222        {
223                // this op
224                play->forward_next(op, arg, i_op, i_var);
225                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) );
226                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) );
227                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
228                CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var);
229
230                // check if we are skipping this operation
231                while( cskip_op[i_op] )
232                {       if( op == CSumOp )
233                        {       // CSumOp has a variable number of arguments
234                                play->forward_csum(op, arg, i_op, i_var);
235                        }
236                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
237                        // if( op == CSkipOp )
238                        // {    // CSkip has a variable number of arguments
239                        //      play->forward_cskip(op, arg, i_op, i_var);
240                        // }
241                        play->forward_next(op, arg, i_op, i_var);
242                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
243                }
244
245                // action depends on the operator
246                switch( op )
247                {
248                        case AbsOp:
249                        forward_abs_op_dir(q, r, i_var, arg[0], J, taylor);
250                        break;
251                        // -------------------------------------------------
252
253                        case AddvvOp:
254                        forward_addvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
255                        break;
256                        // -------------------------------------------------
257
258                        case AddpvOp:
259                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
260                        forward_addpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
261                        break;
262                        // -------------------------------------------------
263
264                        case AcosOp:
265                        // sqrt(1 - x * x), acos(x)
266                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
267                        forward_acos_op_dir(q, r, i_var, arg[0], J, taylor);
268                        break;
269                        // -------------------------------------------------
270
271# if CPPAD_COMPILER_HAS_ACOSH
272                        case AcoshOp:
273                        // sqrt(x * x - 1), acosh(x)
274                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
275                        forward_acosh_op_dir(q, r, i_var, arg[0], J, taylor);
276                        break;
277# endif
278                        // -------------------------------------------------
279
280                        case AsinOp:
281                        // sqrt(1 - x * x), asin(x)
282                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
283                        forward_asin_op_dir(q, r, i_var, arg[0], J, taylor);
284                        break;
285                        // -------------------------------------------------
286
287# if CPPAD_COMPILER_HAS_ASINH
288                        case AsinhOp:
289                        // sqrt(1 + x * x), asinh(x)
290                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
291                        forward_asinh_op_dir(q, r, i_var, arg[0], J, taylor);
292                        break;
293# endif
294                        // -------------------------------------------------
295
296                        case AtanOp:
297                        // 1 + x * x, atan(x)
298                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
299                        forward_atan_op_dir(q, r, i_var, arg[0], J, taylor);
300                        break;
301                        // -------------------------------------------------
302
303                        case CExpOp:
304                        forward_cond_op_dir(
305                                q, r, i_var, arg, num_par, parameter, J, taylor
306                        );
307                        break;
308                        // ---------------------------------------------------
309
310                        case CosOp:
311                        // sin(x), cos(x)
312                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
313                        forward_cos_op_dir(q, r, i_var, arg[0], J, taylor);
314                        break;
315                        // ---------------------------------------------------
316
317                        case CoshOp:
318                        // sinh(x), cosh(x)
319                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
320                        forward_cosh_op_dir(q, r, i_var, arg[0], J, taylor);
321                        break;
322                        // -------------------------------------------------
323
324                        case CSkipOp:
325                        // CSkipOp has a variable number of arguments and
326                        // forward_next thinks it has no arguments.
327                        // we must inform forward_next of this special case.
328                        play->forward_cskip(op, arg, i_op, i_var);
329                        break;
330                        // -------------------------------------------------
331
332                        case CSumOp:
333                        // CSumOp has a variable number of arguments and
334                        // forward_next thinks it has no arguments.
335                        // we must inform forward_next of this special case.
336                        forward_csum_op_dir(
337                                q, r, i_var, arg, num_par, parameter, J, taylor
338                        );
339                        play->forward_csum(op, arg, i_op, i_var);
340                        break;
341                        // -------------------------------------------------
342
343                        case DisOp:
344                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
345                        break;
346                        // -------------------------------------------------
347
348                        case DivvvOp:
349                        forward_divvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
350                        break;
351                        // -------------------------------------------------
352
353                        case DivpvOp:
354                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
355                        forward_divpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
356                        break;
357                        // -------------------------------------------------
358
359                        case DivvpOp:
360                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
361                        forward_divvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
362                        break;
363                        // -------------------------------------------------
364
365                        case EndOp:
366                        // needed for sparse_jacobian test
367                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
368                        more_operators = false;
369                        break;
370                        // -------------------------------------------------
371
372                        case ExpOp:
373                        forward_exp_op_dir(q, r, i_var, arg[0], J, taylor);
374                        break;
375                        // -------------------------------------------------
376
377                        case InvOp:
378                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
379                        break;
380                        // -------------------------------------------------
381
382                        case LdpOp:
383                        case LdvOp:
384                        forward_load_op(
385                                play,
386                                op,
387                                p,
388                                q,
389                                r,
390                                J,
391                                i_var,
392                                arg,
393                                var_by_load_op.data(),
394                                taylor
395                        );
396                        break;
397                        // ---------------------------------------------------
398
399                        case EqpvOp:
400                        case EqvvOp:
401                        case LtpvOp:
402                        case LtvpOp:
403                        case LtvvOp:
404                        case LepvOp:
405                        case LevpOp:
406                        case LevvOp:
407                        case NepvOp:
408                        case NevvOp:
409                        CPPAD_ASSERT_UNKNOWN(q > 0 );
410                        break;
411                        // -------------------------------------------------
412
413                        case LogOp:
414                        forward_log_op_dir(q, r, i_var, arg[0], J, taylor);
415                        break;
416                        // ---------------------------------------------------
417
418                        case MulvvOp:
419                        forward_mulvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
420                        break;
421                        // -------------------------------------------------
422
423                        case MulpvOp:
424                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
425                        forward_mulpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
426                        break;
427                        // -------------------------------------------------
428
429                        case ParOp:
430                        k = i_var*(J-1)*r + i_var + (q-1)*r + 1;
431                        for(ell = 0; ell < r; ell++)
432                                taylor[k + ell] = Base(0);
433                        break;
434                        // -------------------------------------------------
435
436                        case PowpvOp:
437                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
438                        forward_powpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
439                        break;
440                        // -------------------------------------------------
441
442                        case PowvpOp:
443                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
444                        forward_powvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
445                        break;
446                        // -------------------------------------------------
447
448                        case PowvvOp:
449                        forward_powvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
450                        break;
451                        // -------------------------------------------------
452
453                        case PriOp:
454                        CPPAD_ASSERT_UNKNOWN(q > 0);
455                        break;
456                        // -------------------------------------------------
457
458                        case SignOp:
459                        // sign(x)
460                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
461                        forward_sign_op_dir(q, r, i_var, arg[0], J, taylor);
462                        break;
463                        // -------------------------------------------------
464
465                        case SinOp:
466                        // cos(x), sin(x)
467                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
468                        forward_sin_op_dir(q, r, i_var, arg[0], J, taylor);
469                        break;
470                        // -------------------------------------------------
471
472                        case SinhOp:
473                        // cosh(x), sinh(x)
474                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
475                        forward_sinh_op_dir(q, r, i_var, arg[0], J, taylor);
476                        break;
477                        // -------------------------------------------------
478
479                        case SqrtOp:
480                        forward_sqrt_op_dir(q, r, i_var, arg[0], J, taylor);
481                        break;
482                        // -------------------------------------------------
483
484                        case StppOp:
485                        case StpvOp:
486                        case StvpOp:
487                        case StvvOp:
488                        CPPAD_ASSERT_UNKNOWN(q > 0 );
489                        break;
490                        // -------------------------------------------------
491
492                        case SubvvOp:
493                        forward_subvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
494                        break;
495                        // -------------------------------------------------
496
497                        case SubpvOp:
498                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
499                        forward_subpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
500                        break;
501                        // -------------------------------------------------
502
503                        case SubvpOp:
504                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
505                        forward_subvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
506                        break;
507                        // -------------------------------------------------
508
509                        case TanOp:
510                        // tan(x)^2, tan(x)
511                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
512                        forward_tan_op_dir(q, r, i_var, arg[0], J, taylor);
513                        break;
514                        // -------------------------------------------------
515
516                        case TanhOp:
517                        // tanh(x)^2, tanh(x)
518                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
519                        forward_tanh_op_dir(q, r, i_var, arg[0], J, taylor);
520                        break;
521                        // -------------------------------------------------
522
523                        case UserOp:
524                        // start or end an atomic operation sequence
525                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
526                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
527                        if( user_state == user_start )
528                        {       user_index = arg[0];
529                                user_id    = arg[1];
530                                user_n     = arg[2];
531                                user_m     = arg[3];
532                                user_atom  = atomic_base<Base>::class_object(user_index);
533# ifndef NDEBUG
534                                if( user_atom == CPPAD_NULL )
535                                {       std::string msg =
536                                                atomic_base<Base>::class_name(user_index)
537                                                + ": atomic_base function has been deleted";
538                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
539                                }
540# endif
541                                if(user_tx_one.size() != user_n * user_q1)
542                                        user_tx_one.resize(user_n * user_q1);
543                                if( user_tx_all.size() != user_n * (q * r + 1) )
544                                        user_tx_all.resize(user_n * (q * r + 1));
545                                //
546                                if(user_ty_one.size() != user_m * user_q1)
547                                        user_ty_one.resize(user_m * user_q1);
548                                if( user_ty_all.size() != user_m * (q * r + 1) )
549                                        user_ty_all.resize(user_m * (q * r + 1));
550                                //
551                                if(user_iy.size() != user_m)
552                                        user_iy.resize(user_m);
553                                user_j     = 0;
554                                user_i     = 0;
555                                user_state = user_arg;
556                        }
557                        else
558                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
559                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
560                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
561                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
562                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
563
564                                // call users function for this operation
565                                user_atom->set_id(user_id);
566                                for(ell = 0; ell < r; ell++)
567                                {       // set user_tx
568                                        for(j = 0; j < user_n; j++)
569                                        {       size_t j_all     = j * (q * r + 1);
570                                                size_t j_one     = j * user_q1;
571                                                user_tx_one[j_one+0] = user_tx_all[j_all+0];
572                                                for(k = 1; k < user_q1; k++)
573                                                {       size_t k_all       = j_all + (k-1)*r+1+ell;
574                                                        size_t k_one       = j_one + k;
575                                                        user_tx_one[k_one] = user_tx_all[k_all];
576                                                }
577                                        }
578                                        // set user_ty
579                                        for(i = 0; i < user_m; i++)
580                                        {       size_t i_all     = i * (q * r + 1);
581                                                size_t i_one     = i * user_q1;
582                                                user_ty_one[i_one+0] = user_ty_all[i_all+0];
583                                                for(k = 1; k < q; k++)
584                                                {       size_t k_all       = i_all + (k-1)*r+1+ell;
585                                                        size_t k_one       = i_one + k;
586                                                        user_ty_one[k_one] = user_ty_all[k_all];
587                                                }
588                                        }
589                                        CPPAD_ATOMIC_CALL(
590                                        q, q, user_vx, user_vy, user_tx_one, user_ty_one
591                                        );
592# ifndef NDEBUG
593                                        if( ! user_ok )
594                                        {       std::string msg =
595                                                        atomic_base<Base>::class_name(user_index)
596                                                        + ": atomic_base.forward: returned false";
597                                                CPPAD_ASSERT_KNOWN(false, msg.c_str() );
598                                        }
599# endif
600                                        for(i = 0; i < user_m; i++)
601                                        {       if( user_iy[i] > 0 )
602                                                {       size_t i_taylor = user_iy[i]*((J-1)*r+1);
603                                                        size_t q_taylor = i_taylor + (q-1)*r+1+ell;
604                                                        size_t q_one    = i * user_q1 + q;
605                                                        taylor[q_taylor] = user_ty_one[q_one];
606                                                }
607                                        }
608                                }
609# if CPPAD_FORWARD2SWEEP_TRACE
610                                user_state = user_trace;
611# else
612                                user_state = user_start;
613# endif
614                        }
615                        break;
616
617                        case UsrapOp:
618                        // parameter argument in an atomic operation sequence
619                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
620                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
621                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
622                        user_tx_all[user_j*(q*r+1) + 0] = parameter[ arg[0]];
623                        for(ell = 0; ell < r; ell++)
624                                for(k = 1; k < user_q1; k++)
625                                        user_tx_all[user_j*(q*r+1) + (k-1)*r+1+ell] = Base(0);
626                        ++user_j;
627                        if( user_j == user_n )
628                                user_state = user_ret;
629                        break;
630
631                        case UsravOp:
632                        // variable argument in an atomic operation sequence
633                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
634                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
635                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
636                        user_tx_all[user_j*(q*r+1)+0] = taylor[arg[0]*((J-1)*r+1)+0];
637                        for(ell = 0; ell < r; ell++)
638                        {       for(k = 1; k < user_q1; k++)
639                                {       user_tx_all[user_j*(q*r+1) + (k-1)*r+1+ell] =
640                                                taylor[arg[0]*((J-1)*r+1) + (k-1)*r+1+ell];
641                                }
642                        }
643                        ++user_j;
644                        if( user_j == user_n )
645                                user_state = user_ret;
646                        break;
647
648                        case UsrrpOp:
649                        // parameter result in an atomic operation sequence
650                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
651                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
652                        user_iy[user_i] = 0;
653                        user_ty_all[user_i*(q*r+1) + 0] = parameter[ arg[0]];
654                        for(ell = 0; ell < r; ell++)
655                                for(k = 1; k < user_q1; k++)
656                                        user_ty_all[user_i*(q*r+1) + (k-1)*r+1+ell] = Base(0);
657                        user_i++;
658                        if( user_i == user_m )
659                                user_state = user_end;
660                        break;
661
662                        case UsrrvOp:
663                        // variable result in an atomic operation sequence
664                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
665                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
666                        user_iy[user_i] = i_var;
667                        user_ty_all[user_i*(q*r+1)+0] = taylor[i_var*((J-1)*r+1)+0];
668                        for(ell = 0; ell < r; ell++)
669                        {       for(k = 1; k < user_q1; k++)
670                                {       user_ty_all[user_i*(q*r+1) + (k-1)*r+1+ell] =
671                                                taylor[i_var*((J-1)*r+1) + (k-1)*r+1+ell];
672                                }
673                        }
674                        user_i++;
675                        if( user_i == user_m )
676                                user_state = user_end;
677                        break;
678                        // -------------------------------------------------
679
680                        default:
681                        CPPAD_ASSERT_UNKNOWN(0);
682                }
683# if CPPAD_FORWARD2SWEEP_TRACE
684                if( user_state == user_trace )
685                {       user_state = user_start;
686                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
687                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
688                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
689                        {       size_t i_tmp   = (i_op + i) - user_m;
690                                printOp(
691                                        std::cout,
692                                        play,
693                                        i_tmp,
694                                        user_iy[i],
695                                        UsrrvOp,
696                                        CPPAD_NULL
697                                );
698                                Base* Z_tmp = taylor + user_iy[i]*((J-1) * r + 1);
699                                {       Z_vec[0]    = Z_tmp[0];
700                                        for(ell = 0; ell < r; ell++)
701                                        {       std::cout << std::endl << "     ";
702                                                for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)
703                                                        Z_vec[p_tmp] = Z_tmp[(p_tmp-1)*r+ell+1];
704                                                printOpResult(
705                                                        std::cout,
706                                                        q + 1,
707                                                        Z_vec.data(),
708                                                        0,
709                                                        (Base *) CPPAD_NULL
710                                                );
711                                        }
712                                }
713                                std::cout << std::endl;
714                        }
715                }
716                const addr_t*   arg_tmp = arg;
717                if( op == CSumOp )
718                        arg_tmp = arg - arg[-1] - 4;
719                if( op == CSkipOp )
720                        arg_tmp = arg - arg[-1] - 7;
721                if( op != UsrrvOp )
722                {       printOp(
723                                std::cout,
724                                play,
725                                i_op,
726                                i_var,
727                                op,
728                                arg_tmp
729                        );
730                        Base* Z_tmp = CPPAD_NULL;
731                        if( op == UsravOp )
732                                Z_tmp = taylor + arg[0]*((J-1) * r + 1);
733                        else if( NumRes(op) > 0 )
734                                Z_tmp = taylor + i_var*((J-1)*r + 1);
735                        if( Z_tmp != CPPAD_NULL )
736                        {       Z_vec[0]    = Z_tmp[0];
737                                for(ell = 0; ell < r; ell++)
738                                {       std::cout << std::endl << "     ";
739                                        for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)
740                                                Z_vec[p_tmp] = Z_tmp[ (p_tmp-1)*r + ell + 1];
741                                        printOpResult(
742                                                std::cout,
743                                                q + 1,
744                                                Z_vec.data(),
745                                                0,
746                                                (Base *) CPPAD_NULL
747                                        );
748                                }
749                        }
750                        std::cout << std::endl;
751                }
752        }
753        std::cout << std::endl;
754# else
755        }
756# endif
757        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
758        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
759
760        return;
761}
762
763// preprocessor symbols that are local to this file
764# undef CPPAD_FORWARD2SWEEP_TRACE
765# undef CPPAD_ATOMIC_CALL
766
767} // END_CPPAD_NAMESPACE
768# endif
Note: See TracBrowser for help on using the repository browser.