source: trunk/cppad/local/forward0sweep.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: 20.6 KB
Line 
1/* $Id: forward0sweep.hpp 3495 2014-12-24 01:16:15Z bradbell $ */
2# ifndef CPPAD_FORWARD0SWEEP_INCLUDED
3# define CPPAD_FORWARD0SWEEP_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 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\return
128The return value is equal to the number of ComOp operations
129that have a different result from when the information in
130play was recorded.
131(Note that if NDEBUG is true, there are no ComOp operations
132in play and hence this return value is always zero.)
133*/
134
135template <class Base>
136size_t forward0sweep(
137        std::ostream&         s_out,
138        bool                  print,
139        size_t                n,
140        size_t                numvar,
141        player<Base>*         play,
142        size_t                J,
143        Base*                 taylor,
144        bool*                 cskip_op,
145        pod_vector<addr_t>&   var_by_load_op
146)
147{       CPPAD_ASSERT_UNKNOWN( J >= 1 );
148        CPPAD_ASSERT_UNKNOWN( play->num_var_rec() == numvar );
149
150        // use p, q, r so other forward sweeps can use code defined here
151        size_t p = 0;
152        size_t q = 0;
153        size_t r = 1;
154        /*
155        <!-- define forward0sweep_code_define -->
156        */
157        // op code for current instruction
158        OpCode op;
159
160        // index for current instruction
161        size_t i_op;
162
163        // next variables
164        size_t i_var;
165
166        // operation argument indices
167        const addr_t*   arg = CPPAD_NULL;
168
169        // initialize the comparision operator (ComOp) counter
170        size_t compareCount = 0;
171
172        // If this includes a zero calculation, initialize this information
173        pod_vector<bool>   isvar_by_ind;
174        pod_vector<size_t> index_by_ind;
175        if( p == 0 )
176        {       size_t i;
177
178                // this includes order zero calculation, initialize vector indices
179                size_t num = play->num_vec_ind_rec();
180                if( num > 0 )
181                {       isvar_by_ind.extend(num);
182                        index_by_ind.extend(num);
183                        for(i = 0; i < num; i++)
184                        {       index_by_ind[i] = play->GetVecInd(i);
185                                isvar_by_ind[i] = false;
186                        }
187                }
188                // includes zero order, so initialize conditional skip flags
189                num = play->num_op_rec();
190                for(i = 0; i < num; i++)
191                        cskip_op[i] = false;
192        }
193
194        // work space used by UserOp.
195        vector<bool> user_vx;        // empty vecotor
196        vector<bool> user_vy;        // empty vecotor
197        vector<Base> user_tx;        // argument vector Taylor coefficients
198        vector<Base> user_ty;        // result vector Taylor coefficients
199        size_t user_index = 0;       // indentifier for this atomic operation
200        size_t user_id    = 0;       // user identifier for this call to operator
201        size_t user_i     = 0;       // index in result vector
202        size_t user_j     = 0;       // index in argument vector
203        size_t user_m     = 0;       // size of result vector
204        size_t user_n     = 0;       // size of arugment vector
205        //
206        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
207# ifndef NDEBUG
208        bool               user_ok   = false;      // atomic op return value
209# endif
210        //
211        // next expected operator in a UserOp sequence
212        enum { user_start, user_arg, user_ret, user_end, user_trace }
213        user_state = user_start;
214
215        // length of the parameter vector (used by CppAD assert macros)
216        const size_t num_par = play->num_par_rec();
217
218        // pointer to the beginning of the parameter vector
219        const Base* parameter = CPPAD_NULL;
220        if( num_par > 0 )
221                parameter = play->GetPar();
222
223        // length of the text vector (used by CppAD assert macros)
224        const size_t num_text = play->num_text_rec();
225
226        // pointer to the beginning of the text vector
227        const char* text = CPPAD_NULL;
228        if( num_text > 0 )
229                text = play->GetTxt(0);
230        /*
231        <!-- end forward0sweep_code_define -->
232        */
233
234# if CPPAD_FORWARD0SWEEP_TRACE
235        // variable indices for results vector
236        // (done differently for order zero).
237        vector<size_t> user_iy;     
238# endif
239
240        // skip the BeginOp at the beginning of the recording
241        play->forward_start(op, arg, i_op, i_var);
242        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
243# if CPPAD_FORWARD0SWEEP_TRACE
244        std::cout << std::endl;
245# endif
246        bool more_operators = true;
247        while(more_operators)
248        {
249                // this op
250                play->forward_next(op, arg, i_op, i_var);
251                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) ); 
252                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) ); 
253                CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
254                CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var);
255
256                // check if we are skipping this operation
257                while( cskip_op[i_op] )
258                {       if( op == CSumOp )
259                        {       // CSumOp has a variable number of arguments
260                                play->forward_csum(op, arg, i_op, i_var);
261                        }
262                        CPPAD_ASSERT_UNKNOWN( op != CSkipOp );
263                        // if( op == CSkipOp )
264                        // {    // CSkip has a variable number of arguments
265                        //      play->forward_cskip(op, arg, i_op, i_var);
266                        // }
267                        play->forward_next(op, arg, i_op, i_var);
268                        CPPAD_ASSERT_UNKNOWN( i_op < play->num_op_rec() );
269                }
270
271                // action to take depends on the case
272                switch( op )
273                {
274                        case AbsOp:
275                        forward_abs_op_0(i_var, arg[0], J, taylor);
276                        break;
277                        // -------------------------------------------------
278
279                        case AddvvOp:
280                        forward_addvv_op_0(i_var, arg, parameter, J, taylor);
281                        break;
282                        // -------------------------------------------------
283
284                        case AddpvOp:
285                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
286                        forward_addpv_op_0(i_var, arg, parameter, J, taylor);
287                        break;
288                        // -------------------------------------------------
289
290                        case AcosOp:
291                        // sqrt(1 - x * x), acos(x)
292                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
293                        forward_acos_op_0(i_var, arg[0], J, taylor);
294                        break;
295                        // -------------------------------------------------
296
297                        case AsinOp:
298                        // sqrt(1 - x * x), asin(x)
299                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
300                        forward_asin_op_0(i_var, arg[0], J, taylor);
301                        break;
302                        // -------------------------------------------------
303
304                        case AtanOp:
305                        // 1 + x * x, atan(x)
306                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
307                        forward_atan_op_0(i_var, arg[0], J, taylor);
308                        break;
309                        // -------------------------------------------------
310
311                        case CExpOp:
312                        // Use the general case with d == 0
313                        // (could create an optimzied verison for this case)
314                        forward_cond_op_0(
315                                i_var, arg, num_par, parameter, J, taylor
316                        );
317                        break;
318                        // ---------------------------------------------------
319                        case ComOp:
320                        forward_comp_op_0(
321                        compareCount, arg, num_par, parameter, J, taylor
322                        );
323                        break;
324                        // ---------------------------------------------------
325
326                        case CosOp:
327                        // sin(x), cos(x)
328                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
329                        forward_cos_op_0(i_var, arg[0], J, taylor);
330                        break;
331                        // ---------------------------------------------------
332
333                        case CoshOp:
334                        // sinh(x), cosh(x)
335                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
336                        forward_cosh_op_0(i_var, arg[0], J, taylor);
337                        break;
338                        // -------------------------------------------------
339
340                        case CSkipOp:
341                        // CSkipOp has a variable number of arguments and
342                        // forward_next thinks it has no arguments.
343                        // we must inform forward_next of this special case.
344                        forward_cskip_op_0(
345                                i_var, arg, num_par, parameter, J, taylor, cskip_op
346                        );
347                        play->forward_cskip(op, arg, i_op, i_var);
348                        break;
349                        // -------------------------------------------------
350
351                        case CSumOp:
352                        // CSumOp has a variable number of arguments and
353                        // forward_next thinks it has no arguments.
354                        // we must inform forward_next of this special case.
355                        forward_csum_op(
356                                0, 0, i_var, arg, num_par, parameter, J, taylor
357                        );
358                        play->forward_csum(op, arg, i_op, i_var);
359                        break;
360                        // -------------------------------------------------
361
362                        case DisOp:
363                        forward_dis_op(p, q, r, i_var, arg, J, taylor);
364                        break;
365                        // -------------------------------------------------
366
367                        case DivvvOp:
368                        forward_divvv_op_0(i_var, arg, parameter, J, taylor);
369                        break;
370                        // -------------------------------------------------
371
372                        case DivpvOp:
373                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
374                        forward_divpv_op_0(i_var, arg, parameter, J, taylor);
375                        break;
376                        // -------------------------------------------------
377
378                        case DivvpOp:
379                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
380                        forward_divvp_op_0(i_var, arg, parameter, J, taylor);
381                        break;
382                        // -------------------------------------------------
383
384                        case EndOp:
385                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
386                        more_operators = false;
387                        break;
388                        // -------------------------------------------------
389
390# if CPPAD_COMPILER_HAS_ERF
391                        case ErfOp:
392                        CPPAD_ASSERT_UNKNOWN( CPPAD_COMPILER_HAS_ERF );
393                        // 2DO: implement zero order version of this function
394                        forward_erf_op_0(i_var, arg, parameter, J, taylor);
395                        break;
396# endif
397                        // -------------------------------------------------
398
399                        case ExpOp:
400                        forward_exp_op_0(i_var, arg[0], J, taylor);
401                        break;
402                        // -------------------------------------------------
403
404                        case InvOp:
405                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
406                        break;
407                        // -------------------------------------------------
408
409                        case LdpOp:
410                        forward_load_p_op_0(
411                                play,
412                                i_var, 
413                                arg, 
414                                parameter, 
415                                J, 
416                                taylor,
417                                isvar_by_ind.data(),
418                                index_by_ind.data(),
419                                var_by_load_op.data()
420                        );
421                        break;
422                        // -------------------------------------------------
423
424                        case LdvOp:
425                        forward_load_v_op_0(
426                                play,
427                                i_var, 
428                                arg, 
429                                parameter, 
430                                J, 
431                                taylor,
432                                isvar_by_ind.data(),
433                                index_by_ind.data(),
434                                var_by_load_op.data()
435                        );
436                        break;
437                        // -------------------------------------------------
438
439                        case LogOp:
440                        forward_log_op_0(i_var, arg[0], J, taylor);
441                        break;
442                        // -------------------------------------------------
443
444                        case MulvvOp:
445                        forward_mulvv_op_0(i_var, arg, parameter, J, taylor);
446                        break;
447                        // -------------------------------------------------
448
449                        case MulpvOp:
450                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
451                        forward_mulpv_op_0(i_var, arg, parameter, J, taylor);
452                        break;
453                        // -------------------------------------------------
454
455                        case ParOp:
456                        forward_par_op_0(
457                                i_var, arg, num_par, parameter, J, taylor
458                        );
459                        break;
460                        // -------------------------------------------------
461
462                        case PowvpOp:
463                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
464                        forward_powvp_op_0(i_var, arg, parameter, J, taylor);
465                        break;
466                        // -------------------------------------------------
467
468                        case PowpvOp:
469                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
470                        forward_powpv_op_0(i_var, arg, parameter, J, taylor);
471                        break;
472                        // -------------------------------------------------
473
474                        case PowvvOp:
475                        forward_powvv_op_0(i_var, arg, parameter, J, taylor);
476                        break;
477                        // -------------------------------------------------
478
479                        case PriOp:
480                        if( print ) forward_pri_0(s_out,
481                                arg, num_text, text, num_par, parameter, J, taylor
482                        );
483                        break;
484                        // -------------------------------------------------
485
486                        case SignOp:
487                        // cos(x), sin(x)
488                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
489                        forward_sign_op_0(i_var, arg[0], J, taylor);
490                        break;
491                        // -------------------------------------------------
492
493                        case SinOp:
494                        // cos(x), sin(x)
495                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
496                        forward_sin_op_0(i_var, arg[0], J, taylor);
497                        break;
498                        // -------------------------------------------------
499
500                        case SinhOp:
501                        // cosh(x), sinh(x)
502                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
503                        forward_sinh_op_0(i_var, arg[0], J, taylor);
504                        break;
505                        // -------------------------------------------------
506
507                        case SqrtOp:
508                        forward_sqrt_op_0(i_var, arg[0], J, taylor);
509                        break;
510                        // -------------------------------------------------
511
512                        case StppOp:
513                        forward_store_pp_op_0(
514                                i_var, 
515                                arg, 
516                                num_par, 
517                                J, 
518                                taylor,
519                                isvar_by_ind.data(),
520                                index_by_ind.data()
521                        );
522                        break;
523                        // -------------------------------------------------
524
525                        case StpvOp:
526                        forward_store_pv_op_0(
527                                i_var, 
528                                arg, 
529                                num_par, 
530                                J, 
531                                taylor,
532                                isvar_by_ind.data(),
533                                index_by_ind.data()
534                        );
535                        break;
536                        // -------------------------------------------------
537
538                        case StvpOp:
539                        forward_store_vp_op_0(
540                                i_var, 
541                                arg, 
542                                num_par, 
543                                J, 
544                                taylor,
545                                isvar_by_ind.data(),
546                                index_by_ind.data()
547                        );
548                        break;
549                        // -------------------------------------------------
550
551                        case StvvOp:
552                        forward_store_vv_op_0(
553                                i_var, 
554                                arg, 
555                                num_par, 
556                                J, 
557                                taylor,
558                                isvar_by_ind.data(),
559                                index_by_ind.data()
560                        );
561                        break;
562                        // -------------------------------------------------
563
564                        case SubvvOp:
565                        forward_subvv_op_0(i_var, arg, parameter, J, taylor);
566                        break;
567                        // -------------------------------------------------
568
569                        case SubpvOp:
570                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
571                        forward_subpv_op_0(i_var, arg, parameter, J, taylor);
572                        break;
573                        // -------------------------------------------------
574
575                        case SubvpOp:
576                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
577                        forward_subvp_op_0(i_var, arg, parameter, J, taylor);
578                        break;
579                        // -------------------------------------------------
580
581                        case TanOp:
582                        // tan(x)^2, tan(x)
583                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
584                        forward_tan_op_0(i_var, arg[0], J, taylor);
585                        break;
586                        // -------------------------------------------------
587
588                        case TanhOp:
589                        // tanh(x)^2, tanh(x)
590                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
591                        forward_tanh_op_0(i_var, arg[0], J, taylor);
592                        break;
593                        // -------------------------------------------------
594
595                        case UserOp:
596                        // start or end an atomic operation sequence
597                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
598                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
599                        if( user_state == user_start )
600                        {       user_index = arg[0];
601                                user_id    = arg[1];
602                                user_n     = arg[2];
603                                user_m     = arg[3];
604                                user_atom  = atomic_base<Base>::class_object(user_index);
605# ifndef NDEBUG
606                                if( user_atom == CPPAD_NULL )
607                                {       std::string msg = 
608                                                atomic_base<Base>::class_name(user_index)
609                                                + ": atomic_base function has been deleted";
610                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
611                                }
612# endif
613                                if(user_tx.size() != user_n)
614                                        user_tx.resize(user_n);
615                                if(user_ty.size() != user_m)
616                                        user_ty.resize(user_m);
617# if CPPAD_FORWARD0SWEEP_TRACE
618                                if( user_iy.size() != user_m )
619                                        user_iy.resize(user_m);
620# endif
621                                user_j     = 0;
622                                user_i     = 0;
623                                user_state = user_arg;
624                        }
625                        else
626                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
627                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
628                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
629                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
630                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
631# ifndef NDEBUG
632                                if( ! user_ok )
633                                {       std::string msg = 
634                                                atomic_base<Base>::class_name(user_index)
635                                                + ": atomic_base.forward: returned false";
636                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
637                                }
638# endif
639# if CPPAD_FORWARD0SWEEP_TRACE
640                                user_state = user_trace;
641# else
642                                user_state = user_start;
643# endif
644                        }
645                        break;
646
647                        case UsrapOp:
648                        // parameter argument in an atomic operation sequence
649                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
650                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
651                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
652                        user_tx[user_j++] = parameter[ arg[0] ];
653                        if( user_j == user_n )
654                        {       // call users function for this operation
655                                user_atom->set_id(user_id);
656                                CPPAD_ATOMIC_CALL(p, q, 
657                                        user_vx, user_vy, user_tx, user_ty
658                                );
659                                user_state = user_ret;
660                        }
661                        break;
662
663                        case UsravOp:
664                        // variable argument in an atomic operation sequence
665                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
666                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
667                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
668                        user_tx[user_j++] = taylor[ arg[0] * J + 0 ];
669                        if( user_j == user_n )
670                        {       // call users function for this operation
671                                user_atom->set_id(user_id);
672                                CPPAD_ATOMIC_CALL(p, q, 
673                                        user_vx, user_vy, user_tx, user_ty
674                                );
675                                user_state = user_ret;
676                        }
677                        break;
678
679                        case UsrrpOp:
680                        // parameter result in an atomic operation sequence
681                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
682                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
683# if CPPAD_FORWARD0SWEEP_TRACE
684                        user_iy[user_i] = 0;
685# endif
686                        user_i++;
687                        if( user_i == user_m )
688                                user_state = user_end;
689                        break;
690
691                        case UsrrvOp:
692                        // variable result in an atomic operation sequence
693                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
694                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
695# if CPPAD_FORWARD0SWEEP_TRACE
696                        user_iy[user_i] = i_var;
697# endif
698                        taylor[ i_var * J + 0 ] = user_ty[user_i++];
699                        if( user_i == user_m )
700                                user_state = user_end;
701                        break;
702                        // -------------------------------------------------
703
704                        default:
705                        CPPAD_ASSERT_UNKNOWN(false);
706                }
707# if CPPAD_FORWARD0SWEEP_TRACE
708                size_t  d  = 0;
709                if( user_state == user_trace )
710                {       user_state = user_start;
711
712                        CPPAD_ASSERT_UNKNOWN( op == UserOp );
713                        CPPAD_ASSERT_UNKNOWN( NumArg(UsrrvOp) == 0 );
714                        for(size_t i = 0; i < user_m; i++) if( user_iy[i] > 0 )
715                        {       size_t i_tmp   = (i_op + i) - user_m;
716                                printOp(
717                                        std::cout, 
718                                        play,
719                                        i_tmp,
720                                        user_iy[i],
721                                        UsrrvOp, 
722                                        CPPAD_NULL
723                                );
724                                Base* Z_tmp = taylor + user_iy[i] * J;
725                                printOpResult(
726                                        std::cout, 
727                                        d + 1, 
728                                        Z_tmp,
729                                        0, 
730                                        (Base *) CPPAD_NULL
731                                );
732                                std::cout << std::endl;
733                        }
734                }
735                Base*           Z_tmp   = taylor + i_var * J;
736                const addr_t*   arg_tmp = arg;
737                if( op == CSumOp )
738                        arg_tmp = arg - arg[-1] - 4;
739                if( op == CSkipOp )
740                        arg_tmp = arg - arg[-1] - 7;
741                if( op != UsrrvOp )
742                {
743                        printOp(
744                                std::cout, 
745                                play,
746                                i_op,
747                                i_var,
748                                op, 
749                                arg_tmp
750                        );
751                        if( NumRes(op) > 0 ) printOpResult(
752                                std::cout, 
753                                d + 1, 
754                                Z_tmp, 
755                                0, 
756                                (Base *) CPPAD_NULL
757                        );
758                        std::cout << std::endl;
759                }
760        }
761        std::cout << std::endl;
762# else
763        }
764# endif
765        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
766        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
767
768        return compareCount;
769}
770
771} // END_CPPAD_NAMESPACE
772
773// preprocessor symbols that are local to this file
774# undef CPPAD_FORWARD0SWEEP_TRACE
775# undef CPPAD_ATOMIC_CALL
776
777# endif
Note: See TracBrowser for help on using the repository browser.