source: trunk/cppad/local/for_jac_sweep.hpp @ 3680

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

merge to branch: trunk
from repository: https://github.com/coin-or/CppAD
start hash code: 071875a4beba3363e5fa9752426aec4762cd1caa
end hash code: 0bef506513a519e1073c6279d5c4cba9e5c3b180

commit 0bef506513a519e1073c6279d5c4cba9e5c3b180
Author: Brad Bell <bradbell@…>
Date: Thu May 7 12:14:32 2015 -0700

Add the acosh function (as an atomic operation when defined by compiler).

commit b3264fa17b2f65b65800423a0e243c9c3ccfe06a
Author: Brad Bell <bradbell@…>
Date: Wed May 6 20:25:38 2015 -0700

CMakeLists.txt: Change so test only check for compliation.

commit dcbac4d4f20cc383f2bd9edb02036659df40b791
Author: Brad Bell <bradbell@…>
Date: Wed May 6 15:06:28 2015 -0700

asinh.cpp: check higher orders, relax accuracy on test.

commit 5f8881993fedd18cccc3c74831133a8f8a9d17b0
Author: Brad Bell <bradbell@…>
Date: Wed May 6 14:36:18 2015 -0700

Change Acos to acos.
acos.cpp: remove trailing white space.

commit e828fa1f7c4c3848c727f14b1b7a8030071ee705
Author: Brad Bell <bradbell@…>
Date: Wed May 6 12:07:35 2015 -0700

Change Acos to acos.
acos.cpp: remove redundant index commands, remove trailing with space.

commit 3d16e5b9fe1bdafa4ad01d1d466bb72b792650fa
Author: Brad Bell <bradbell@…>
Date: Wed May 6 11:30:49 2015 -0700

op_code.hpp: Minor edits to AcosOp? commnets.

commit 58beaaad149b4ac29fae44589d7f8900bf8f4c40
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:51:43 2015 -0700

for_jac_sweep.hpp: Add missing AsinhOp? case.

commit 623c134870c522ae5e80bcf0f89d230902594c80
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:27:39 2015 -0700

Fix comment about AsinhOp? operator.

commit 226b14f6f4810f5abf1ca247aae541963efaf4d6
Author: Brad Bell <bradbell@…>
Date: Wed May 6 10:14:08 2015 -0700

Add derivative of F to make order zero case clearer.
acos_reverse.omh: Fix some sign errors.
asin_reverse.omh: Fix typo.
acos_forward.omh: Simplify by distributing minus sign.

commit 4682f4ee73e33b600b180086576e986f636a24dc
Author: Brad Bell <bradbell@…>
Date: Wed May 6 08:15:50 2015 -0700

acos_forward.omh: fix sign that depends on acos versus acosh.

commit 906ae10adf019ddda7f57dd165aab08fc55289c4
Author: Brad Bell <bradbell@…>
Date: Wed May 6 07:09:47 2015 -0700

  1. Fix inclusion of some temporary files in package (e.g., git_commit.sh).
  2. Simplify and improve using git ls-files and ls bin/check_*.
  3. Remove trailing white space.

commit 5096f4706a547bd76caa3766aa2c62802ef7f0bf
Author: Brad Bell <bradbell@…>
Date: Wed May 6 06:41:20 2015 -0700

Combine base type documentation for erf, asinh
(will add more functions to this list list).

commit b3535db5ad95bee90672abcaa686032d23bce2fc
Author: Brad Bell <bradbell@…>
Date: Tue May 5 18:01:11 2015 -0700

  1. Change Arc Cosine/Sine? to Inverse Cosine/Sine?.
  2. Change arcsin-> asin and arccos->acos.
  3. Remove index commands that are duplicates of words in titles.


acos_reverse.omh: Add acosh case to this page.

  • Property svn:keywords set to Id
