source: trunk/cppad/local/forward2sweep.hpp @ 3607

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

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

commit 894d554a00ceec8a3545f05eca62708a7b5cb43d
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 09:06:10 2015 -0700

Fix copyright end date.


whats_new_15.omh: Add comment about date of deprecation.

commit 611e982000168db91aba22b763c14bb78d57da47
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 08:53:00 2015 -0700

Squashed commit from old/compare_op to master:


In addition, fix copyright end date for some files, and add note about
deprecated date in whats_new_15.omh.


commit 6e46df5c850ecd58d7a886db4043bc3f2d4579d1
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 08:16:57 2015 -0700


Always return f.compare_change_op_index() == 0 after f.optimize().


checkpoint.hpp: ignore comparison operators.
fun_construct.hpp: remove double initilaization of values.
compare_change.cpp: demonstrate more features of new interface.
whats_new_15.omh: prepare for merging this branch into master.
wish_list.omh: update wish list item to new compare_change interface.


commit 45315907c70e5b383d984fb9498b54a474001af0
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 05:04:37 2015 -0700


Use the new f.compare_change_count(0) option in speed tests.


commit bb6e72befd6d01f1fb62c43b9b19471ffaa7cc2c
Author: Brad Bell <bradbell@…>
Date: Tue Jan 20 04:51:16 2015 -0700


Move CompareChange? -> deprecated and plan -> compare_change.


forward0sweep.hpp: skip comparison operator when count is zero.
forward1sweep.hpp: skip comparison operator when count is zero.
compare_change.cpp: demonstrate count == 0 case.


commit 622a13c568c612d9dfe9ccd1a01f4ac5f74ba824
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 23:17:42 2015 -0700


Add example and test of new compare change user API.


ad_fun.hpp: fix f.compare_change_op_index.
compare_change.cpp: Change example to use new API.
compare_change.cpp: Move old example here (just test now).


commit ec4c1613eae8df56fbf31e7b8711ce69cc41df83
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 21:12:11 2015 -0700


Implement the compare change plan, still needs an example and test.
Also have the change from 'plan' to just plain documentation.


commit a81a46f27011bee08ba072551044dc9f4a99a906
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 17:49:05 2015 -0700


Change name of compare_change functions and partially implement this new plan.


commit 146faad48a700a56362e74f9c3a3c39144a79738
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 14:22:40 2015 -0700


Branch: compare_op
plan.omh: change name of count function.


commit 35d91d126765d1a0ab4bfe9e2b006bbf535cd648
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 13:19:07 2015 -0700


Add deprecation date for some more cases.


commit 5bb65a8c48fae4263b66fcd04520e10e66febc11
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 13:13:51 2015 -0700


Add date of deprecation for some more cases.


commit e95ee6b209601cd9a075d2e37c602e73c32fb6ab
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 12:58:44 2015 -0700


Add date of deprecation for some more cases.


commit 0ea84ccd87383edc62a6ae1711da104b12e8c444
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 12:47:01 2015 -0700


Add date of deprecation for some cases.


commit 17755e609ea8e03472b08dcc2fb5ad347eb723cb
Author: Brad Bell <bradbell@…>
Date: Mon Jan 19 08:20:45 2015 -0700


plan.omh: changs some names.


commit 29f369c06d4d0ee284c4c668d52d8461613066dc
Author: Brad Bell <bradbell@…>
Date: Fri Jan 16 06:39:45 2015 -0700


Document the plan for compare_change user API.


compare_change.omh: fix minor typo.
plan.txt: change to the omhelp file plan.omh.


commit a3a2f4dedd202a722812b6eb2714851b40726e6e
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 21:03:44 2015 -0700


new_branch.sh: remove unused variable.
push_git2svn.py: move repository from github/bradbell to coin-or/bradbell.


commit 3751a197ab2897e76616f9d9b0915148bd855356
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 20:56:17 2015 -0700


plan.txt: plan for this branches API will go here.


commit 76013ec2ad7baacdeab5e761812d542867910174
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 18:04:33 2015 -0700


