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