source: trunk/cppad/local/reverse_sweep.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: 20.8 KB
Line 
1/* $Id: reverse_sweep.hpp 3607 2015-01-20 16:20:41Z bradbell $ */
2# ifndef CPPAD_REVERSE_SWEEP_INCLUDED
3# define CPPAD_REVERSE_SWEEP_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
16
17namespace CppAD { // BEGIN_CPPAD_NAMESPACE
18/*!
19\file reverse_sweep.hpp
20Compute derivatives of arbitrary order Taylor coefficients.
21*/
22
23/*
24\def CPPAD_ATOMIC_CALL
25This avoids warnings when NDEBUG is defined and user_ok is not used.
26If \c NDEBUG is defined, this resolves to
27\code
28        user_atom->reverse
29\endcode
30otherwise, it respolves to
31\code
32        user_ok = user_atom->reverse
33\endcode
34This maco is undefined at the end of this file to facillitate is
35use with a different definition in other files.
36*/
37# ifdef NDEBUG
38# define CPPAD_ATOMIC_CALL user_atom->reverse
39# else
40# define CPPAD_ATOMIC_CALL user_ok = user_atom->reverse
41# endif
42
43/*!
44\def CPPAD_REVERSE_SWEEP_TRACE
45This value is either zero or one.
46Zero is the normal operational value.
47If it is one, a trace of every reverse_sweep computation is printed.
48*/
49# define CPPAD_REVERSE_SWEEP_TRACE 0
50
51/*!
52Compute derivative of arbitrary order forward mode Taylor coefficients.
53
54\tparam Base
55base type for the operator; i.e., this operation sequence was recorded
56using AD< \a Base > and computations by this routine are done using type
57\a Base.
58
59\param d
60is the highest order Taylor coefficients that
61we are computing the derivative of.
62
63\param n
64is the number of independent variables on the tape.
65
66\param numvar
67is the total number of variables on the tape.
68This is also equal to the number of rows in the matrix \a Taylor; i.e.,
69play->num_var_rec().
70
71\param play
72The information stored in \a play
73is a recording of the operations corresponding to the function
74\f[
75        F : {\bf R}^n \rightarrow {\bf R}^m
76\f]
77where \f$ n \f$ is the number of independent variables and
78\f$ m \f$ is the number of dependent variables.
79We define \f$ u^{(k)} \f$ as the value of <code>x_k</code> in the previous call
80of the form
81<code>
82        f.Forward(k, x_k)
83</code>
84We define
85\f$ X : {\bf R}^{n \times d} \rightarrow {\bf R}^n \f$ by
86\f[
87        X(t, u) =  u^{(0)} + u^{(1)} t + \cdots + u^{(d)} t^d
88\f]
89We define
90\f$ Y : {\bf R}^{n \times d} \rightarrow {\bf R}^m \f$ by
91\f[
92        Y(t, u) =  F[ X(t, u) ]
93\f]
94We define the function
95\f$ W : {\bf R}^{n \times d} \rightarrow {\bf R} \f$ by
96\f[
97W(u)
98=
99\sum_{k=0}^{d} ( w^{(k)} )^{\rm T}
100        \frac{1}{k !} \frac{\partial^k}{\partial t^k} Y(0, u)
101\f]
102(The matrix \f$ w \in {\bf R}^m \f$,
103is defined below under the heading Partial.)
104Note that the scale factor  1 / k  converts
105the k-th partial derivative to the k-th order Taylor coefficient.
106This routine computes the derivative of \f$ W(u) \f$
107with respect to all the Taylor coefficients
108\f$ u^{(k)} \f$ for \f$ k = 0 , ... , d \f$.
109\n
110\n
111The object \a play is effectly constant.
112There is an exception to this,
113while palying back the tape
114the object \a play holds information about the current location
115with in the tape and this changes during palyback.
116
117\param J
118Is the number of columns in the coefficient matrix \a Taylor.
119This must be greater than or equal \a d + 1.
120
121\param Taylor
122For i = 1 , ... , \a numvar, and for k = 0 , ... , \a d,
123\a Taylor [ i * J + k ]
124is the k-th order Taylor coefficient corresponding to
125variable with index i on the tape.
126The value \f$ u \in {\bf R}^{n \times d} \f$,
127at which the derivative is computed,
128is defined by
129\f$ u_j^{(k)} \f$ = \a Taylor [ j * J + k ]
130for j = 1 , ... , \a n, and for k = 0 , ... , \a d.
131
132\param K
133Is the number of columns in the partial derivative matrix \a Partial.
134It must be greater than or equal \a d + 1.
135
136\param Partial
137\b Input:
138The last \f$ m \f$ rows of \a Partial are inputs.
139The matrix \f$ w \f$, used to define \f$ W(u) \f$,
140is specified by these rows.
141For i = 0 , ... , m - 1,
142for k = 0 , ... , d,
143<code>Partial [ (numvar - m + i ) * K + k ] = w[i,k]</code>.
144\n
145\n
146\b Temporary:
147For i = n+1 , ... , \a numvar - 1 and for k = 0 , ... , d,
148the value of \a Partial [ i * K + k ] is used for temporary work space
149and its output value is not defined.
150\n
151\n
152\b Output:
153For j = 1 , ... , n and for k = 0 , ... , d,
154\a Partial [ j * K + k ]
155is the partial derivative of \f$ W( u ) \f$ with
156respect to \f$ u_j^{(k)} \f$.
157
158\param cskip_op
159Is a vector with size play->num_op_rec().
160If cskip_op[i] is true, the operator index i in the recording
161does not affect any of the dependent variable (given the value
162of the independent variables).
163
164\param var_by_load_op
165is a vector with size play->num_load_op_rec().
166Is the variable index corresponding to each load instruction.
167In the case where the index is zero,
168the instruction corresponds to a parameter (not variable).
169
170\par Assumptions
171The first operator on the tape is a BeginOp,
172and the next \a n operators are InvOp operations for the
173corresponding independent variables.
174*/
175template <class Base>
176void ReverseSweep(
177        size_t                      d,
178        size_t                      n,
179        size_t                      numvar,
180        player<Base>*               play,
181        size_t                      J,
182        const Base*                 Taylor,
183        size_t                      K,
184        Base*                       Partial,
185        bool*                       cskip_op,
186        const pod_vector<addr_t>&   var_by_load_op
187)
188{
189        OpCode           op;
190        size_t         i_op;
191        size_t        i_var;
192
193        const addr_t*   arg = CPPAD_NULL;
194
195        // check numvar argument
196        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
197        CPPAD_ASSERT_UNKNOWN( numvar > 0 );
198
199        // length of the parameter vector (used by CppAD assert macros)
200        const size_t num_par = play->num_par_rec();
201
202        // pointer to the beginning of the parameter vector
203        const Base* parameter = CPPAD_NULL;
204        if( num_par > 0 )
205                parameter = play->GetPar();
206
207        // work space used by UserOp.
208        const size_t user_k  = d;    // highest order we are differentiating
209        const size_t user_k1 = d+1;  // number of orders for this calculation
210        vector<size_t> user_ix;      // variable indices for argument vector
211        vector<Base> user_tx;        // argument vector Taylor coefficients
212        vector<Base> user_ty;        // result vector Taylor coefficients
213        vector<Base> user_px;        // partials w.r.t argument vector
214        vector<Base> user_py;        // partials w.r.t. result vector
215        size_t user_index = 0;       // indentifier for this atomic operation
216        size_t user_id    = 0;       // user identifier for this call to operator
217        size_t user_i     = 0;       // index in result vector
218        size_t user_j     = 0;       // index in argument vector
219        size_t user_m     = 0;       // size of result vector
220        size_t user_n     = 0;       // size of arugment vector
221        //
222        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
223# ifndef NDEBUG
224        bool               user_ok   = false;      // atomic op return value
225# endif
226        //
227        // next expected operator in a UserOp sequence
228        enum { user_start, user_arg, user_ret, user_end } user_state = user_end;
229
230        // temporary indices
231        size_t j, ell;
232
233        // Initialize
234        play->reverse_start(op, arg, i_op, i_var);
235        CPPAD_ASSERT_UNKNOWN( op == EndOp );
236# if CPPAD_REVERSE_SWEEP_TRACE
237        std::cout << std::endl;
238# endif
239        bool more_operators = true;
240        while(more_operators)
241        {       // next op
242                play->reverse_next(op, arg, i_op, i_var);
243                CPPAD_ASSERT_UNKNOWN((i_op >  n) | (op == InvOp) | (op == BeginOp));
244                CPPAD_ASSERT_UNKNOWN((i_op <= n) | (op != InvOp) | (op != BeginOp));
245                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
246
247                // check if we are skipping this operation
248                while( cskip_op[i_op] )
249                {       if( op == CSumOp )
250                        {       // CSumOp has a variable number of arguments
251                                play->reverse_csum(op, arg, i_op, i_var);
252                        }
253                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
254                        // if( op == CSkipOp )
255                        // {    // CSkip has a variable number of arguments
256                        //      play->reverse_cskip(op, arg, i_op, i_var);
257                        // }
258                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
259                        play->reverse_next(op, arg, i_op, i_var);
260                }
261
262                // rest of informaiton depends on the case
263# if CPPAD_REVERSE_SWEEP_TRACE
264                if( op == CSumOp )
265                {       // CSumOp has a variable number of arguments
266                        play->reverse_csum(op, arg, i_op, i_var);
267                }
268                if( op == CSkipOp )
269                {       // CSkip has a variable number of arguments
270                        play->reverse_cskip(op, arg, i_op, i_var);
271                }
272                size_t       i_tmp  = i_var;
273                const Base*  Z_tmp  = Taylor + i_var * J;
274                const Base*  pZ_tmp = Partial + i_var * K;
275                printOp(
276                        std::cout, 
277                        play,
278                        i_op,
279                        i_tmp,
280                        op, 
281                        arg
282                );
283                if( NumRes(op) > 0 && op != BeginOp ) printOpResult(
284                        std::cout, 
285                        d + 1, 
286                        Z_tmp, 
287                        d + 1, 
288                        pZ_tmp
289                );
290                std::cout << std::endl;
291# endif
292                switch( op )
293                {
294
295                        case AbsOp:
296                        reverse_abs_op(
297                                d, i_var, arg[0], J, Taylor, K, Partial
298                        );
299                        break;
300                        // --------------------------------------------------
301
302                        case AddvvOp:
303                        reverse_addvv_op(
304                                d, i_var, arg, parameter, J, Taylor, K, Partial
305                        );
306                        break;
307                        // --------------------------------------------------
308
309                        case AddpvOp:
310                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
311                        reverse_addpv_op(
312                                d, i_var, arg, parameter, J, Taylor, K, Partial
313                        );
314                        break;
315                        // --------------------------------------------------
316
317                        case AcosOp:
318                        // sqrt(1 - x * x), acos(x)
319                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
320                        reverse_acos_op(
321                                d, i_var, arg[0], J, Taylor, K, Partial
322                        );
323                        break;
324                        // --------------------------------------------------
325
326                        case AsinOp:
327                        // sqrt(1 - x * x), asin(x)
328                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
329                        reverse_asin_op(
330                                d, i_var, arg[0], J, Taylor, K, Partial
331                        );
332                        break;
333                        // --------------------------------------------------
334
335                        case AtanOp:
336                        // 1 + x * x, atan(x)
337                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
338                        reverse_atan_op(
339                                d, i_var, arg[0], J, Taylor, K, Partial
340                        );
341                        break;
342                        // -------------------------------------------------
343
344                        case BeginOp:
345                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
346                        more_operators = false;
347                        break;
348                        // --------------------------------------------------
349
350                        case CSkipOp:
351                        // CSkipOp has a variable number of arguments and
352                        // forward_next thinks it one has one argument.
353                        // we must inform reverse_next of this special case.
354# if ! CPPAD_REVERSE_SWEEP_TRACE
355                        play->reverse_cskip(op, arg, i_op, i_var);
356# endif
357                        break;
358                        // -------------------------------------------------
359
360                        case CSumOp:
361                        // CSumOp has a variable number of arguments and
362                        // reverse_next thinks it one has one argument.
363                        // We must inform reverse_next of this special case.
364# if ! CPPAD_REVERSE_SWEEP_TRACE
365                        play->reverse_csum(op, arg, i_op, i_var);
366# endif
367                        reverse_csum_op(
368                                d, i_var, arg, K, Partial
369                        );
370                        // end of a cummulative summation
371                        break;
372                        // -------------------------------------------------
373
374                        case CExpOp:
375                        reverse_cond_op(
376                                d, 
377                                i_var, 
378                                arg, 
379                                num_par, 
380                                parameter, 
381                                J, 
382                                Taylor,
383                                K, 
384                                Partial
385                        );
386                        break;
387                        // --------------------------------------------------
388
389                        case CosOp:
390                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
391                        reverse_cos_op(
392                                d, i_var, arg[0], J, Taylor, K, Partial
393                        );
394                        break;
395                        // --------------------------------------------------
396
397                        case CoshOp:
398                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
399                        reverse_cosh_op(
400                                d, i_var, arg[0], J, Taylor, K, Partial
401                        );
402                        break;
403                        // --------------------------------------------------
404
405                        case DisOp:
406                        // Derivative of discrete operation is zero so no
407                        // contribution passes through this operation.
408                        break;
409                        // --------------------------------------------------
410
411                        case DivvvOp:
412                        reverse_divvv_op(
413                                d, i_var, arg, parameter, J, Taylor, K, Partial
414                        );
415                        break;
416                        // --------------------------------------------------
417
418                        case DivpvOp:
419                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
420                        reverse_divpv_op(
421                                d, i_var, arg, parameter, J, Taylor, K, Partial
422                        );
423                        break;
424                        // --------------------------------------------------
425
426                        case DivvpOp:
427                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
428                        reverse_divvp_op(
429                                d, i_var, arg, parameter, J, Taylor, K, Partial
430                        );
431                        break;
432                        // --------------------------------------------------
433
434# if CPPAD_COMPILER_HAS_ERF
435                        case ErfOp:
436                        reverse_erf_op(
437                                d, i_var, arg, parameter, J, Taylor, K, Partial
438                        );
439                        break;
440# endif
441                        // --------------------------------------------------
442
443                        case ExpOp:
444                        reverse_exp_op(
445                                d, i_var, arg[0], J, Taylor, K, Partial
446                        );
447                        break;
448                        // --------------------------------------------------
449
450                        case InvOp:
451                        break;
452                        // --------------------------------------------------
453
454                        case LdpOp:
455                        reverse_load_op(
456                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
457                        );
458                        break;
459                        // -------------------------------------------------
460
461                        case LdvOp:
462                        reverse_load_op(
463                op, d, i_var, arg, J, Taylor, K, Partial, var_by_load_op.data()
464                        );
465                        break;
466                        // --------------------------------------------------
467
468                        case EqpvOp:
469                        case EqvvOp:
470                        case LtpvOp:
471                        case LtvpOp:
472                        case LtvvOp:
473                        case LepvOp:
474                        case LevpOp:
475                        case LevvOp:
476                        case NepvOp:
477                        case NevvOp:
478                        break;
479                        // -------------------------------------------------
480
481                        case LogOp:
482                        reverse_log_op(
483                                d, i_var, arg[0], J, Taylor, K, Partial
484                        );
485                        break;
486                        // --------------------------------------------------
487
488                        case MulvvOp:
489                        reverse_mulvv_op(
490                                d, i_var, arg, parameter, J, Taylor, K, Partial
491                        );
492                        break;
493                        // --------------------------------------------------
494
495                        case MulpvOp:
496                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
497                        reverse_mulpv_op(
498                                d, i_var, arg, parameter, J, Taylor, K, Partial
499                        );
500                        break;
501                        // --------------------------------------------------
502
503                        case ParOp:
504                        break;
505                        // --------------------------------------------------
506
507                        case PowvpOp:
508                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
509                        reverse_powvp_op(
510                                d, i_var, arg, parameter, J, Taylor, K, Partial
511                        );
512                        break;
513                        // -------------------------------------------------
514
515                        case PowpvOp:
516                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
517                        reverse_powpv_op(
518                                d, i_var, arg, parameter, J, Taylor, K, Partial
519                        );
520                        break;
521                        // -------------------------------------------------
522
523                        case PowvvOp:
524                        reverse_powvv_op(
525                                d, i_var, arg, parameter, J, Taylor, K, Partial
526                        );
527                        break;
528                        // --------------------------------------------------
529
530                        case PriOp:
531                        // no result so nothing to do
532                        break;
533                        // --------------------------------------------------
534
535                        case SignOp:
536                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
537                        reverse_sign_op(
538                                d, i_var, arg[0], J, Taylor, K, Partial
539                        );
540                        break;
541                        // -------------------------------------------------
542
543                        case SinOp:
544                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
545                        reverse_sin_op(
546                                d, i_var, arg[0], J, Taylor, K, Partial
547                        );
548                        break;
549                        // -------------------------------------------------
550
551                        case SinhOp:
552                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
553                        reverse_sinh_op(
554                                d, i_var, arg[0], J, Taylor, K, Partial
555                        );
556                        break;
557                        // --------------------------------------------------
558
559                        case SqrtOp:
560                        reverse_sqrt_op(
561                                d, i_var, arg[0], J, Taylor, K, Partial
562                        );
563                        break;
564                        // --------------------------------------------------
565
566                        case StppOp:
567                        break;
568                        // --------------------------------------------------
569
570                        case StpvOp:
571                        break;
572                        // -------------------------------------------------
573
574                        case StvpOp:
575                        break;
576                        // -------------------------------------------------
577
578                        case StvvOp:
579                        break;
580                        // --------------------------------------------------
581
582                        case SubvvOp:
583                        reverse_subvv_op(
584                                d, i_var, arg, parameter, J, Taylor, K, Partial
585                        );
586                        break;
587                        // --------------------------------------------------
588
589                        case SubpvOp:
590                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
591                        reverse_subpv_op(
592                                d, i_var, arg, parameter, J, Taylor, K, Partial
593                        );
594                        break;
595                        // --------------------------------------------------
596
597                        case SubvpOp:
598                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
599                        reverse_subvp_op(
600                                d, i_var, arg, parameter, J, Taylor, K, Partial
601                        );
602                        break;
603                        // -------------------------------------------------
604
605                        case TanOp:
606                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
607                        reverse_tan_op(
608                                d, i_var, arg[0], J, Taylor, K, Partial
609                        );
610                        break;
611                        // -------------------------------------------------
612
613                        case TanhOp:
614                        CPPAD_ASSERT_UNKNOWN( i_var < numvar );
615                        reverse_tanh_op(
616                                d, i_var, arg[0], J, Taylor, K, Partial
617                        );
618                        break;
619                        // --------------------------------------------------
620
621                        case UserOp:
622                        // start or end an atomic operation sequence
623                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
624                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
625                        if( user_state == user_end )
626                        {       user_index = arg[0];
627                                user_id    = arg[1];
628                                user_n     = arg[2];
629                                user_m     = arg[3];
630                                user_atom  = atomic_base<Base>::class_object(user_index);
631# ifndef NDEBUG
632                                if( user_atom == CPPAD_NULL )
633                                {       std::string msg = 
634                                                atomic_base<Base>::class_name(user_index)
635                                                + ": atomic_base function has been deleted";
636                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
637                                }
638# endif
639                                if(user_ix.size() != user_n)
640                                        user_ix.resize(user_n);
641                                if(user_tx.size() != user_n * user_k1)
642                                {       user_tx.resize(user_n * user_k1);
643                                        user_px.resize(user_n * user_k1);
644                                }
645                                if(user_ty.size() != user_m * user_k1)
646                                {       user_ty.resize(user_m * user_k1);
647                                        user_py.resize(user_m * user_k1);
648                                }
649                                user_j     = user_n;
650                                user_i     = user_m;
651                                user_state = user_ret;
652                        }
653                        else
654                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_start );
655                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
656                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
657                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
658                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
659
660                                // call users function for this operation
661                                user_atom->set_id(user_id);
662                                CPPAD_ATOMIC_CALL(
663                                        user_k, user_tx, user_ty, user_px, user_py
664                                );
665# ifndef NDEBUG
666                                if( ! user_ok )
667                                {       std::string msg = 
668                                                atomic_base<Base>::class_name(user_index)
669                                                + ": atomic_base.reverse: returned false";
670                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
671                                }
672# endif
673                                for(j = 0; j < user_n; j++) if( user_ix[j] > 0 )
674                                {       for(ell = 0; ell < user_k1; ell++)
675                                                Partial[user_ix[j] * K + ell] +=
676                                                        user_px[j * user_k1 + ell];
677                                }
678                                user_state = user_end;
679                        }
680                        break;
681
682                        case UsrapOp:
683                        // parameter argument in an atomic operation sequence
684                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
685                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
686                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
687                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
688                        --user_j;
689                        user_ix[user_j] = 0;
690                        user_tx[user_j * user_k1 + 0] = parameter[ arg[0]];
691                        for(ell = 1; ell < user_k1; ell++)
692                                user_tx[user_j * user_k1 + ell] = Base(0.);
693                       
694                        if( user_j == 0 )
695                                user_state = user_start;
696                        break;
697
698                        case UsravOp:
699                        // variable argument in an atomic operation sequence
700                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
701                        CPPAD_ASSERT_UNKNOWN( 0 < user_j && user_j <= user_n );
702                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
703                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
704                        CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
705                        --user_j;
706                        user_ix[user_j] = arg[0];
707                        for(ell = 0; ell < user_k1; ell++)
708                                user_tx[user_j*user_k1 + ell] = Taylor[ arg[0] * J + ell];
709                        if( user_j == 0 )
710                                user_state = user_start;
711                        break;
712
713                        case UsrrpOp:
714                        // parameter result in an atomic operation sequence
715                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
716                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
717                        CPPAD_ASSERT_UNKNOWN( NumArg(op) == 1 );
718                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
719                        --user_i;
720                        for(ell = 0; ell < user_k1; ell++)
721                        {       user_py[user_i * user_k1 + ell] = Base(0.);
722                                user_ty[user_i * user_k1 + ell] = Base(0.);
723                        }
724                        user_ty[user_i * user_k1 + 0] = parameter[ arg[0] ];
725                        if( user_i == 0 )
726                                user_state = user_arg;
727                        break;
728
729                        case UsrrvOp:
730                        // variable result in an atomic operation sequence
731                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
732                        CPPAD_ASSERT_UNKNOWN( 0 < user_i && user_i <= user_m );
733                        --user_i;
734                        for(ell = 0; ell < user_k1; ell++)
735                        {       user_py[user_i * user_k1 + ell] =
736                                                Partial[i_var * K + ell];
737                                user_ty[user_i * user_k1 + ell] =
738                                                Taylor[i_var * J + ell];
739                        }
740                        if( user_i == 0 )
741                                user_state = user_arg;
742                        break;
743                        // ------------------------------------------------------------
744
745                        default:
746                        CPPAD_ASSERT_UNKNOWN(false);
747                }
748        }
749# if CPPAD_REVERSE_SWEEP_TRACE
750        std::cout << std::endl;
751# endif
752        // values corresponding to BeginOp
753        CPPAD_ASSERT_UNKNOWN( i_op == 0 );
754        CPPAD_ASSERT_UNKNOWN( i_var == 0 );
755}
756
757} // END_CPPAD_NAMESPACE
758
759// preprocessor symbols that are local to this file
760# undef CPPAD_REVERSE_SWEEP_TRACE
761# undef CPPAD_ATOMIC_CALL
762
763# endif
Note: See TracBrowser for help on using the repository browser.