Store the operator index for the first comparision change in the ADFun object.


commit 9caf25014079a60df5de17bcac76775daf8ee201
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 12:45:56 2015 -0700


Make compare_change a parameter (so will be easy to add compare_first).


commit 2246d22fe82b8909d432f82ab0d783ce3351a02f
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 09:12:40 2015 -0700


speed_branch.sh: fix directory (before cd).


commit b3910de86558a97749741bfb728e45c5a86d1c73
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 05:14:01 2015 -0700


search.sh: use git to get list of source files.
ad_fun.hpp: imporve doxygen doc for compare_change_.
ad_tape.hpp: remove RecordCompare? (no longer used).
atomic_base.hpp: minor edit to user documentation.


commit dd74f331386cadc9cc272c264296e575691aa3f8
Author: Brad Bell <bradbell@…>
Date: Thu Jan 15 04:12:34 2015 -0700


Change Leq..Op -> Le..Op and leq.._op -> le.._op.


commit ae729296323eb7f4f4a7c0e90a303a8d7f4ed42a
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 21:19:55 2015 -0700


comp_op.hpp: Add doxygen documentaiton for compare operators.
compare.hpp: avoid an extra branch.


commit b064d59a5ad01dff5c708cc8c02f628f58c863ec
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 16:11:25 2015 -0700


Remove ComOp?, replaced by specific cases Eq..Op, Ne..Op, Leq..Op, Lt..Op,
which should run faster.


forward0sweep.hpp: Remove out-dated comment about CompOp?.
forward1sweep.hpp: Remove out-dated comment about CompOp?.


commit 5bb0a70d1151e9086b88024050cea6cf11e83aa7
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 09:02:17 2015 -0700


Use Eq..Op, Ne..Op to implement == and !=.


commit 0ebeec61bc040a00c50db41ca5da31fb87194f93
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 07:19:26 2015 -0700


compare.hpp: Finish folding < <= > >= into Lt..Op and Leq..Op.


commit c949e5b72158b98cbab61c8aea98e76008e9c2f4
Author: Brad Bell <bradbell@…>
Date: Wed Jan 14 06:28:41 2015 -0700


  1. Change plan to fold all compare operations into Leq..Op and Lt..Op cases.
  2. Fix alphabetical order between Ld and Leq.


commit 6ffee88b68b682359d62bc75a8c2ba3e28d012ac
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 22:40:18 2015 -0700


Splite parameter <= variable and parameter > variable as separate compare
operators.


commit 0841014db4ead690d1c2358f5e09494030ae1e5f
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 21:12:57 2015 -0700


Attempting to recording and playback of compare operators faster:
Split variable <= variable and variable > variable out as separate cases.


compare.hpp: remove white space at end of lines.


commit cfd3afceebd4b3383b3042cbca98caf82ff77670
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 08:39:12 2015 -0700


speed_branch.sh: compare speed_cppad between two git branches.
speed_new.sh: correct list of options, remove unused variable.
wish_list.omh: correct discussion of effect of keeping compare operators.


commit 9ed03e1ee2c258ca38561ad083067e235d032e14
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:54:30 2015 -0700


Change test so it corresponds to optimization keeping compare operators.


commit 5c418d477d58984b094bba027ebb0794e759e557
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 05:12:50 2015 -0700


Include example and test of using CompareChange? with optimized tape.


commit c1b48edfa56ca096ce8c2db1dbadb2658cb13fe3
Author: Brad Bell <bradbell@…>
Date: Tue Jan 13 04:24:54 2015 -0700


Fix optimization so variables used in compare opertions are alwasy available.


commit 6fe607ca30db07b356fd3a9fe9779fa2dfd382d8
Author: Brad Bell <bradbell@…>
Date: Mon Jan 12 07:56:41 2015 -0700


Keep CompareChange? in optimized versions of tape and when NDEBUG is defined.

commit b4c0e51489cc0878499a331b4af4875b2781d8d8
Author: Brad Bell <bradbell@…>
Date: Sun Jan 11 17:01:59 2015 -0700