File size: 20.6 KB
Line 
1/* $Id: for_jac_sweep.hpp 3680 2015-05-07 19:17:37Z bradbell $ */
2# ifndef CPPAD_FOR_JAC_SWEEP_INCLUDED
3# define CPPAD_FOR_JAC_SWEEP_INCLUDED
4/* --------------------------------------------------------------------------
5CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-15 Bradley M. Bell
6
7CppAD is distributed under multiple licenses. This distribution is under
8the terms of the
9                    Eclipse Public License Version 1.0.
10
11A copy of this license is included in the COPYING file of this distribution.
12Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13-------------------------------------------------------------------------- */
14
15# include <set>
16# include <cppad/local/pod_vector.hpp>
17
18namespace CppAD { // BEGIN_CPPAD_NAMESPACE
19/*!
20\file for_jac_sweep.hpp
21Compute Forward mode Jacobian sparsity patterns.
22*/
23
24/*!
25\def CPPAD_FOR_JAC_SWEEP_TRACE
26This value is either zero or one.
27Zero is the normal operational value.
28If it is one, a trace of every for_jac_sweep computation is printed.
29*/
30# define CPPAD_FOR_JAC_SWEEP_TRACE 0
31
32/*
33\def CPPAD_ATOMIC_CALL
34This avoids warnings when NDEBUG is defined and user_ok is not used.
35If \c NDEBUG is defined, this resolves to
36\code
37        user_atom->for_sparse_jac
38\endcode
39otherwise, it respolves to
40\code
41        user_ok = user_atom->for_sparse_jac
42\endcode
43This maco is undefined at the end of this file to facillitate is
44use with a different definition in other files.
45*/
46# ifdef NDEBUG
47# define CPPAD_ATOMIC_CALL user_atom->for_sparse_jac
48# else
49# define CPPAD_ATOMIC_CALL user_ok = user_atom->for_sparse_jac
50# endif
51
52/*!
53Given the sparsity pattern for the independent variables,
54ForJacSweep computes the sparsity pattern for all the other variables.
55
56\tparam Base
57base type for the operator; i.e., this operation sequence was recorded
58using AD< \a Base > and computations by this routine are done using type
59\a Base.
60
61\tparam Vector_set
62is the type used for vectors of sets. It can be either
63\c sparse_pack, \c sparse_set, or \c sparse_list.
64
65\param n
66is the number of independent variables on the tape.
67
68\param numvar
69is the total number of variables on the tape; i.e.,
70\a play->num_var_rec().
71
72\param play
73The information stored in \a play
74is a recording of the operations corresponding to a function
75\f[
76        F : {\bf R}^n \rightarrow {\bf R}^m
77\f]
78where \f$ n \f$ is the number of independent variables
79and \f$ m \f$ is the number of dependent variables.
80The object \a play is effectly constant.
81It is not declared const because while playing back the tape
82the object \a play holds information about the currentl location
83with in the tape and this changes during playback.
84
85\param var_sparsity
86\b Input: For j = 1 , ... , \a n,
87the sparsity pattern for the independent variable with index (j-1)
88corresponds to the set with index j in \a var_sparsity.
89\n
90\n
91\b Output: For i = \a n + 1 , ... , \a numvar - 1,
92the sparsity pattern for the variable with index i on the tape
93corresponds to the set with index i in \a var_sparsity.
94
95\par Checked Assertions:
96\li numvar == var_sparsity.n_set()
97\li numvar == play->num_var_rec()
98*/
99
100template <class Base, class Vector_set>
101void ForJacSweep(
102        size_t                n            ,
103        size_t                numvar       ,
104        player<Base>*         play         ,
105        Vector_set&           var_sparsity )
106{
107        OpCode           op;
108        size_t         i_op;
109        size_t        i_var;
110
111        const addr_t*   arg = CPPAD_NULL;
112
113        size_t            i, j, k;
114
115        // check numvar argument
116        CPPAD_ASSERT_UNKNOWN( play->num_var_rec()  == numvar );
117        CPPAD_ASSERT_UNKNOWN( var_sparsity.n_set() == numvar );
118
119        // length of the parameter vector (used by CppAD assert macros)
120        const size_t num_par = play->num_par_rec();
121
122        // cum_sparsity accumulates sparsity pattern a cummulative sum
123        size_t limit = var_sparsity.end();
124
125        // vecad_sparsity contains a sparsity pattern from each VecAD object
126        // to all the other variables.
127        // vecad_ind maps a VecAD index (the beginning of the
128        // VecAD object) to its from index in vecad_sparsity
129        size_t num_vecad_ind   = play->num_vec_ind_rec();
130        size_t num_vecad_vec   = play->num_vecad_vec_rec();
131        Vector_set  vecad_sparsity;
132        vecad_sparsity.resize(num_vecad_vec, limit);
133        pod_vector<size_t> vecad_ind;
134        if( num_vecad_vec > 0 )
135        {       size_t length;
136                vecad_ind.extend(num_vecad_ind);
137                j             = 0;
138                for(i = 0; i < num_vecad_vec; i++)
139                {       // length of this VecAD
140                        length   = play->GetVecInd(j);
141                        // set to proper index for this VecAD
142                        vecad_ind[j] = i;
143                        for(k = 1; k <= length; k++)
144                                vecad_ind[j+k] = num_vecad_vec; // invalid index
145                        // start of next VecAD
146                        j       += length + 1;
147                }
148                CPPAD_ASSERT_UNKNOWN( j == play->num_vec_ind_rec() );
149        }
150
151        // --------------------------------------------------------------
152        // work space used by UserOp.
153        //
154        typedef std::set<size_t> size_set;
155        size_set::iterator set_itr;  // iterator for a standard set
156        size_set::iterator set_end;  // end of iterator sequence
157        vector< size_set > set_r;    // set sparsity pattern for the argument x
158        vector< size_set > set_s;    // set sparisty pattern for the result y
159        //
160        vector<bool>       bool_r;   // bool sparsity pattern for the argument x
161        vector<bool>       bool_s;   // bool sparisty pattern for the result y
162        //
163        const size_t user_q = limit; // maximum element plus one
164        size_t user_index = 0;       // indentifier for this atomic operation
165        size_t user_id    = 0;       // user identifier for this call to operator
166        size_t user_i     = 0;       // index in result vector
167        size_t user_j     = 0;       // index in argument vector
168        size_t user_m     = 0;       // size of result vector
169        size_t user_n     = 0;       // size of arugment vector
170        //
171        atomic_base<Base>* user_atom = CPPAD_NULL; // user's atomic op calculator
172        bool               user_bool = false;      // use bool or set sparsity ?
173# ifndef NDEBUG
174        bool               user_ok   = false;      // atomic op return value
175# endif
176        //
177        // next expected operator in a UserOp sequence
178        enum { user_start, user_arg, user_ret, user_end } user_state = user_start;
179        // --------------------------------------------------------------
180
181# if CPPAD_FOR_JAC_SWEEP_TRACE
182        std::cout << std::endl;
183        CppAD::vectorBool z_value(limit);
184# endif
185
186        // skip the BeginOp at the beginning of the recording
187        play->forward_start(op, arg, i_op, i_var);
188        CPPAD_ASSERT_UNKNOWN( op == BeginOp );
189        bool more_operators = true;
190        while(more_operators)
191        {
192                // this op
193                play->forward_next(op, arg, i_op, i_var);
194                CPPAD_ASSERT_UNKNOWN( (i_op > n)  | (op == InvOp) );
195                CPPAD_ASSERT_UNKNOWN( (i_op <= n) | (op != InvOp) );
196                CPPAD_ASSERT_ARG_BEFORE_RESULT(op, arg, i_var);
197
198                // rest of information depends on the case
199                switch( op )
200                {
201                        case AbsOp:
202                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
203                        forward_sparse_jacobian_unary_op(
204                                i_var, arg[0], var_sparsity
205                        );
206                        break;
207                        // -------------------------------------------------
208
209                        case AddvvOp:
210                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
211                        forward_sparse_jacobian_binary_op(
212                                i_var, arg, var_sparsity
213                        );
214                        break;
215                        // -------------------------------------------------
216
217                        case AddpvOp:
218                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
219                        forward_sparse_jacobian_unary_op(
220                                i_var, arg[1], var_sparsity
221                        );
222                        break;
223                        // -------------------------------------------------
224
225                        case AcosOp:
226                        // sqrt(1 - x * x), acos(x)
227                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
228                        forward_sparse_jacobian_unary_op(
229                                i_var, arg[0], var_sparsity
230                        );
231                        break;
232                        // -------------------------------------------------
233
234# if CPPAD_COMPILER_HAS_ACOSH
235                        case AcoshOp:
236                        // sqrt(x * x - 1), acosh(x)
237                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
238                        forward_sparse_jacobian_unary_op(
239                                i_var, arg[0], var_sparsity
240                        );
241                        break;
242# endif
243                        // -------------------------------------------------
244
245                        case AsinOp:
246                        // sqrt(1 - x * x), asin(x)
247                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
248                        forward_sparse_jacobian_unary_op(
249                                i_var, arg[0], var_sparsity
250                        );
251                        break;
252                        // -------------------------------------------------
253
254# if CPPAD_COMPILER_HAS_ASINH
255                        case AsinhOp:
256                        // sqrt(1 + x * x), asinh(x)
257                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
258                        forward_sparse_jacobian_unary_op(
259                                i_var, arg[0], var_sparsity
260                        );
261                        break;
262# endif
263                        // -------------------------------------------------
264
265                        case AtanOp:
266                        // 1 + x * x, atan(x)
267                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
268                        forward_sparse_jacobian_unary_op(
269                                i_var, arg[0], var_sparsity
270                        );
271                        break;
272                        // -------------------------------------------------
273
274                        case CSkipOp:
275                        // CSipOp has a variable number of arguments and
276                        // forward_next thinks it has no arguments.
277                        // we must inform forward_next of this special case.
278                        play->forward_cskip(op, arg, i_op, i_var);
279                        break;
280                        // -------------------------------------------------
281
282                        case CSumOp:
283                        // CSumOp has a variable number of arguments and
284                        // forward_next thinks it has no arguments.
285                        // we must inform forward_next of this special case.
286                        forward_sparse_jacobian_csum_op(
287                                i_var, arg, var_sparsity
288                        );
289                        play->forward_csum(op, arg, i_op, i_var);
290                        break;
291                        // -------------------------------------------------
292
293                        case CExpOp:
294                        forward_sparse_jacobian_cond_op(
295                                i_var, arg, num_par, var_sparsity
296                        );
297                        break;
298                        // --------------------------------------------------
299
300                        case CosOp:
301                        // sin(x), cos(x)
302                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
303                        forward_sparse_jacobian_unary_op(
304                                i_var, arg[0], var_sparsity
305                        );
306                        break;
307                        // ---------------------------------------------------
308
309                        case CoshOp:
310                        // sinh(x), cosh(x)
311                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
312                        forward_sparse_jacobian_unary_op(
313                                i_var, arg[0], var_sparsity
314                        );
315                        break;
316                        // -------------------------------------------------
317
318                        case DisOp:
319                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
320                        var_sparsity.clear(i_var);
321                        break;
322                        // -------------------------------------------------
323
324                        case DivvvOp:
325                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
326                        forward_sparse_jacobian_binary_op(
327                                i_var, arg, var_sparsity
328                        );
329                        break;
330                        // -------------------------------------------------
331
332                        case DivpvOp:
333                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
334                        forward_sparse_jacobian_unary_op(
335                                i_var, arg[1], var_sparsity
336                        );
337                        break;
338                        // -------------------------------------------------
339
340                        case DivvpOp:
341                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
342                        forward_sparse_jacobian_unary_op(
343                                i_var, arg[0], var_sparsity
344                        );
345                        break;
346                        // -------------------------------------------------
347
348                        case EndOp:
349                        CPPAD_ASSERT_NARG_NRES(op, 0, 0);
350                        more_operators = false;
351                        break;
352                        // -------------------------------------------------
353
354                        case ErfOp:
355                        // arg[1] is always the parameter 0
356                        // arg[0] is always the parameter 2 / sqrt(pi)
357                        CPPAD_ASSERT_NARG_NRES(op, 3, 5);
358                        forward_sparse_jacobian_unary_op(
359                                i_var, arg[0], var_sparsity
360                        );
361                        break;
362                        // -------------------------------------------------
363
364                        case ExpOp:
365                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
366                        forward_sparse_jacobian_unary_op(
367                                i_var, arg[0], var_sparsity
368                        );
369                        break;
370                        // -------------------------------------------------
371
372                        case InvOp:
373                        CPPAD_ASSERT_NARG_NRES(op, 0, 1);
374                        // sparsity pattern is already defined
375                        break;
376                        // -------------------------------------------------
377
378                        case LdpOp:
379                        forward_sparse_load_op(
380                                op,
381                                i_var,
382                                arg,
383                                num_vecad_ind,
384                                vecad_ind.data(),
385                                var_sparsity,
386                                vecad_sparsity
387                        );
388                        break;
389                        // -------------------------------------------------
390
391                        case LdvOp:
392                        forward_sparse_load_op(
393                                op,
394                                i_var,
395                                arg,
396                                num_vecad_ind,
397                                vecad_ind.data(),
398                                var_sparsity,
399                                vecad_sparsity
400                        );
401                        break;
402                        // -------------------------------------------------
403
404                        case EqpvOp:
405                        case EqvvOp:
406                        case LtpvOp:
407                        case LtvpOp:
408                        case LtvvOp:
409                        case LepvOp:
410                        case LevpOp:
411                        case LevvOp:
412                        case NepvOp:
413                        case NevvOp:
414                        CPPAD_ASSERT_NARG_NRES(op, 2, 0);
415                        break;
416                        // -------------------------------------------------
417
418                        case LogOp:
419                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
420                        forward_sparse_jacobian_unary_op(
421                                i_var, arg[0], var_sparsity
422                        );
423                        break;
424                        // -------------------------------------------------
425
426                        case MulvvOp:
427                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
428                        forward_sparse_jacobian_binary_op(
429                                i_var, arg, var_sparsity
430                        );
431                        break;
432                        // -------------------------------------------------
433
434                        case MulpvOp:
435                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
436                        forward_sparse_jacobian_unary_op(
437                                i_var, arg[1], var_sparsity
438                        );
439                        break;
440                        // -------------------------------------------------
441
442                        case ParOp:
443                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
444                        var_sparsity.clear(i_var);
445                        break;
446                        // -------------------------------------------------
447
448                        case PowvpOp:
449                        CPPAD_ASSERT_NARG_NRES(op, 2, 3);
450                        forward_sparse_jacobian_unary_op(
451                                i_var, arg[0], var_sparsity
452                        );
453                        break;
454                        // -------------------------------------------------
455
456                        case PowpvOp:
457                        CPPAD_ASSERT_NARG_NRES(op, 2, 3);
458                        forward_sparse_jacobian_unary_op(
459                                i_var, arg[1], var_sparsity
460                        );
461                        break;
462                        // -------------------------------------------------
463
464                        case PowvvOp:
465                        CPPAD_ASSERT_NARG_NRES(op, 2, 3);
466                        forward_sparse_jacobian_binary_op(
467                                i_var, arg, var_sparsity
468                        );
469                        break;
470                        // -------------------------------------------------
471
472                        case PriOp:
473                        CPPAD_ASSERT_NARG_NRES(op, 5, 0);
474                        break;
475                        // -------------------------------------------------
476
477                        case SignOp:
478                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
479                        forward_sparse_jacobian_unary_op(
480                                i_var, arg[0], var_sparsity
481                        );
482                        break;
483                        // -------------------------------------------------
484
485                        case SinOp:
486                        // cos(x), sin(x)
487                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
488                        forward_sparse_jacobian_unary_op(
489                                i_var, arg[0], var_sparsity
490                        );
491                        break;
492                        // -------------------------------------------------
493
494                        case SinhOp:
495                        // cosh(x), sinh(x)
496                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
497                        forward_sparse_jacobian_unary_op(
498                                i_var, arg[0], var_sparsity
499                        );
500                        break;
501                        // -------------------------------------------------
502
503                        case SqrtOp:
504                        CPPAD_ASSERT_NARG_NRES(op, 1, 1);
505                        forward_sparse_jacobian_unary_op(
506                                i_var, arg[0], var_sparsity
507                        );
508                        break;
509                        // -------------------------------------------------
510
511                        case StppOp:
512                        CPPAD_ASSERT_NARG_NRES(op, 3, 0);
513                        // storing a parameter does not affect vector sparsity
514                        break;
515                        // -------------------------------------------------
516
517                        case StpvOp:
518                        forward_sparse_store_op(
519                                op,
520                                arg,
521                                num_vecad_ind,
522                                vecad_ind.data(),
523                                var_sparsity,
524                                vecad_sparsity
525                        );
526                        break;
527                        // -------------------------------------------------
528
529                        case StvpOp:
530                        CPPAD_ASSERT_NARG_NRES(op, 3, 0);
531                        // storing a parameter does not affect vector sparsity
532                        break;
533                        // -------------------------------------------------
534
535                        case StvvOp:
536                        forward_sparse_store_op(
537                                op,
538                                arg,
539                                num_vecad_ind,
540                                vecad_ind.data(),
541                                var_sparsity,
542                                vecad_sparsity
543                        );
544                        break;
545                        // -------------------------------------------------
546
547                        case SubvvOp:
548                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
549                        forward_sparse_jacobian_binary_op(
550                                i_var, arg, var_sparsity
551                        );
552                        break;
553                        // -------------------------------------------------
554
555                        case SubpvOp:
556                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
557                        forward_sparse_jacobian_unary_op(
558                                i_var, arg[1], var_sparsity
559                        );
560                        break;
561                        // -------------------------------------------------
562
563                        case SubvpOp:
564                        CPPAD_ASSERT_NARG_NRES(op, 2, 1);
565                        forward_sparse_jacobian_unary_op(
566                                i_var, arg[0], var_sparsity
567                        );
568                        break;
569                        // -------------------------------------------------
570
571                        case TanOp:
572                        // tan(x)^2, tan(x)
573                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
574                        forward_sparse_jacobian_unary_op(
575                                i_var, arg[0], var_sparsity
576                        );
577                        break;
578                        // -------------------------------------------------
579
580                        case TanhOp:
581                        // tanh(x)^2, tanh(x)
582                        CPPAD_ASSERT_NARG_NRES(op, 1, 2);
583                        forward_sparse_jacobian_unary_op(
584                                i_var, arg[0], var_sparsity
585                        );
586                        break;
587                        // -------------------------------------------------
588
589                        case UserOp:
590                        // start or end an atomic operation sequence
591                        CPPAD_ASSERT_UNKNOWN( NumRes( UserOp ) == 0 );
592                        CPPAD_ASSERT_UNKNOWN( NumArg( UserOp ) == 4 );
593                        if( user_state == user_start )
594                        {       user_index = arg[0];
595                                user_id    = arg[1];
596                                user_n     = arg[2];
597                                user_m     = arg[3];
598                                user_atom  = atomic_base<Base>::class_object(user_index);
599# ifndef NDEBUG
600                                if( user_atom == CPPAD_NULL )
601                                {       std::string msg =
602                                                atomic_base<Base>::class_name(user_index)
603                                                + ": atomic_base function has been deleted";
604                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
605                                }
606# endif
607                                user_bool  = user_atom->sparsity() ==
608                                                        atomic_base<Base>::bool_sparsity_enum;
609                                if( user_bool )
610                                {       if( bool_r.size() != user_n * user_q )
611                                                bool_r.resize( user_n * user_q );
612                                        if( bool_s.size() != user_m * user_q )
613                                                bool_s.resize( user_m * user_q );
614                                        for(i = 0; i < user_n; i++)
615                                                for(j = 0; j < user_q; j++)
616                                                        bool_r[ i * user_q + j] = false;
617                                }
618                                else
619                                {       if(set_r.size() != user_n )
620                                                set_r.resize(user_n);
621                                        if(set_s.size() != user_m )
622                                                set_s.resize(user_m);
623                                        for(i = 0; i < user_n; i++)
624                                                set_r[i].clear();
625                                }
626                                user_j     = 0;
627                                user_i     = 0;
628                                user_state = user_arg;
629                        }
630                        else
631                        {       CPPAD_ASSERT_UNKNOWN( user_state == user_end );
632                                CPPAD_ASSERT_UNKNOWN( user_index == size_t(arg[0]) );
633                                CPPAD_ASSERT_UNKNOWN( user_id    == size_t(arg[1]) );
634                                CPPAD_ASSERT_UNKNOWN( user_n     == size_t(arg[2]) );
635                                CPPAD_ASSERT_UNKNOWN( user_m     == size_t(arg[3]) );
636# ifndef NDEBUG
637                                if( ! user_ok )
638                                {       std::string msg =
639                                                atomic_base<Base>::class_name(user_index)
640                                                + ": atomic_base.for_sparse_jac: returned false";
641                                        CPPAD_ASSERT_KNOWN(false, msg.c_str() );
642                                }
643# endif
644                                user_state = user_start;
645                        }
646                        break;
647
648                        case UsrapOp:
649                        // parameter argument in an atomic operation sequence
650                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
651                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
652                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_par );
653                        // set row user_j to empty sparsity pattern
654                        ++user_j;
655                        if( user_j == user_n )
656                        {       // call users function for this operation
657                                user_atom->set_id(user_id);
658                                if( user_bool )
659                                        CPPAD_ATOMIC_CALL(
660                                                user_q, bool_r, bool_s
661                                );
662                                else
663                                        CPPAD_ATOMIC_CALL(
664                                                user_q, set_r, set_s
665                                );
666                                user_state = user_ret;
667                        }
668                        break;
669
670                        case UsravOp:
671                        // variable argument in an atomic operation sequence
672                        CPPAD_ASSERT_UNKNOWN( user_state == user_arg );
673                        CPPAD_ASSERT_UNKNOWN( user_j < user_n );
674                        CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) <= i_var );
675                        // set row user_j to sparsity pattern for variable arg[0]
676                        var_sparsity.begin(arg[0]);
677                        i = var_sparsity.next_element();
678                        while( i < user_q )
679                        {       if( user_bool )
680                                        bool_r[user_j * user_q + i] = true;
681                                else
682                                        set_r[user_j].insert(i);
683                                i = var_sparsity.next_element();
684                        }
685                        ++user_j;
686                        if( user_j == user_n )
687                        {       // call users function for this operation
688                                user_atom->set_id(user_id);
689                                if( user_bool )
690                                        CPPAD_ATOMIC_CALL(
691                                                user_q, bool_r, bool_s
692                                );
693                                else
694                                        CPPAD_ATOMIC_CALL(
695                                                user_q, set_r, set_s
696                                );
697                                user_state = user_ret;
698                        }
699                        break;
700
701                        case UsrrpOp:
702                        // parameter result in an atomic operation sequence
703                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
704                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
705                        user_i++;
706                        if( user_i == user_m )
707                                user_state = user_end;
708                        break;
709
710                        case UsrrvOp:
711                        // variable result in an atomic operation sequence
712                        CPPAD_ASSERT_UNKNOWN( user_state == user_ret );
713                        CPPAD_ASSERT_UNKNOWN( user_i < user_m );
714                        // It might be faster if we add set union to var_sparsity
715                        // where one of the sets is not in var_sparsity
716                        if( user_bool )
717                        {       for(j = 0; j < user_q; j++)
718                                        if( bool_s[ user_i * user_q + j ] )
719                                                var_sparsity.add_element(i_var, j);
720                        }
721                        else
722                        {       set_itr = set_s[user_i].begin();
723                                set_end = set_s[user_i].end();
724                                while( set_itr != set_end )
725                                        var_sparsity.add_element(i_var, *set_itr++);
726                        }
727                        user_i++;
728                        if( user_i == user_m )
729                                user_state = user_end;
730                        break;
731                        // -------------------------------------------------
732
733                        default:
734                        CPPAD_ASSERT_UNKNOWN(0);
735                }
736# if CPPAD_FOR_JAC_SWEEP_TRACE
737                const addr_t*   arg_tmp = arg;
738                if( op == CSumOp )
739                        arg_tmp = arg - arg[-1] - 4;
740                if( op == CSkipOp )
741                        arg_tmp = arg - arg[-1] - 7;
742                //
743                // value for this variable
744                for(j = 0; j < limit; j++)
745                        z_value[j] = false;
746                var_sparsity.begin(i_var);
747                j = var_sparsity.next_element();
748                while( j < limit )
749                {       z_value[j] = true;
750                        j = var_sparsity.next_element();
751                }
752                printOp(
753                        std::cout,
754                        play,
755                        i_op,
756                        i_var,
757                        op,
758                        arg_tmp
759                );
760                if( NumRes(op) > 0 ) printOpResult(
761                        std::cout,
762                        1,
763                        &z_value,
764                        0,
765                        (CppAD::vectorBool *) CPPAD_NULL
766                );
767                std::cout << std::endl;
768        }
769        std::cout << std::endl;
770# else
771        }
772# endif
773        CPPAD_ASSERT_UNKNOWN( i_var + 1 == play->num_var_rec() );
774
775        return;
776}
777
778} // END_CPPAD_NAMESPACE
779
780// preprocessor symbols that are local to this file
781# undef CPPAD_FOR_JAC_SWEEP_TRACE
782# undef CPPAD_ATOMIC_CALL
783
784# endif
Note: See TracBrowser for help on using the repository browser.