source: trunk/cppad/local/forward0sweep.hpp @ 2794

Last change on this file since 2794 was 2794, checked in by bradbell, 7 years ago
  1. Use CPPAD_NULL, intead of 0, for null pointer.

check_if_0.sh: Ignore subdirectories of new directories.
jenkins.sh: output logs when an error occurs.
acos_op.hpp: avoid use of q (will use it for an order index).
asin_op.hpp: avoid use of q (will use it for an order index).
forward_sweep.hpp: chnage d to p, use const in prototype.
div_op.hpp: minor edit of white space.
atom_usead_2.cpp: use ADFUN to compute variable/parameter information.

  • Property svn:keywords set to Id
File size: 16.7 KB
Line 
1/* $Id: forward0sweep.hpp 2794 2013-05-02 08:20:30Z bradbell $ */
2# ifndef CPPAD_FORWARD0SWEEP_INCLUDED
3# define CPPAD_FORWARD0SWEEP_INCLUDED
4
5/* --------------------------------------------------------------------------
6CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-13 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
16CPPAD_BEGIN_NAMESPACE
17/*!
18\defgroup forward0sweep_hpp forward0sweep.hpp
19\{
20\file forward0sweep.hpp
21Compute zero order forward mode Taylor coefficients.
22*/
23
24/*!
25\def CPPAD_FORWARD0SWEEP_TRACE
26This value is either zero or one.
27Zero is the normal operational value.
28If it is one, a trace of every forward0sweep computation is printed.
29(Note that forward0sweep is not used if CPPAD_USE_FORWARD0SWEEP is zero).
30*/
31# define CPPAD_FORWARD0SWEEP_TRACE 0
32
33/*!
34Compute zero order forward mode Taylor coefficients.
35
36\tparam Base
37The type used during the forward mode computations; i.e., the corresponding
38recording of operations used the type \c AD<Base>.
39
40\param s_out
41Is the stream where output corresponding to \c PriOp operations will
42be written.
43
44\param print
45If \a print is false,
46suppress the output that is otherwise generated by the c PriOp instructions.
47
48\param n
49is the number of independent variables on the tape.
50
51\param numvar
52is the total number of variables on the tape.
53This is also equal to the number of rows in the matrix \a Taylor; i.e.,
54\a Rec->num_rec_var().
55
56\param Rec
57The information stored in \a Rec
58is a recording of the operations corresponding to the function
59\f[
60        F : {\bf R}^n \rightarrow {\bf R}^m
61\f]
62where \f$ n \f$ is the number of independent variables and
63\f$ m \f$ is the number of dependent variables.
64\n
65\n
66The object \a Rec is effectly constant.
67There are two exceptions to this.
68The first exception is that while palying back the tape
69the object \a Rec holds information about the current location
70with in the tape and this changes during palyback.
71The second exception is the fact that the
72zero order ( \a d = 0 ) versions of the VecAD operators LdpOp and LdvOp
73modify the corresponding \a op_arg values returned by
74\ref player::next_forward and \ref player::next_reverse; see the
75\link load_op.hpp LdpOp and LdvOp \endlink operations.
76
77\param J
78Is the number of columns in the coefficient matrix \a Taylor.
79This must be greater than or equal one.
80
81\param Taylor
82\b Input: For j = 1 , ... , \a n,
83\a Taylor [ j * J + 0 ]
84variable with index i on the tape
85(independent variable with index (j-1) in the independent variable vector).
86\n
87\n
88\b Output: For i = \a n + 1, ... , \a numvar - 1,
89\a Taylor [ i * J + 0 ]
90is the zero order Taylor coefficient for the variable with
91index i on the tape.
92
93\a return
94The return value is equal to the number of ComOp operations
95that have a different result from when the information in
96\a Rec was recorded.
97(Note that if NDEBUG is true, there are no ComOp operations
98in Rec and hence this return value is always zero.)
99*/
100
101template <class Base>
102size_t forward0sweep(
103        std::ostream&         s_out,
104        bool                  print,
105        size_t                n,
106        size_t                numvar,
107        player<Base>         *Rec,
108        size_t                J,
109        Base                 *Taylor
110)
111{       CPPAD_ASSERT_UNKNOWN( J >= 1 );
112
113        // op code for current instruction
114        OpCode           op;
115
116        // index for current instruction
117        size_t         i_op;
118
119        // next variables
120        size_t        i_var;
121
122        // constant and non-constant version of the operation argument indices
123        addr_t*         non_const_arg;
124        const addr_t*   arg = CPPAD_NULL;
125
126        // initialize the comparision operator (ComOp) counter
127        size_t compareCount = 0;
128
129        // This is an order zero calculation, initialize vector indices
130        pod_vector<size_t> VectorInd;  // address for each element
131        pod_vector<bool>   VectorVar;  // is element a variable
132        size_t  i = Rec->num_rec_vecad_ind();
133        if( i > 0 )
134        {       VectorInd.extend(i);
135                VectorVar.extend(i);
136                while(i--)
137                {       VectorInd[i] = Rec->GetVecInd(i);
138                        VectorVar[i] = false;
139                }
140        }
141
142        // work space used by UserOp.
143        const size_t user_k = 0;     // order of this forward mode calculation
144        vector<Base> user_tx;        // argument vector Taylor coefficients
145        vector<Base> user_ty;        // result vector Taylor coefficients
146        size_t user_index = 0;       // indentifier for this user_atomic operation
147        size_t user_id    = 0;       // user identifier for this call to operator
148        size_t user_i     = 0;       // index in result vector
149        size_t user_j     = 0;       // index in argument vector
150        size_t user_m     = 0;       // size of result vector
151        size_t user_n     = 0;       // size of arugment vector
152        // next expected operator in a UserOp sequence
153        enum { user_start, user_arg, user_ret, user_end } user_state = user_start;
154
155        // check numvar argument
156        CPPAD_ASSERT_UNKNOWN( Rec->num_rec_var() == numvar );
157
158        // length of the parameter vector (used by CppAD assert macros)
159        const size_t num_par = Rec->num_rec_par();
160
161        // length of the text vector (used by CppAD assert macros)
162        const size_t num_text = Rec->num_rec_text();
163
164        // pointer to the beginning of the parameter vector
165        const Base* parameter = CPPAD_NULL;
166        if( num_par > 0 )
167                parameter = Rec->GetPar();
168
169        // pointer to the beginning of the text vector
170        const char* text = CPPAD_NULL;
171        if( num_text > 0 )
172                text = Rec->GetTxt(0);
173
174        // skip the BeginOp at the beginning of the recording
175        Rec->start_forward(op, arg, i_op, i_var);
176        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
177# if CPPAD_FORWARD0SWEEP_TRACE
178        std::cout << std::endl;
179# endif
180        while(op != EndOp)
181        {
182                // this op
183                Rec->next_forward(op, arg, i_op, i_var);
184# ifndef NDEBUG
185                if( i_op <= n )
186                {       CPPAD_ASSERT_UNKNOWN((op == InvOp) | (op == BeginOp));
187                }
188                else    CPPAD_ASSERT_UNKNOWN((op != InvOp) & (op != BeginOp));
189# endif
190
191                // action to take depends on the case
192                switch( op )
193                {
194                        case AbsOp:
195                        forward_abs_op_0(i_var, arg[0], J, Taylor);
196                        break;
197                        // -------------------------------------------------
198
199                        case AddvvOp:
200                        forward_addvv_op_0(i_var, arg, parameter, J, Taylor);
201                        break;
202                        // -------------------------------------------------
203
204                        case AddpvOp:
205                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
206                        forward_addpv_op_0(i_var, arg, parameter, J, Taylor);
207                        break;
208                        // -------------------------------------------------
209
210                        case AcosOp:
211                        // sqrt(1 - x * x), acos(x)
212                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
213                        forward_acos_op_0(i_var, arg[0], J, Taylor);
214                        break;
215                        // -------------------------------------------------
216
217                        case AsinOp:
218                        // sqrt(1 - x * x), asin(x)
219                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
220                        forward_asin_op_0(i_var, arg[0], J, Taylor);
221                        break;
222                        // -------------------------------------------------
223
224                        case AtanOp:
225                        // 1 + x * x, atan(x)
226                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
227                        forward_atan_op_0(i_var, arg[0], J, Taylor);
228                        break;
229                        // -------------------------------------------------
230
231                        case CSumOp:
232                        // CSumOp has a variable number of arguments and
233                        // next_forward thinks it one has one argument.
234                        // we must inform next_forward of this special case.
235                        Rec->forward_csum(op, arg, i_op, i_var);
236                        forward_csum_op(
237                                0, i_var, arg, num_par, parameter, J, Taylor
238                        );
239                        break;
240
241                        // -------------------------------------------------
242                        case CExpOp:
243                        // Use the general case with d == 0
244                        // (could create an optimzied verison for this case)
245                        forward_cond_op_0(
246                                i_var, arg, num_par, parameter, J, Taylor
247                        );
248                        break;
249                        // ---------------------------------------------------
250                        case ComOp:
251                        forward_comp_op_0(
252                        compareCount, arg, num_par, parameter, J, Taylor
253                        );
254                        break;
255                        // ---------------------------------------------------
256
257                        case CosOp:
258                        // sin(x), cos(x)
259                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
260                        forward_cos_op_0(i_var, arg[0], J, Taylor);
261                        break;
262                        // ---------------------------------------------------
263
264                        case CoshOp:
265                        // sinh(x), cosh(x)
266                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
267                        forward_cosh_op_0(i_var, arg[0], J, Taylor);
268                        break;
269                        // -------------------------------------------------
270
271                        case DisOp:
272                        forward_dis_op_0(i_var, arg, J, Taylor);
273                        break;
274                        // -------------------------------------------------
275
276                        case DivvvOp:
277                        forward_divvv_op_0(i_var, arg, parameter, J, Taylor);
278                        break;
279                        // -------------------------------------------------
280
281                        case DivpvOp:
282                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
283                        forward_divpv_op_0(i_var, arg, parameter, J, Taylor);
284                        break;
285                        // -------------------------------------------------
286
287                        case DivvpOp:
288                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
289                        forward_divvp_op_0(i_var, arg, parameter, J, Taylor);
290                        break;
291                        // -------------------------------------------------
292
293                        case EndOp:
294                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
295                        break;
296                        // -------------------------------------------------
297
298                        case ExpOp:
299                        forward_exp_op_0(i_var, arg[0], J, Taylor);
300                        break;
301                        // -------------------------------------------------
302
303                        case InvOp:
304                        break;
305                        // -------------------------------------------------
306
307                        case LdpOp:
308                        CPPAD_ASSERT_UNKNOWN( VectorInd.size() != 0 );
309                        CPPAD_ASSERT_UNKNOWN( VectorVar.size() != 0 );
310                        non_const_arg = Rec->forward_non_const_arg();
311                        forward_load_p_op_0(
312                                i_var, 
313                                non_const_arg, 
314                                num_par, 
315                                parameter, 
316                                J, 
317                                Taylor,
318                                Rec->num_rec_vecad_ind(),
319                                VectorVar.data(),
320                                VectorInd.data()
321                        );
322                        break;
323                        // -------------------------------------------------
324
325                        case LdvOp:
326                        CPPAD_ASSERT_UNKNOWN( VectorInd.size() != 0 );
327                        CPPAD_ASSERT_UNKNOWN( VectorVar.size() != 0 );
328                        non_const_arg = Rec->forward_non_const_arg();
329                        forward_load_v_op_0(
330                                i_var, 
331                                non_const_arg, 
332                                num_par, 
333                                parameter, 
334                                J, 
335                                Taylor,
336                                Rec->num_rec_vecad_ind(),
337                                VectorVar.data(),
338                                VectorInd.data()
339                        );
340                        break;
341                        // -------------------------------------------------
342
343                        case LogOp:
344                        forward_log_op_0(i_var, arg[0], J, Taylor);
345                        break;
346                        // -------------------------------------------------
347
348                        case MulvvOp:
349                        forward_mulvv_op_0(i_var, arg, parameter, J, Taylor);
350                        break;
351                        // -------------------------------------------------
352
353                        case MulpvOp:
354                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
355                        forward_mulpv_op_0(i_var, arg, parameter, J, Taylor);
356                        break;
357                        // -------------------------------------------------
358
359                        case ParOp:
360                        forward_par_op_0(
361                                i_var, arg, num_par, parameter, J, Taylor
362                        );
363                        break;
364                        // -------------------------------------------------
365
366                        case PowvpOp:
367                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
368                        forward_powvp_op_0(i_var, arg, parameter, J, Taylor);
369                        break;
370                        // -------------------------------------------------
371
372                        case PowpvOp:
373                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
374                        forward_powpv_op_0(i_var, arg, parameter, J, Taylor);
375                        break;
376                        // -------------------------------------------------
377
378                        case PowvvOp:
379                        forward_powvv_op_0(i_var, arg, parameter, J, Taylor);
380                        break;
381                        // -------------------------------------------------
382
383                        case PriOp:
384                        if( print ) forward_pri_0(s_out,
385                                i_var, arg, num_text, text, num_par, parameter, J, Taylor
386                        );
387                        break;
388                        // -------------------------------------------------
389
390                        case SignOp:
391                        // cos(x), sin(x)
392                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
393                        forward_sign_op_0(i_var, arg[0], J, Taylor);
394                        break;
395                        // -------------------------------------------------
396
397                        case SinOp:
398                        // cos(x), sin(x)
399                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
400                        forward_sin_op_0(i_var, arg[0], J, Taylor);
401                        break;
402                        // -------------------------------------------------
403
404                        case SinhOp:
405                        // cosh(x), sinh(x)
406                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
407                        forward_sinh_op_0(i_var, arg[0], J, Taylor);
408                        break;
409                        // -------------------------------------------------
410
411                        case SqrtOp:
412                        forward_sqrt_op_0(i_var, arg[0], J, Taylor);
413                        break;
414                        // -------------------------------------------------
415
416                        case StppOp:
417                        forward_store_pp_op_0(
418                                i_var, 
419                                arg, 
420                                num_par, 
421                                J, 
422                                Taylor,
423                                Rec->num_rec_vecad_ind(),
424                                VectorVar.data(),
425                                VectorInd.data()
426                        );
427                        break;
428                        // -------------------------------------------------
429
430                        case StpvOp:
431                        forward_store_pv_op_0(
432                                i_var, 
433                                arg, 
434                                num_par, 
435                                J, 
436                                Taylor,
437                                Rec->num_rec_vecad_ind(),
438                                VectorVar.data(),
439                                VectorInd.data()
440                        );
441                        break;
442                        // -------------------------------------------------
443
444                        case StvpOp:
445                        forward_store_vp_op_0(
446                                i_var, 
447                                arg, 
448                                num_par, 
449                                J, 
450                                Taylor,
451                                Rec->num_rec_vecad_ind(),
452                                VectorVar.data(),
453                                VectorInd.data()
454                        );
455                        break;
456                        // -------------------------------------------------
457
458                        case StvvOp:
459                        forward_store_vv_op_0(
460                                i_var, 
461                                arg, 
462                                num_par, 
463                                J, 
464                                Taylor,
465                                Rec->num_rec_vecad_ind(),
466                                VectorVar.data(),
467                                VectorInd.data()
468                        );
469                        break;
470                        // -------------------------------------------------
471
472                        case SubvvOp:
473                        forward_subvv_op_0(i_var, arg, parameter, J, Taylor);
474                        break;
475                        // -------------------------------------------------
476
477                        case SubpvOp:
478                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
479                        forward_subpv_op_0(i_var, arg, parameter, J, Taylor);
480                        break;
481                        // -------------------------------------------------
482
483                        case SubvpOp:
484                        CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < num_par );
485                        forward_subvp_op_0(i_var, arg, parameter, J, Taylor);
486                        break;
487                        // -------------------------------------------------
488
489                        case TanOp:
490                        // tan(x)^2, tan(x)
491                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
492                        forward_tan_op_0(i_var, arg[0], J, Taylor);
493                        break;
494                        // -------------------------------------------------
495
496                        case TanhOp:
497                        // tanh(x)^2, tanh(x)
498                        CPPAD_ASSERT_UNKNOWN( i_var < numvar  );
499                        forward_tanh_op_0(i_var, arg[0], J, Taylor);
500                        break;
501                        // -------------------------------------------------
502
503                        case UserOp:
504                        // start or end an atomic operation sequence
505                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
506                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
507                        if( user_state == user_start )
508                        {       user_index = arg[0];
509                                user_id    = arg[1];
510                                user_n     = arg[2];
511                                user_m     = arg[3];
512                                if(user_tx.size() < user_n)
513                                        user_tx.resize(user_n);
514                                if(user_ty.size() < user_m)
515                                        user_ty.resize(user_m);
516                                user_j     = 0;
517                                user_i     = 0;
518                                user_state = user_arg;
519                        }
520                        else
521                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
522                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
523                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
524                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
525                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
526                                user_state = user_start;
527                        }
528                        break;
529
530                        case UsrapOp:
531                        // parameter argument in an atomic operation sequence
532                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
533                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
534                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
535                        user_tx[user_j++] = parameter[ arg[0] ];
536                        if( user_j == user_n )
537                        {       // call users function for this operation
538                                user_atomic<Base>::forward(user_index, user_id, 
539                                        user_k, user_n, user_m, user_tx, user_ty
540                                );
541                                user_state = user_ret;
542                        }
543                        break;
544
545                        case UsravOp:
546                        // variable argument in an atomic operation sequence
547                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
548                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
549                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
550                        user_tx[user_j++] = Taylor[ arg[0] * J + 0 ];
551                        if( user_j == user_n )
552                        {       // call users function for this operation
553                                user_atomic<Base>::forward(user_index, user_id,
554                                        user_k, user_n, user_m, user_tx, user_ty
555                                );
556                                user_state = user_ret;
557                        }
558                        break;
559
560                        case UsrrpOp:
561                        // parameter result in an atomic operation sequence
562                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
563                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
564                        user_i++;
565                        if( user_i == user_m )
566                                user_state = user_end;
567                        break;
568
569                        case UsrrvOp:
570                        // variable result in an atomic operation sequence
571                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
572                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
573                        Taylor[ i_var * J + 0 ] = user_ty[user_i++];
574                        if( user_i == user_m )
575                                user_state = user_end;
576                        break;
577                        // -------------------------------------------------
578
579                        default:
580                        CPPAD_ASSERT_UNKNOWN(0);
581                }
582# if CPPAD_FORWARD0SWEEP_TRACE
583                size_t       d      = 0;
584                size_t       i_tmp  = i_var;
585                Base*        Z_tmp  = Taylor + i_var * J;
586
587                printOp(
588                        std::cout, 
589                        Rec,
590                        i_tmp,
591                        op, 
592                        arg,
593                        d + 1, 
594                        Z_tmp, 
595                        0, 
596                        (Base *) CPPAD_NULL
597                );
598        }
599        std::cout << std::endl;
600# else
601        }
602# endif
603        CPPAD_ASSERT_UNKNOWN( user_state == user_start );
604        CPPAD_ASSERT_UNKNOWN( i_var + 1 == Rec->num_rec_var() );
605
606        return compareCount;
607}
608
609/*! \} */
610CPPAD_END_NAMESPACE
611
612// preprocessor symbols that are local to this file
613# undef CPPAD_FORWARD0SWEEP_TRACE
614
615# endif
Note: See TracBrowser for help on using the repository browser.