new_branch.sh: final procedure (only hand tested).

  • Property svn:keywords set to Id
File size: 21.2 KB
Line 
1/* $Id: forward2sweep.hpp 3607 2015-01-20 16:20:41Z 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                        case AsinOp:
272                        // sqrt(1 - x * x), asin(x)
273                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
274                        forward_asin_op_dir(q, r, i_var, arg[0], J, taylor);
275                        break;
276                        // -------------------------------------------------
277
278                        case AtanOp:
279                        // 1 + x * x, atan(x)
280                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
281                        forward_atan_op_dir(q, r, i_var, arg[0], J, taylor);
282                        break;
283                        // -------------------------------------------------
284
285                        case CExpOp:
286                        forward_cond_op_dir(
287                                q, r, i_var, arg, num_par, parameter, J, taylor
288                        );
289                        break;
290                        // ---------------------------------------------------
291
292                        case CosOp:
293                        // sin(x), cos(x)
294                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
295                        forward_cos_op_dir(q, r, i_var, arg[0], J, taylor);
296                        break;
297                        // ---------------------------------------------------
298
299                        case CoshOp:
300                        // sinh(x), cosh(x)
301                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
302                        forward_cosh_op_dir(q, r, i_var, arg[0], J, taylor);
303                        break;
304                        // -------------------------------------------------
305
306                        case CSkipOp:
307                        // CSkipOp has a variable number of arguments and
308                        // forward_next thinks it has no arguments.
309                        // we must inform forward_next of this special case.
310                        play->forward_cskip(op, arg, i_op, i_var);
311                        break;
312                        // -------------------------------------------------
313
314                        case CSumOp:
315                        // CSumOp has a variable number of arguments and
316                        // forward_next thinks it has no arguments.
317                        // we must inform forward_next of this special case.
318                        forward_csum_op_dir(
319                                q, r, i_var, arg, num_par, parameter, J, taylor
320                        );
321                        play->forward_csum(op, arg, i_op, i_var);
322                        break;
323                        // -------------------------------------------------
324
325                        case DisOp:
326                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
327                        break;
328                        // -------------------------------------------------
329
330                        case DivvvOp:
331                        forward_divvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
332                        break;
333                        // -------------------------------------------------
334
335                        case DivpvOp:
336                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
337                        forward_divpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
338                        break;
339                        // -------------------------------------------------
340
341                        case DivvpOp:
342                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
343                        forward_divvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
344                        break;
345                        // -------------------------------------------------
346
347                        case EndOp:
348                        // needed for sparse_jacobian test
349                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
350                        more_operators = false;
351                        break;
352                        // -------------------------------------------------
353
354                        case ExpOp:
355                        forward_exp_op_dir(q, r, i_var, arg[0], J, taylor);
356                        break;
357                        // -------------------------------------------------
358
359                        case InvOp:
360                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
361                        break;
362                        // -------------------------------------------------
363
364                        case LdpOp:
365                        case LdvOp:
366                        forward_load_op(
367                                play,
368                                op,
369                                p,
370                                q,
371                                r,
372                                J,
373                                i_var,
374                                arg,
375                                var_by_load_op.data(),
376                                taylor
377                        );
378                        break;
379                        // ---------------------------------------------------
380
381                        case EqpvOp:
382                        case EqvvOp:
383                        case LtpvOp:
384                        case LtvpOp:
385                        case LtvvOp:
386                        case LepvOp:
387                        case LevpOp:
388                        case LevvOp:
389                        case NepvOp:
390                        case NevvOp:
391                        CPPAD_ASSERT_UNKNOWN(q > 0 );
392                        break;
393                        // -------------------------------------------------
394
395                        case LogOp:
396                        forward_log_op_dir(q, r, i_var, arg[0], J, taylor);
397                        break;
398                        // ---------------------------------------------------
399
400                        case MulvvOp:
401                        forward_mulvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
402                        break;
403                        // -------------------------------------------------
404
405                        case MulpvOp:
406                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
407                        forward_mulpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
408                        break;
409                        // -------------------------------------------------
410
411                        case ParOp:
412                        k = i_var*(J-1)*r + i_var + (q-1)*r + 1;
413                        for(ell = 0; ell < r; ell++)
414                                taylor[k + ell] = Base(0); 
415                        break;
416                        // -------------------------------------------------
417
418                        case PowpvOp:
419                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
420                        forward_powpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
421                        break;
422                        // -------------------------------------------------
423
424                        case PowvpOp:
425                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
426                        forward_powvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
427                        break;
428                        // -------------------------------------------------
429
430                        case PowvvOp:
431                        forward_powvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
432                        break;
433                        // -------------------------------------------------
434
435                        case PriOp:
436                        CPPAD_ASSERT_UNKNOWN(q > 0);
437                        break;
438                        // -------------------------------------------------
439
440                        case SignOp:
441                        // sign(x)
442                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
443                        forward_sign_op_dir(q, r, i_var, arg[0], J, taylor);
444                        break;
445                        // -------------------------------------------------
446
447                        case SinOp:
448                        // cos(x), sin(x)
449                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
450                        forward_sin_op_dir(q, r, i_var, arg[0], J, taylor);
451                        break;
452                        // -------------------------------------------------
453
454                        case SinhOp:
455                        // cosh(x), sinh(x)
456                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
457                        forward_sinh_op_dir(q, r, i_var, arg[0], J, taylor);
458                        break;
459                        // -------------------------------------------------
460
461                        case SqrtOp:
462                        forward_sqrt_op_dir(q, r, i_var, arg[0], J, taylor);
463                        break;
464                        // -------------------------------------------------
465
466                        case StppOp:
467                        case StpvOp:
468                        case StvpOp:
469                        case StvvOp:
470                        CPPAD_ASSERT_UNKNOWN(q > 0 );
471                        break;
472                        // -------------------------------------------------
473
474                        case SubvvOp:
475                        forward_subvv_op_dir(q, r, i_var, arg, parameter, J, taylor);
476                        break;
477                        // -------------------------------------------------
478
479                        case SubpvOp:
480                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
481                        forward_subpv_op_dir(q, r, i_var, arg, parameter, J, taylor);
482                        break;
483                        // -------------------------------------------------
484
485                        case SubvpOp:
486                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
487                        forward_subvp_op_dir(q, r, i_var, arg, parameter, J, taylor);
488                        break;
489                        // -------------------------------------------------
490
491                        case TanOp:
492                        // tan(x)^2, tan(x)
493                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
494                        forward_tan_op_dir(q, r, i_var, arg[0], J, taylor);
495                        break;
496                        // -------------------------------------------------
497
498                        case TanhOp:
499                        // tanh(x)^2, tanh(x)
500                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
501                        forward_tanh_op_dir(q, r, i_var, arg[0], J, taylor);
502                        break;
503                        // -------------------------------------------------
504
505                        case UserOp:
506                        // start or end an atomic operation sequence
507                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
508                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
509                        if( user_state == user_start )
510                        {       user_index = arg[0];
511                                user_id    = arg[1];
512                                user_n     = arg[2];
513                                user_m     = arg[3];
514                                user_atom  = atomic_base<Base>::class_object(user_index);
515# ifndef NDEBUG
516                                if( user_atom == CPPAD_NULL )
517                                {       std::string msg = 
518                                                atomic_base<Base>::class_name(user_index)
519                                                + ": atomic_base function has been deleted";
520                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
521                                }
522# endif
523                                if(user_tx_one.size() != user_n * user_q1)
524                                        user_tx_one.resize(user_n * user_q1);
525                                if( user_tx_all.size() != user_n * (q * r + 1) )
526                                        user_tx_all.resize(user_n * (q * r + 1));
527                                //
528                                if(user_ty_one.size() != user_m * user_q1)
529                                        user_ty_one.resize(user_m * user_q1);
530                                if( user_ty_all.size() != user_m * (q * r + 1) )
531                                        user_ty_all.resize(user_m * (q * r + 1));
532                                //
533                                if(user_iy.size() != user_m)
534                                        user_iy.resize(user_m);
535                                user_j     = 0;
536                                user_i     = 0;
537                                user_state = user_arg;
538                        }
539                        else
540                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
541                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
542                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
543                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
544                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
545
546                                // call users function for this operation
547                                user_atom->set_id(user_id);
548                                for(ell = 0; ell < r; ell++)
549                                {       // set user_tx
550                                        for(j = 0; j < user_n; j++)
551                                        {       size_t j_all     = j * (q * r + 1);
552                                                size_t j_one     = j * user_q1;
553                                                user_tx_one[j_one+0] = user_tx_all[j_all+0];
554                                                for(k = 1; k < user_q1; k++)
555                                                {       size_t k_all       = j_all + (k-1)*r+1+ell;
556                                                        size_t k_one       = j_one + k;
557                                                        user_tx_one[k_one] = user_tx_all[k_all];
558                                                }
559                                        }
560                                        // set user_ty
561                                        for(i = 0; i < user_m; i++)
562                                        {       size_t i_all     = i * (q * r + 1);
563                                                size_t i_one     = i * user_q1;
564                                                user_ty_one[i_one+0] = user_ty_all[i_all+0];
565                                                for(k = 1; k < q; k++)
566                                                {       size_t k_all       = i_all + (k-1)*r+1+ell;
567                                                        size_t k_one       = i_one + k;
568                                                        user_ty_one[k_one] = user_ty_all[k_all];
569                                                }
570                                        }
571                                        CPPAD_ATOMIC_CALL(
572                                        q, q, user_vx, user_vy, user_tx_one, user_ty_one
573                                        );
574# ifndef NDEBUG
575                                        if( ! user_ok )
576                                        {       std::string msg = 
577                                                        atomic_base<Base>::class_name(user_index)
578                                                        + ": atomic_base.forward: returned false";
579                                                CPPAD_ASSERT_KNOWN(false, msg.c_str() );
580                                        }
581# endif
582                                        for(i = 0; i < user_m; i++) 
583                                        {       if( user_iy[i] > 0 )
584                                                {       size_t i_taylor = user_iy[i]*((J-1)*r+1); 
585                                                        size_t q_taylor = i_taylor + (q-1)*r+1+ell;
586                                                        size_t q_one    = i * user_q1 + q;
587                                                        taylor[q_taylor] = user_ty_one[q_one];
588                                                }
589                                        }
590                                }
591# if CPPAD_FORWARD2SWEEP_TRACE
592                                user_state = user_trace;
593# else
594                                user_state = user_start;
595# endif
596                        }
597                        break;
598
599                        case UsrapOp:
600                        // parameter argument in an atomic operation sequence
601                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
602                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
603                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
604                        user_tx_all[user_j*(q*r+1) + 0] = parameter[ arg[0]];
605                        for(ell = 0; ell < r; ell++)
606                                for(k = 1; k < user_q1; k++)
607                                        user_tx_all[user_j*(q*r+1) + (k-1)*r+1+ell] = Base(0);
608                        ++user_j;
609                        if( user_j == user_n )
610                                user_state = user_ret;
611                        break;
612
613                        case UsravOp:
614                        // variable argument in an atomic operation sequence
615                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
616                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
617                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
618                        user_tx_all[user_j*(q*r+1)+0] = taylor[arg[0]*((J-1)*r+1)+0];
619                        for(ell = 0; ell < r; ell++)
620                        {       for(k = 1; k < user_q1; k++)
621                                {       user_tx_all[user_j*(q*r+1) + (k-1)*r+1+ell] = 
622                                                taylor[arg[0]*((J-1)*r+1) + (k-1)*r+1+ell];
623                                }
624                        }
625                        ++user_j;
626                        if( user_j == user_n )
627                                user_state = user_ret;
628                        break;
629
630                        case UsrrpOp:
631                        // parameter result in an atomic operation sequence
632                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
633                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
634                        user_iy[user_i] = 0;
635                        user_ty_all[user_i*(q*r+1) + 0] = parameter[ arg[0]];
636                        for(ell = 0; ell < r; ell++)
637                                for(k = 1; k < user_q1; k++)
638                                        user_ty_all[user_i*(q*r+1) + (k-1)*r+1+ell] = Base(0);
639                        user_i++;
640                        if( user_i == user_m )
641                                user_state = user_end;
642                        break;
643
644                        case UsrrvOp:
645                        // variable result in an atomic operation sequence
646                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
647                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
648                        user_iy[user_i] = i_var;
649                        user_ty_all[user_i*(q*r+1)+0] = taylor[i_var*((J-1)*r+1)+0];
650                        for(ell = 0; ell < r; ell++)
651                        {       for(k = 1; k < user_q1; k++)
652                                {       user_ty_all[user_i*(q*r+1) + (k-1)*r+1+ell] = 
653                                                taylor[i_var*((J-1)*r+1) + (k-1)*r+1+ell];
654                                }
655                        }
656                        user_i++;
657                        if( user_i == user_m )
658                                user_state = user_end;
659                        break;
660                        // -------------------------------------------------
661
662                        default:
663                        CPPAD_ASSERT_UNKNOWN(0);
664                }
665# if CPPAD_FORWARD2SWEEP_TRACE
666                if( user_state == user_trace )
667                {       user_state = user_start;
668                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
669                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
670                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
671                        {       size_t i_tmp   = (i_op + i) - user_m;
672                                printOp(
673                                        std::cout, 
674                                        play,
675                                        i_tmp,
676                                        user_iy[i],
677                                        UsrrvOp, 
678                                        CPPAD_NULL
679                                );
680                                Base* Z_tmp = taylor + user_iy[i]*((J-1) * r + 1);
681                                {       Z_vec[0]    = Z_tmp[0];
682                                        for(ell = 0; ell < r; ell++)
683                                        {       std::cout << std::endl << "     ";
684                                                for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)
685                                                        Z_vec[p_tmp] = Z_tmp[(p_tmp-1)*r+ell+1];
686                                                printOpResult(
687                                                        std::cout, 
688                                                        q + 1, 
689                                                        Z_vec.data(),
690                                                        0, 
691                                                        (Base *) CPPAD_NULL
692                                                );
693                                        }
694                                }
695                                std::cout << std::endl;
696                        }
697                }
698                const addr_t*   arg_tmp = arg;
699                if( op == CSumOp )
700                        arg_tmp = arg - arg[-1] - 4;
701                if( op == CSkipOp )
702                        arg_tmp = arg - arg[-1] - 7;
703                if( op != UsrrvOp )
704                {       printOp(
705                                std::cout, 
706                                play,
707                                i_op,
708                                i_var,
709                                op, 
710                                arg_tmp
711                        );
712                        Base* Z_tmp = CPPAD_NULL;
713                        if( op == UsravOp )
714                                Z_tmp = taylor + arg[0]*((J-1) * r + 1);
715                        else if( NumRes(op) > 0 )
716                                Z_tmp = taylor + i_var*((J-1)*r + 1);
717                        if( Z_tmp != CPPAD_NULL )
718                        {       Z_vec[0]    = Z_tmp[0];
719                                for(ell = 0; ell < r; ell++)
720                                {       std::cout << std::endl << "     ";
721                                        for(size_t p_tmp = 1; p_tmp <= q; p_tmp++)
722                                                Z_vec[p_tmp] = Z_tmp[ (p_tmp-1)*r + ell + 1];
723                                        printOpResult(
724                                                std::cout, 
725                                                q + 1, 
726                                                Z_vec.data(),
727                                                0, 
728                                                (Base *) CPPAD_NULL
729                                        );
730                                }
731                        }
732                        std::cout << std::endl;
733                }
734        }
735        std::cout << std::endl;
736# else
737        }
738# endif
739        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
740        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
741
742        return;
743}
744
745// preprocessor symbols that are local to this file
746# undef CPPAD_FORWARD2SWEEP_TRACE
747# undef CPPAD_ATOMIC_CALL
748
749} // END_CPPAD_NAMESPACE
750# endif
Note: See TracBrowser for help on using the repository browser.