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