source: trunk/cppad/local/forward1sweep.hpp @ 3495

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

Squashed commit of the following:

commit ea33674d009e14c6b8b8479fe08f5fd14efe15ce
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 17:32:52 2014 -0700

Change CPPAD_HAS_ERROR_FUNCTION -> CPPAD_COMPLIER_HAS_ERF.

commit c81badddaa95ce83d9d74ef5516955fb53be650f
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 16:31:03 2014 -0700

base_require.hpp: remove command that is not used.
base_adolc.hpp: define erf when it is required.
erf_op.hpp: fix derivative of zero order.
for_jac_sweep.hpp: remove trailing white space, add ErfOp?.
op_code.hpp: fix tracing of ErfOp?
rev_hes_sweep.hpp: add ErfOp?.
rev_jac_sweep.hpp: remove trailing white space, add ErfOp?.
erf.cpp: add more examples and tests.
erf.cpp: change x0 to not be multiply identity.

commit 213c2321cb527d6b913ac627ab631098e643be4f
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 07:14:56 2014 -0700

Add special routine for erf zero order forward mode.

commit 8cc6ca517ddbe213988e497a100a8ae6465a0a3e
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 06:54:33 2014 -0700

Implement and test atomic erf in reverse mode.

commit 8611fca3e9fea21ff5cc5d4e8742a01e1f29070f
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 05:31:47 2014 -0700

tan_reverse.omh: fix typo.

commit f582631d101fdbab721fb283e5284b59bc018015
Author: Brad Bell <bradbell@…>
Date: Tue Dec 23 04:53:39 2014 -0700

Test forward order zero, one, and two both with and without std::erf.

commit 7bba97a757252f279dfe7fc58209d8e55ce8e9f6
Author: Brad Bell <bradbell@…>
Date: Mon Dec 22 21:48:30 2014 -0700

  1. Ignore git_commit.sh (temporary file created by ~/bin/git_commit.sh).
  2. Add base requrements for erf function.
  3. Implement and test forward mode for erf(double).

erf_op.hpp: remove i_x (not used).
forward0sweep.hpp: add ErfOp? case.
undef.hpp: make CPPAD_HAS_ERROR_FUNCTION part of user api.
erf.cpp: comment out parts not yet being tested.

commit 967f6843f9c4133ed3f986371e01115504e20f68
Merge: 3a7a9ea 9edd70a
Author: Brad Bell <bradbell@…>
Date: Mon Dec 22 07:16:00 2014 -0700

Merge branch 'master' into erf

commit 3a7a9ea832d4ab90c80c5c9bbeea5a9f3c9839e7
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 18:51:58 2014 -0700

op_code.hpp: add ErfOp?.
undef.hpp: add CPPAD_HAS_ERROR_FUNCTION.
makefile.am: add erf_op.hpp.

commit d584798c43e7fe5c5c3d080328fee06ff7ba0fe1
Merge: 5f13ae6 58a292c
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 09:24:16 2014 -0700

Merge branch 'master' into erf

commit 5f13ae64b979e618188adabad4365ffa6c011215
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 09:12:11 2014 -0700

erf_op.hpp: only defined operators when compiler has erf.

commit acc16d2b5251250850ef3125a2bdcea11ec18cf8
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 08:41:35 2014 -0700

Implement erf general forward mode as plan for other changes (not hooked up).

commit 5522393a914a2117bdc149fe16b62c0afff0102e
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 06:40:27 2014 -0700

Add cppad_has_error_function (true if compiler has error function).

commit da4f1ba378f92e78b17ca1e85c417f86b6946dbf
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 06:13:52 2014 -0700

erf.hpp: Document planned change in this branch.
erf_forward.omh: fix sqrt{pi}, fix svn Id (messed up by git-svn).
erf_reverse.omh: fix svn Id.

commit 05eebb357f90818f2b4dec8a3e108820fb6c34b2
Merge: 2398fd6 7d9ed8a
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 05:33:05 2014 -0700

Merge branch 'master' into erf

commit 7d9ed8abddffba666f76f64e28e48766cbc28fb6
Author: Brad Bell <bradbell@…>
Date: Sun Dec 21 05:27:17 2014 -0700

  1. Change size_t_same_unsigned_int to size_t_not_unsigned_int. so that test result variable has same meaning as test.
  2. Fix svn Id property at top if files being commited.

package.sh: Remove check_svn_id.sh from list becuse git-svn messed up Id.

commit 2398fd6ad75d51c436ee1cf9b9cf2f606ef44828
Author: Brad Bell <bradbell@…>
Date: Sat Dec 20 09:02:02 2014 -0700

erf_reverse.omh: theory for for erf reverse mode calculation.

commit fc83d4fe0da0ecc09bbb5a8d0334379756e58c3e
Author: Brad Bell <bradbell@…>
Date: Sat Dec 20 07:43:50 2014 -0700

Start work on makeing erf an atomic operation (when supported by compiler).

erf_forward.omh: forward mode theory for erf.

  • Property svn:keywords set to Id
File size: 22.7 KB
Line 
1/* $Id: forward1sweep.hpp 3495 2014-12-24 01:16:15Z bradbell $ */
2# ifndef CPPAD_FORWARD1SWEEP_INCLUDED
3# define CPPAD_FORWARD1SWEEP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-14 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\return
168If p is not zero, the return value is zero.
169If p is zero,
170the return value is equal to the number of ComOp operations
171that have a different result from when the information in
172a play was recorded.
173(Note that if NDEBUG is true, there are no ComOp operations
174in play and hence this return value is always zero.)
175*/
176
177template <class Base>
178size_t forward1sweep(
179        std::ostream&         s_out,
180        const bool            print,
181        const size_t          p,
182        const size_t          q,
183        const size_t          n,
184        const size_t          numvar,
185        player<Base>*         play,
186        const size_t          J,
187        Base*                 taylor,
188        bool*                 cskip_op,
189        pod_vector<addr_t>&   var_by_load_op
190)
191{
192        // number of directions
193        const size_t r = 1;
194
195        CPPAD_ASSERT_UNKNOWN( p <= q );
196        CPPAD_ASSERT_UNKNOWN( J >= q + 1 );
197        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
198
199        /*
200        <!-- replace forward0sweep_code_define -->
201        */
202        // op code for current instruction
203        OpCode op;
204
205        // index for current instruction
206        size_t i_op;
207
208        // next variables
209        size_t i_var;
210
211        // operation argument indices
212        const addr_t*   arg = CPPAD_NULL;
213
214        // initialize the comparision operator (ComOp) counter
215        size_t compareCount = 0;
216
217        // If this includes a zero calculation, initialize this information
218        pod_vector<bool>   isvar_by_ind;
219        pod_vector<size_t> index_by_ind;
220        if( p == 0 )
221        {       size_t i;
222
223                // this includes order zero calculation, initialize vector indices
224                size_t num = play->num_vec_ind_rec();
225                if( num > 0 )
226                {       isvar_by_ind.extend(num);
227                        index_by_ind.extend(num);
228                        for(i = 0; i < num; i++)
229                        {       index_by_ind[i] = play->GetVecInd(i);
230                                isvar_by_ind[i] = false;
231                        }
232                }
233                // includes zero order, so initialize conditional skip flags
234                num = play->num_op_rec();
235                for(i = 0; i < num; i++)
236                        cskip_op[i] = false;
237        }
238
239        // work space used by UserOp.
240        vector<bool> user_vx;        // empty vecotor
241        vector<bool> user_vy;        // empty vecotor
242        vector<Base> user_tx;        // argument vector Taylor coefficients
243        vector<Base> user_ty;        // result vector Taylor coefficients
244        size_t user_index = 0;       // indentifier for this atomic operation
245        size_t user_id    = 0;       // user identifier for this call to operator
246        size_t user_i     = 0;       // index in result vector
247        size_t user_j     = 0;       // index in argument vector
248        size_t user_m     = 0;       // size of result vector
249        size_t user_n     = 0;       // size of arugment vector
250        //
251        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
252# ifndef NDEBUG
253        bool               user_ok   = false;      // atomic op return value
254# endif
255        //
256        // next expected operator in a UserOp sequence
257        enum { user_start, user_arg, user_ret, user_end, user_trace }
258        user_state = user_start;
259
260        // length of the parameter vector (used by CppAD assert macros)
261        const size_t num_par = play->num_par_rec();
262
263        // pointer to the beginning of the parameter vector
264        const Base* parameter = CPPAD_NULL;
265        if( num_par > 0 )
266                parameter = play->GetPar();
267
268        // length of the text vector (used by CppAD assert macros)
269        const size_t num_text = play->num_text_rec();
270
271        // pointer to the beginning of the text vector
272        const char* text = CPPAD_NULL;
273        if( num_text > 0 )
274                text = play->GetTxt(0);
275        /*
276        <!-- end forward0sweep_code_define -->
277        */
278        // temporary indices
279        size_t i, k;
280
281        // number of orders for this user calculation
282        // (not needed for order zero)
283        const size_t user_q1 = q+1;
284
285        // variable indices for results vector
286        // (done differently for order zero).
287        vector<size_t> user_iy;     
288
289        // skip the BeginOp at the beginning of the recording
290        play->forward_start(op, arg, i_op, i_var);
291        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
292# if CPPAD_FORWARD1SWEEP_TRACE
293        std::cout << std::endl;
294# endif
295        bool more_operators = true;
296        while(more_operators)
297        {
298                // this op
299                play->forward_next(op, arg, i_op, i_var);
300                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) ); 
301                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); 
302                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
303                CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var);
304
305                // check if we are skipping this operation
306                while( cskip_op[i_op] )
307                {       if( op == CSumOp )
308                        {       // CSumOp has a variable number of arguments
309                                play->forward_csum(op, arg, i_op, i_var);
310                        }
311                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
312                        // if( op == CSkipOp )
313                        // {    // CSkip has a variable number of arguments
314                        //      play->forward_cskip(op, arg, i_op, i_var);
315                        // }
316                        play->forward_next(op, arg, i_op, i_var);
317                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
318                }
319
320                // action depends on the operator
321                switch( op )
322                {
323                        case AbsOp:
324                        forward_abs_op(p, q, i_var, arg[0], J, taylor);
325                        break;
326                        // -------------------------------------------------
327
328                        case AddvvOp:
329                        forward_addvv_op(p, q, i_var, arg, parameter, J, taylor);
330                        break;
331                        // -------------------------------------------------
332
333                        case AddpvOp:
334                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
335                        forward_addpv_op(p, q, i_var, arg, parameter, J, taylor);
336                        break;
337                        // -------------------------------------------------
338
339                        case AcosOp:
340                        // sqrt(1 - x * x), acos(x)
341                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
342                        forward_acos_op(p, q, i_var, arg[0], J, taylor);
343                        break;
344                        // -------------------------------------------------
345
346                        case AsinOp:
347                        // sqrt(1 - x * x), asin(x)
348                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
349                        forward_asin_op(p, q, i_var, arg[0], J, taylor);
350                        break;
351                        // -------------------------------------------------
352
353                        case AtanOp:
354                        // 1 + x * x, atan(x)
355                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
356                        forward_atan_op(p, q, i_var, arg[0], J, taylor);
357                        break;
358                        // -------------------------------------------------
359
360# if CPPAD_COMPILER_HAS_ERF
361                        case ErfOp:
362                        CPPAD_ASSERT_UNKNOWN( CPPAD_COMPILER_HAS_ERF );
363                        // 2DO: implement zero order version of this function
364                        forward_erf_op(p, q, i_var, arg, parameter, J, taylor);
365                        break;
366# endif
367                        // -------------------------------------------------
368
369                        case CExpOp:
370                        forward_cond_op(
371                                p, q, i_var, arg, num_par, parameter, J, taylor
372                        );
373                        break;
374                        // ---------------------------------------------------
375
376                        case ComOp:
377                        if( p == 0 ) forward_comp_op_0(
378                        compareCount, 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 ExpOp:
450                        forward_exp_op(p, q, i_var, arg[0], J, taylor);
451                        break;
452                        // -------------------------------------------------
453
454                        case InvOp:
455                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
456                        break;
457                        // -------------------------------------------------
458
459                        case LdpOp:
460                        if( p == 0 )
461                        {       forward_load_p_op_0(
462                                        play,
463                                        i_var, 
464                                        arg, 
465                                        parameter, 
466                                        J, 
467                                        taylor,
468                                        isvar_by_ind.data(),
469                                        index_by_ind.data(),
470                                        var_by_load_op.data()
471                                );
472                                if( p < q ) forward_load_op( 
473                                        play,
474                                        op,
475                                        p+1,
476                                        q,
477                                        r,
478                                        J,
479                                        i_var,
480                                        arg,
481                                        var_by_load_op.data(),
482                                        taylor
483                                );
484                        }
485                        else    forward_load_op( 
486                                play,
487                                op,
488                                p,
489                                q,
490                                r,
491                                J,
492                                i_var,
493                                arg,
494                                var_by_load_op.data(),
495                                taylor
496                        );
497                        break;
498                        // -------------------------------------------------
499
500                        case LdvOp:
501                        if( p == 0 )
502                        {       forward_load_v_op_0(
503                                        play,
504                                        i_var, 
505                                        arg, 
506                                        parameter, 
507                                        J, 
508                                        taylor,
509                                        isvar_by_ind.data(),
510                                        index_by_ind.data(),
511                                        var_by_load_op.data()
512                                );
513                                if( p < q ) forward_load_op( 
514                                        play,
515                                        op,
516                                        p+1,
517                                        q,
518                                        r,
519                                        J,
520                                        i_var,
521                                        arg,
522                                        var_by_load_op.data(),
523                                        taylor
524                                );
525                        }
526                        else    forward_load_op( 
527                                play,
528                                op,
529                                p,
530                                q,
531                                r,
532                                J,
533                                i_var,
534                                arg,
535                                var_by_load_op.data(),
536                                taylor
537                        );
538                        break;
539                        // -------------------------------------------------
540
541                        case LogOp:
542                        forward_log_op(p, q, i_var, arg[0], J, taylor);
543                        break;
544                        // -------------------------------------------------
545
546                        case MulvvOp:
547                        forward_mulvv_op(p, q, i_var, arg, parameter, J, taylor);
548                        break;
549                        // -------------------------------------------------
550
551                        case MulpvOp:
552                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
553                        forward_mulpv_op(p, q, i_var, arg, parameter, J, taylor);
554                        break;
555                        // -------------------------------------------------
556
557                        case ParOp:
558                        i = p;
559                        if( i == 0 )
560                        {       forward_par_op_0(
561                                        i_var, arg, num_par, parameter, J, taylor
562                                );
563                                i++;
564                        }
565                        while(i <= q)
566                        {       taylor[ i_var * J + i] = Base(0); 
567                                i++;
568                        }
569                        break;
570                        // -------------------------------------------------
571
572                        case PowvpOp:
573                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
574                        forward_powvp_op(p, q, i_var, arg, parameter, J, taylor);
575                        break;
576                        // -------------------------------------------------
577
578                        case PowpvOp:
579                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
580                        forward_powpv_op(p, q, i_var, arg, parameter, J, taylor);
581                        break;
582                        // -------------------------------------------------
583
584                        case PowvvOp:
585                        forward_powvv_op(p, q, i_var, arg, parameter, J, taylor);
586                        break;
587                        // -------------------------------------------------
588
589                        case PriOp:
590                        if( (p == 0) & print ) forward_pri_0(s_out,
591                                arg, num_text, text, num_par, parameter, J, taylor
592                        );
593                        break;
594                        // -------------------------------------------------
595
596                        case SignOp:
597                        // sign(x)
598                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
599                        forward_sign_op(p, q, i_var, arg[0], J, taylor);
600                        break;
601                        // -------------------------------------------------
602
603                        case SinOp:
604                        // cos(x), sin(x)
605                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
606                        forward_sin_op(p, q, i_var, arg[0], J, taylor);
607                        break;
608                        // -------------------------------------------------
609
610                        case SinhOp:
611                        // cosh(x), sinh(x)
612                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
613                        forward_sinh_op(p, q, i_var, arg[0], J, taylor);
614                        break;
615                        // -------------------------------------------------
616
617                        case SqrtOp:
618                        forward_sqrt_op(p, q, i_var, arg[0], J, taylor);
619                        break;
620                        // -------------------------------------------------
621
622                        case StppOp:
623                        if( p == 0 )
624                        {       forward_store_pp_op_0(
625                                        i_var, 
626                                        arg, 
627                                        num_par, 
628                                        J, 
629                                        taylor,
630                                        isvar_by_ind.data(),
631                                        index_by_ind.data()
632                                );
633                        }
634                        break;
635                        // -------------------------------------------------
636
637                        case StpvOp:
638                        if( p == 0 )
639                        {       forward_store_pv_op_0(
640                                        i_var, 
641                                        arg, 
642                                        num_par, 
643                                        J, 
644                                        taylor,
645                                        isvar_by_ind.data(),
646                                        index_by_ind.data()
647                                );
648                        }
649                        break;
650                        // -------------------------------------------------
651
652                        case StvpOp:
653                        if( p == 0 )
654                        {       forward_store_vp_op_0(
655                                        i_var, 
656                                        arg, 
657                                        num_par, 
658                                        J, 
659                                        taylor,
660                                        isvar_by_ind.data(),
661                                        index_by_ind.data()
662                                );
663                        }
664                        break;
665                        // -------------------------------------------------
666
667                        case StvvOp:
668                        if( p == 0 )
669                        {       forward_store_vv_op_0(
670                                        i_var, 
671                                        arg, 
672                                        num_par, 
673                                        J, 
674                                        taylor,
675                                        isvar_by_ind.data(),
676                                        index_by_ind.data()
677                                );
678                        }
679                        break;
680                        // -------------------------------------------------
681
682                        case SubvvOp:
683                        forward_subvv_op(p, q, i_var, arg, parameter, J, taylor);
684                        break;
685                        // -------------------------------------------------
686
687                        case SubpvOp:
688                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
689                        forward_subpv_op(p, q, i_var, arg, parameter, J, taylor);
690                        break;
691                        // -------------------------------------------------
692
693                        case SubvpOp:
694                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
695                        forward_subvp_op(p, q, i_var, arg, parameter, J, taylor);
696                        break;
697                        // -------------------------------------------------
698
699                        case TanOp:
700                        // tan(x)^2, tan(x)
701                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
702                        forward_tan_op(p, q, i_var, arg[0], J, taylor);
703                        break;
704                        // -------------------------------------------------
705
706                        case TanhOp:
707                        // tanh(x)^2, tanh(x)
708                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
709                        forward_tanh_op(p, q, i_var, arg[0], J, taylor);
710                        break;
711                        // -------------------------------------------------
712
713                        case UserOp:
714                        // start or end an atomic operation sequence
715                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
716                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
717                        if( user_state == user_start )
718                        {       user_index = arg[0];
719                                user_id    = arg[1];
720                                user_n     = arg[2];
721                                user_m     = arg[3];
722                                user_atom  = atomic_base<Base>::class_object(user_index);
723# ifndef NDEBUG
724                                if( user_atom == CPPAD_NULL )
725                                {       std::string msg = 
726                                                atomic_base<Base>::class_name(user_index)
727                                                + ": atomic_base function has been deleted";
728                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
729                                }
730# endif
731                                if(user_tx.size() != user_n * user_q1)
732                                        user_tx.resize(user_n * user_q1);
733                                if(user_ty.size() != user_m * user_q1)
734                                        user_ty.resize(user_m * user_q1);
735                                if(user_iy.size() != user_m)
736                                        user_iy.resize(user_m);
737                                user_j     = 0;
738                                user_i     = 0;
739                                user_state = user_arg;
740                        }
741                        else
742                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
743                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
744                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
745                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
746                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
747
748                                // call users function for this operation
749                                user_atom->set_id(user_id);
750                                CPPAD_ATOMIC_CALL(
751                                        p, q, user_vx, user_vy, user_tx, user_ty
752                                );
753# ifndef NDEBUG
754                                if( ! user_ok )
755                                {       std::string msg = 
756                                                atomic_base<Base>::class_name(user_index)
757                                                + ": atomic_base.forward: returned false";
758                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
759                                }
760# endif
761                                for(i = 0; i < user_m; i++) 
762                                        if( user_iy[i] > 0 )
763                                                for(k = p; k <= q; k++)
764                                                        taylor[ user_iy[i] * J + k ] = 
765                                                                user_ty[ i * user_q1 + k ];
766# if CPPAD_FORWARD1SWEEP_TRACE
767                                user_state = user_trace;
768# else
769                                user_state = user_start;
770# endif
771                        }
772                        break;
773
774                        case UsrapOp:
775                        // parameter argument in an atomic operation sequence
776                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
777                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
778                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
779                        user_tx[user_j * user_q1 + 0] = parameter[ arg[0]];
780                        for(k = 1; k < user_q1; k++)
781                                user_tx[user_j * user_q1 + k] = Base(0);
782                        ++user_j;
783                        if( user_j == user_n )
784                                user_state = user_ret;
785                        break;
786
787                        case UsravOp:
788                        // variable argument in an atomic operation sequence
789                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
790                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
791                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
792                        for(k = 0; k < user_q1; k++)
793                                user_tx[user_j * user_q1 + k] = taylor[ arg[0] * J + k];
794                        ++user_j;
795                        if( user_j == user_n )
796                                user_state = user_ret;
797                        break;
798
799                        case UsrrpOp:
800                        // parameter result in an atomic operation sequence
801                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
802                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
803                        user_iy[user_i] = 0;
804                        user_ty[user_i * user_q1 + 0] = parameter[ arg[0]];
805                        for(k = 1; k < p; k++)
806                                user_ty[user_i * user_q1 + k] = Base(0);
807                        user_i++;
808                        if( user_i == user_m )
809                                user_state = user_end;
810                        break;
811
812                        case UsrrvOp:
813                        // variable result in an atomic operation sequence
814                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
815                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
816                        user_iy[user_i] = i_var;
817                        for(k = 0; k < p; k++)
818                                user_ty[user_i * user_q1 + k] = taylor[ i_var * J + k];
819                        user_i++;
820                        if( user_i == user_m )
821                                user_state = user_end;
822                        break;
823                        // -------------------------------------------------
824
825                        default:
826                        CPPAD_ASSERT_UNKNOWN(0);
827                }
828# if CPPAD_FORWARD1SWEEP_TRACE
829                if( user_state == user_trace )
830                {       user_state = user_start;
831
832                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
833                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
834                        for(i = 0; i < user_m; i++) if( user_iy[i] > 0 )
835                        {       size_t i_tmp   = (i_op + i) - user_m;
836                                printOp(
837                                        std::cout, 
838                                        play,
839                                        i_tmp,
840                                        user_iy[i],
841                                        UsrrvOp, 
842                                        CPPAD_NULL
843                                );
844                                Base* Z_tmp = taylor + user_iy[i] * J;
845                                printOpResult(
846                                        std::cout, 
847                                        q + 1, 
848                                        Z_tmp,
849                                        0, 
850                                        (Base *) CPPAD_NULL
851                                );
852                                std::cout << std::endl;
853                        }
854                }
855                Base*           Z_tmp   = taylor + J * i_var;
856                const addr_t*   arg_tmp = arg;
857                if( op == CSumOp )
858                        arg_tmp = arg - arg[-1] - 4;
859                if( op == CSkipOp )
860                        arg_tmp = arg - arg[-1] - 7;
861                if( op != UsrrvOp )
862                {
863                        printOp(
864                                std::cout, 
865                                play,
866                                i_op,
867                                i_var,
868                                op, 
869                                arg_tmp
870                        );
871                        if( NumRes(op) > 0 ) printOpResult(
872                                std::cout, 
873                                q + 1, 
874                                Z_tmp, 
875                                0, 
876                                (Base *) CPPAD_NULL
877                        );
878                        std::cout << std::endl;
879                }
880        }
881        std::cout << std::endl;
882# else
883        }
884# endif
885        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
886        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
887
888        return compareCount;
889}
890
891// preprocessor symbols that are local to this file
892# undef CPPAD_FORWARD1SWEEP_TRACE
893# undef CPPAD_ATOMIC_CALL
894
895} // END_CPPAD_NAMESPACE
896# endif
Note: See TracBrowser for help on using the repository browser.