CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
old_atomic.hpp
Go to the documentation of this file.
1 # ifndef CPPAD_CORE_OLD_ATOMIC_HPP
2 # define CPPAD_CORE_OLD_ATOMIC_HPP
3 /* --------------------------------------------------------------------------
4 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
5 
6 CppAD is distributed under multiple licenses. This distribution is under
7 the terms of the
8  Eclipse Public License Version 1.0.
9 
10 A copy of this license is included in the COPYING file of this distribution.
11 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
12 -------------------------------------------------------------------------- */
13 /*
14 $begin old_atomic$$
15 $spell
16  hes
17  std
18  Jacobian
19  jac
20  Tvector
21  afun
22  vx
23  vy
24  bool
25  namespace
26  CppAD
27  const
28  Taylor
29  tx
30  ty
31  px
32  py
33 $$
34 
35 $section User Defined Atomic AD Functions$$
36 $mindex operation old_atomic$$
37 
38 $head Deprecated 2013-05-27$$
39 Using $code CPPAD_USER_ATOMIC$$ has been deprecated.
40 Use $cref atomic_base$$ instead.
41 
42 $head Syntax Function$$
43 $codei%CPPAD_USER_ATOMIC(%afun%, %Tvector%, %Base%,
44  %forward%, %reverse%, %for_jac_sparse%, %rev_jac_sparse%, %rev_hes_sparse%
45 )
46 %$$
47 
48 $subhead Use Function$$
49 $icode%afun%(%id%, %ax%, %ay%)
50 %$$
51 
52 $subhead Callback Routines$$
53 $icode%ok% = %forward%(%id%, %k%, %n%, %m%, %vx%, %vy%, %tx%, %ty%)
54 %$$
55 $icode%ok% = %reverse%(%id%, %k%, %n%, %m%, %tx%, %ty%, %px%, %py%)
56 %$$
57 $icode%ok% = %for_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%)
58 %$$
59 $icode%ok% = %rev_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%)
60 %$$
61 $icode%ok% = %rev_hes_sparse%(%id%, %n%, %m%, %q%, %r%, %s%, %t%, %u%, %v%)
62 %$$
63 
64 $subhead Free Static Memory$$
65 $codei%user_atomic<%Base%>::clear()%$$
66 
67 $head Purpose$$
68 In some cases, the user knows how to compute the derivative
69 of a function
70 $latex \[
71  y = f(x) \; {\rm where} \; f : B^n \rightarrow B^m
72 \] $$
73 more efficiently than by coding it using $codei%AD<%Base%>%$$
74 $cref/atomic/glossary/Operation/Atomic/$$ operations
75 and letting CppAD do the rest.
76 In this case, $code CPPAD_USER_ATOMIC$$ can be used
77 add the user code for $latex f(x)$$, and its derivatives,
78 to the set of $codei%AD<%Base%>%$$ atomic operations.
79 $pre
80 
81 $$
82 Another possible purpose is to reduce the size of the tape;
83 see $cref/use AD/old_atomic/Example/Use AD/$$
84 
85 $head Partial Implementation$$
86 The routines
87 $cref/forward/old_atomic/forward/$$,
88 $cref/reverse/old_atomic/reverse/$$,
89 $cref/for_jac_sparse/old_atomic/for_jac_sparse/$$,
90 $cref/rev_jac_sparse/old_atomic/rev_jac_sparse/$$, and
91 $cref/rev_hes_sparse/old_atomic/rev_hes_sparse/$$,
92 must be defined by the user.
93 The $icode forward$$ the routine,
94 for the case $icode%k% = 0%$$, must be implemented.
95 Functions with the correct prototype,
96 that just return $code false$$,
97 can be used for the other cases
98 (unless they are required by your calculations).
99 For example, you need not implement
100 $icode forward$$ for the case $icode%k% == 2%$$ until you require
101 forward mode calculation of second derivatives.
102 
103 $head CPPAD_USER_ATOMIC$$
104 The macro
105 $codei%
106 CPPAD_USER_ATOMIC(%afun%, %Tvector%, %Base%,
107  %forward%, %reverse%, %for_jac_sparse%, %rev_jac_sparse%, %rev_hes_sparse%
108 )
109 %$$
110 defines the $codei%AD<%Base%>%$$ routine $icode afun$$.
111 This macro can be placed within a namespace
112 (not the $code CppAD$$ namespace)
113 but must be outside of any routine.
114 
115 $subhead Tvector$$
116 The macro argument $icode Tvector$$ must be a
117 $cref/simple vector template class/SimpleVector/$$.
118 It determines the type of vectors used as arguments to the routine
119 $icode afun$$.
120 
121 $subhead Base$$
122 The macro argument $icode Base$$ specifies the
123 $cref/base type/base_require/$$
124 corresponding to $codei%AD<%Base>%$$ operation sequences.
125 Calling the routine $icode afun$$ will add the operator defined
126 by this macro to an $codei%AD<%Base>%$$ operation sequence.
127 
128 $head ok$$
129 For all routines documented below,
130 the return value $icode ok$$ has prototype
131 $codei%
132  bool %ok%
133 %$$
134 If it is $code true$$, the corresponding evaluation succeeded,
135 otherwise it failed.
136 
137 $head id$$
138 For all routines documented below,
139 the argument $icode id$$ has prototype
140 $codei%
141  size_t %id%
142 %$$
143 Its value in all other calls is the same as in the corresponding
144 call to $icode afun$$.
145 It can be used to store and retrieve extra information about
146 a specific call to $icode afun$$.
147 
148 $head k$$
149 For all routines documented below, the argument $icode k$$ has prototype
150 $codei%
151  size_t %k%
152 %$$
153 The value $icode%k%$$ is the order of the Taylor coefficient that
154 we are evaluating ($cref/forward/old_atomic/forward/$$)
155 or taking the derivative of ($cref/reverse/old_atomic/reverse/$$).
156 
157 $head n$$
158 For all routines documented below,
159 the argument $icode n$$ has prototype
160 $codei%
161  size_t %n%
162 %$$
163 It is the size of the vector $icode ax$$ in the corresponding call to
164 $icode%afun%(%id%, %ax%, %ay%)%$$; i.e.,
165 the dimension of the domain space for $latex y = f(x)$$.
166 
167 $head m$$
168 For all routines documented below, the argument $icode m$$ has prototype
169 $codei%
170  size_t %m%
171 %$$
172 It is the size of the vector $icode ay$$ in the corresponding call to
173 $icode%afun%(%id%, %ax%, %ay%)%$$; i.e.,
174 the dimension of the range space for $latex y = f(x)$$.
175 
176 $head tx$$
177 For all routines documented below,
178 the argument $icode tx$$ has prototype
179 $codei%
180  const CppAD::vector<%Base%>& %tx%
181 %$$
182 and $icode%tx%.size() >= (%k% + 1) * %n%$$.
183 For $latex j = 0 , \ldots , n-1$$ and $latex \ell = 0 , \ldots , k$$,
184 we use the Taylor coefficient notation
185 $latex \[
186 \begin{array}{rcl}
187  x_j^\ell & = & tx [ j * ( k + 1 ) + \ell ]
188  \\
189  X_j (t) & = & x_j^0 + x_j^1 t^1 + \cdots + x_j^k t^k
190 \end{array}
191 \] $$
192 If $icode%tx%.size() > (%k% + 1) * %n%$$,
193 the other components of $icode tx$$ are not specified and should not be used.
194 Note that superscripts represent an index for $latex x_j^\ell$$
195 and an exponent for $latex t^\ell$$.
196 Also note that the Taylor coefficients for $latex X(t)$$ correspond
197 to the derivatives of $latex X(t)$$ at $latex t = 0$$ in the following way:
198 $latex \[
199  x_j^\ell = \frac{1}{ \ell ! } X_j^{(\ell)} (0)
200 \] $$
201 
202 $head ty$$
203 In calls to $cref/forward/old_atomic/forward/$$,
204 the argument $icode ty$$ has prototype
205 $codei%
206  CppAD::vector<%Base%>& %ty%
207 %$$
208 while in calls to $cref/reverse/old_atomic/reverse/$$ it has prototype
209 $codei%
210  const CppAD::vector<%Base%>& %ty%
211 %$$
212 For all calls, $icode%tx%.size() >= (%k% + 1) * %m%$$.
213 For $latex i = 0 , \ldots , m-1$$ and $latex \ell = 0 , \ldots , k$$,
214 we use the Taylor coefficient notation
215 $latex \[
216 \begin{array}{rcl}
217  y_i^\ell & = & ty [ i * ( k + 1 ) + \ell ]
218  \\
219  Y_i (t) & = & y_i^0 + y_i^1 t^1 + \cdots + y_i^k t^k + o ( t^k )
220 \end{array}
221 \] $$
222 where $latex o( t^k ) / t^k \rightarrow 0$$ as $latex t \rightarrow 0$$.
223 If $icode%ty%.size() > (%k% + 1) * %m%$$,
224 the other components of $icode ty$$ are not specified and should not be used.
225 Note that superscripts represent an index for $latex y_j^\ell$$
226 and an exponent for $latex t^\ell$$.
227 Also note that the Taylor coefficients for $latex Y(t)$$ correspond
228 to the derivatives of $latex Y(t)$$ at $latex t = 0$$ in the following way:
229 $latex \[
230  y_j^\ell = \frac{1}{ \ell ! } Y_j^{(\ell)} (0)
231 \] $$
232 
233 $subhead forward$$
234 In the case of $icode forward$$,
235 for $latex i = 0 , \ldots , m-1$$, $latex ty[ i *( k + 1) + k ]$$ is an output
236 and all the other components of $icode ty$$ are inputs.
237 
238 $subhead reverse$$
239 In the case of $icode reverse$$,
240 all the components of $icode ty$$ are inputs.
241 
242 $head afun$$
243 The macro argument $icode afun$$,
244 is the name of the AD function corresponding to this atomic
245 operation (as it is used in the source code).
246 CppAD uses the other functions,
247 where the arguments are vectors with elements of type $icode Base$$,
248 to implement the function
249 $codei%
250  %afun%(%id%, %ax%, %ay%)
251 %$$
252 where the argument are vectors with elements of type $codei%AD<%Base%>%$$.
253 
254 $subhead ax$$
255 The $icode afun$$ argument $icode ax$$ has prototype
256 $codei%
257  const %Tvector%< AD<%Base%> >& %ax%
258 %$$
259 It is the argument vector $latex x \in B^n$$
260 at which the $codei%AD<%Base%>%$$ version of
261 $latex y = f(x)$$ is to be evaluated.
262 The dimension of the domain space for $latex y = f (x)$$
263 is specified by $cref/n/old_atomic/n/$$ $codei%= %ax%.size()%$$,
264 which must be greater than zero.
265 
266 $subhead ay$$
267 The $icode afun$$ result $icode ay$$ has prototype
268 $codei%
269  %Tvector%< AD<%Base%> >& %ay%
270 %$$
271 The input values of its elements
272 are not specified (must not matter).
273 Upon return, it is the $codei%AD<%Base%>%$$ version of the
274 result vector $latex y = f(x)$$.
275 The dimension of the range space for $latex y = f (x)$$
276 is specified by $cref/m/old_atomic/m/$$ $codei%= %ay%.size()%$$,
277 which must be greater than zero.
278 
279 $subhead Parallel Mode$$
280 The first call to
281 $codei%
282  %afun%(%id%, %ax%, %ay%)
283 %$$
284 must not be in $cref/parallel/ta_in_parallel/$$ mode.
285 In addition, the
286 $cref/old_atomic clear/old_atomic/clear/$$
287 routine cannot be called while in parallel mode.
288 
289 $head forward$$
290 The macro argument $icode forward$$ is a
291 user defined function
292 $codei%
293  %ok% = %forward%(%id%, %k%, %n%, %m%, %vx%, %vy%, %tx%, %ty%)
294 %$$
295 that computes results during a $cref/forward/Forward/$$ mode sweep.
296 For this call, we are given the Taylor coefficients in $icode tx$$
297 form order zero through $icode k$$,
298 and the Taylor coefficients in $icode ty$$ with order less than $icode k$$.
299 The $icode forward$$ routine computes the
300 $icode k$$ order Taylor coefficients for $latex y$$ using the definition
301 $latex Y(t) = f[ X(t) ]$$.
302 For example, for $latex i = 0 , \ldots , m-1$$,
303 $latex \[
304 \begin{array}{rcl}
305 y_i^0 & = & Y(0)
306  = f_i ( x^0 )
307 \\
308 y_i^1 & = & Y^{(1)} ( 0 )
309  = f_i^{(1)} ( x^0 ) X^{(1)} ( 0 )
310  = f_i^{(1)} ( x^0 ) x^1
311 \\
312 y_i^2
313 & = & \frac{1}{2 !} Y^{(2)} (0)
314 \\
315 & = & \frac{1}{2} X^{(1)} (0)^\R{T} f_i^{(2)} ( x^0 ) X^{(1)} ( 0 )
316  + \frac{1}{2} f_i^{(1)} ( x^0 ) X^{(2)} ( 0 )
317 \\
318 & = & \frac{1}{2} (x^1)^\R{T} f_i^{(2)} ( x^0 ) x^1
319  + f_i^{(1)} ( x^0 ) x^2
320 \end{array}
321 \] $$
322 Then, for $latex i = 0 , \ldots , m-1$$, it sets
323 $latex \[
324  ty [ i * (k + 1) + k ] = y_i^k
325 \] $$
326 The other components of $icode ty$$ must be left unchanged.
327 
328 $subhead Usage$$
329 This routine is used,
330 with $icode%vx%.size() > 0%$$ and $icode%k% == 0%$$,
331 by calls to $icode afun$$.
332 It is used,
333 with $icode%vx%.size() = 0%$$ and
334 $icode k$$ equal to the order of the derivative begin computed,
335 by calls to $cref/forward/forward_order/$$.
336 
337 $subhead vx$$
338 The $icode forward$$ argument $icode vx$$ has prototype
339 $codei%
340  const CppAD::vector<bool>& %vx%
341 %$$
342 The case $icode%vx%.size() > 0%$$ occurs
343 once for each call to $icode afun$$,
344 during the call,
345 and before any of the other callbacks corresponding to that call.
346 Hence such a call can be used to cache information attached to
347 the corresponding $icode id$$
348 (such as the elements of $icode vx$$).
349 If $icode%vx%.size() > 0%$$ then
350 $icode%k% == 0%$$,
351 $icode%vx%.size() >= %n%$$, and
352 for $latex j = 0 , \ldots , n-1$$,
353 $icode%vx%[%j%]%$$ is true if and only if
354 $icode%ax%[%j%]%$$ is a $cref/variable/glossary/Variable/$$.
355 $pre
356 
357 $$
358 If $icode%vx%.size() == 0%$$,
359 then $icode%vy%.size() == 0%$$ and neither of these vectors
360 should be used.
361 
362 $subhead vy$$
363 The $icode forward$$ argument $icode vy$$ has prototype
364 $codei%
365  CppAD::vector<bool>& %vy%
366 %$$
367 If $icode%vy%.size() == 0%$$, it should not be used.
368 Otherwise,
369 $icode%k% == 0%$$ and $icode%vy%.size() >= %m%$$.
370 The input values of the elements of $icode vy$$
371 are not specified (must not matter).
372 Upon return, for $latex j = 0 , \ldots , m-1$$,
373 $icode%vy%[%i%]%$$ is true if and only if
374 $icode%ay%[%j%]%$$ is a variable.
375 (CppAD uses $icode vy$$ to reduce the necessary computations.)
376 
377 $head reverse$$
378 The macro argument $icode reverse$$
379 is a user defined function
380 $codei%
381  %ok% = %reverse%(%id%, %k%, %n%, %m%, %tx%, %ty%, %px%, %py%)
382 %$$
383 that computes results during a $cref/reverse/Reverse/$$ mode sweep.
384 The input value of the vectors $icode tx$$ and $icode ty$$
385 contain Taylor coefficient, up to order $icode k$$,
386 for $latex X(t)$$ and $latex Y(t)$$ respectively.
387 We use the $latex \{ x_j^\ell \}$$ and $latex \{ y_i^\ell \}$$
388 to denote these Taylor coefficients where the implicit range indices are
389 $latex i = 0 , \ldots , m-1$$,
390 $latex j = 0 , \ldots , n-1$$,
391 $latex \ell = 0 , \ldots , k$$.
392 Using the calculations done by $cref/forward/old_atomic/forward/$$,
393 the Taylor coefficients $latex \{ y_i^\ell \}$$ are a function of the Taylor
394 coefficients for $latex \{ x_j^\ell \}$$; i.e., given $latex y = f(x)$$
395 we define the function
396 $latex F : B^{n \times (k+1)} \rightarrow B^{m \times (k+1)}$$ by
397 $latex \[
398 y_i^\ell = F_i^\ell ( \{ x_j^\ell \} )
399 \] $$
400 We use $latex G : B^{m \times (k+1)} \rightarrow B$$
401 to denote an arbitrary scalar valued function of the Taylor coefficients for
402 $latex Y(t)$$ and write $latex z = G( \{ y_i^\ell \} )$$.
403 The $code reverse$$ routine
404 is given the derivative of $latex z$$ with respect to
405 $latex \{ y_i^\ell \}$$ and computes its derivative with respect
406 to $latex \{ x_j^\ell \}$$.
407 
408 $subhead Usage$$
409 This routine is used,
410 with $icode%k% + 1%$$ equal to the order of the derivative being calculated,
411 by calls to $cref/reverse/reverse_any/$$.
412 
413 $subhead py$$
414 The $icode reverse$$ argument $icode py$$ has prototype
415 $codei%
416  const CppAD::vector<%Base%>& %py%
417 %$$
418 and $icode%py%.size() >= (%k% + 1) * %m%$$.
419 For $latex i = 0 , \ldots , m-1$$ and $latex \ell = 0 , \ldots , k$$,
420 $latex \[
421  py[ i * (k + 1 ) + \ell ] = \partial G / \partial y_i^\ell
422 \] $$
423 If $icode%py%.size() > (%k% + 1) * %m%$$,
424 the other components of $icode py$$ are not specified and should not be used.
425 
426 $subhead px$$
427 We define the function
428 $latex \[
429 H ( \{ x_j^\ell \} ) = G[ F( \{ x_j^\ell \} ) ]
430 \] $$
431 The $icode reverse$$ argument $icode px$$ has prototype
432 $codei%
433  CppAD::vector<%Base%>& %px%
434 %$$
435 and $icode%px%.size() >= (%k% + 1) * %n%$$.
436 The input values of the elements of $icode px$$
437 are not specified (must not matter).
438 Upon return,
439 for $latex j = 0 , \ldots , n-1$$ and $latex p = 0 , \ldots , k$$,
440 $latex \[
441 \begin{array}{rcl}
442 px [ j * (k + 1) + p ] & = & \partial H / \partial x_j^p
443 \\
444 & = &
445 ( \partial G / \partial \{ y_i^\ell \} )
446  ( \partial \{ y_i^\ell \} / \partial x_j^p )
447 \\
448 & = &
449 \sum_{i=0}^{m-1} \sum_{\ell=0}^k
450 ( \partial G / \partial y_i^\ell ) ( \partial y_i^\ell / \partial x_j^p )
451 \\
452 & = &
453 \sum_{i=0}^{m-1} \sum_{\ell=p}^k
454 py[ i * (k + 1 ) + \ell ] ( \partial F_i^\ell / \partial x_j^p )
455 \end{array}
456 \] $$
457 Note that we have used the fact that for $latex \ell < p$$,
458 $latex \partial F_i^\ell / \partial x_j^p = 0$$.
459 If $icode%px%.size() > (%k% + 1) * %n%$$,
460 the other components of $icode px$$ are not specified and should not be used.
461 
462 $head for_jac_sparse$$
463 The macro argument $icode for_jac_sparse$$
464 is a user defined function
465 $codei%
466  %ok% = %for_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%)
467 %$$
468 that is used to compute results during a forward Jacobian sparsity sweep.
469 For a fixed $latex n \times q$$ matrix $latex R$$,
470 the Jacobian of $latex f( x + R * u)$$ with respect to $latex u \in B^q$$ is
471 $latex \[
472  S(x) = f^{(1)} (x) * R
473 \] $$
474 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex R$$,
475 $icode for_jac_sparse$$ computes a sparsity pattern for $latex S(x)$$.
476 
477 $subhead Usage$$
478 This routine is used by calls to $cref ForSparseJac$$.
479 
480 $subhead q$$
481 The $icode for_jac_sparse$$ argument $icode q$$ has prototype
482 $codei%
483  size_t %q%
484 %$$
485 It specifies the number of columns in
486 $latex R \in B^{n \times q}$$ and the Jacobian
487 $latex S(x) \in B^{m \times q}$$.
488 
489 $subhead r$$
490 The $icode for_jac_sparse$$ argument $icode r$$ has prototype
491 $codei%
492  const CppAD::vector< std::set<size_t> >& %r%
493 %$$
494 and $icode%r%.size() >= %n%$$.
495 For $latex j = 0 , \ldots , n-1$$,
496 all the elements of $icode%r%[%j%]%$$ are between
497 zero and $icode%q%-1%$$ inclusive.
498 This specifies a sparsity pattern for the matrix $latex R$$.
499 
500 $subhead s$$
501 The $icode for_jac_sparse$$ return value $icode s$$ has prototype
502 $codei%
503  CppAD::vector< std::set<size_t> >& %s%
504 %$$
505 and $icode%s%.size() >= %m%%$$.
506 The input values of its sets
507 are not specified (must not matter). Upon return
508 for $latex i = 0 , \ldots , m-1$$,
509 all the elements of $icode%s%[%i%]%$$ are between
510 zero and $icode%q%-1%$$ inclusive.
511 This represents a sparsity pattern for the matrix $latex S(x)$$.
512 
513 $head rev_jac_sparse$$
514 The macro argument $icode rev_jac_sparse$$
515 is a user defined function
516 $codei%
517  %ok% = %rev_jac_sparse%(%id%, %n%, %m%, %q%, %r%, %s%)
518 %$$
519 that is used to compute results during a reverse Jacobian sparsity sweep.
520 For a fixed $latex q \times m$$ matrix $latex S$$,
521 the Jacobian of $latex S * f( x )$$ with respect to $latex x \in B^n$$ is
522 $latex \[
523  R(x) = S * f^{(1)} (x)
524 \] $$
525 Given a $cref/sparsity pattern/glossary/Sparsity Pattern/$$ for $latex S$$,
526 $icode rev_jac_sparse$$ computes a sparsity pattern for $latex R(x)$$.
527 
528 $subhead Usage$$
529 This routine is used by calls to $cref RevSparseJac$$
530 and to $cref optimize$$.
531 
532 
533 $subhead q$$
534 The $icode rev_jac_sparse$$ argument $icode q$$ has prototype
535 $codei%
536  size_t %q%
537 %$$
538 It specifies the number of rows in
539 $latex S \in B^{q \times m}$$ and the Jacobian
540 $latex R(x) \in B^{q \times n}$$.
541 
542 $subhead s$$
543 The $icode rev_jac_sparse$$ argument $icode s$$ has prototype
544 $codei%
545  const CppAD::vector< std::set<size_t> >& %s%
546 %$$
547 and $icode%s%.size() >= %m%$$.
548 For $latex i = 0 , \ldots , m-1$$,
549 all the elements of $icode%s%[%i%]%$$
550 are between zero and $icode%q%-1%$$ inclusive.
551 This specifies a sparsity pattern for the matrix $latex S^\R{T}$$.
552 
553 $subhead r$$
554 The $icode rev_jac_sparse$$ return value $icode r$$ has prototype
555 $codei%
556  CppAD::vector< std::set<size_t> >& %r%
557 %$$
558 and $icode%r%.size() >= %n%$$.
559 The input values of its sets
560 are not specified (must not matter).
561 Upon return for $latex j = 0 , \ldots , n-1$$,
562 all the elements of $icode%r%[%j%]%$$
563 are between zero and $icode%q%-1%$$ inclusive.
564 This represents a sparsity pattern for the matrix $latex R(x)^\R{T}$$.
565 
566 $head rev_hes_sparse$$
567 The macro argument $icode rev_hes_sparse$$
568 is a user defined function
569 $codei%
570  %ok% = %rev_hes_sparse%(%id%, %n%, %m%, %q%, %r%, %s%, %t%, %u%, %v%)
571 %$$
572 There is an unspecified scalar valued function
573 $latex g : B^m \rightarrow B$$.
574 Given a sparsity pattern for $latex R$$
575 and information about the function $latex z = g(y)$$,
576 this routine computes the sparsity pattern for
577 $latex \[
578  V(x) = (g \circ f)^{(2)}( x ) R
579 \] $$
580 
581 $subhead Usage$$
582 This routine is used by calls to $cref RevSparseHes$$.
583 
584 $subhead q$$
585 The $icode rev_hes_sparse$$ argument $icode q$$ has prototype
586 $codei%
587  size_t %q%
588 %$$
589 It specifies the number of columns in the sparsity patterns.
590 
591 $subhead r$$
592 The $icode rev_hes_sparse$$ argument $icode r$$ has prototype
593 $codei%
594  const CppAD::vector< std::set<size_t> >& %r%
595 %$$
596 and $icode%r%.size() >= %n%$$.
597 For $latex j = 0 , \ldots , n-1$$,
598 all the elements of $icode%r%[%j%]%$$ are between
599 zero and $icode%q%-1%$$ inclusive.
600 This specifies a sparsity pattern for the matrix $latex R \in B^{n \times q}$$.
601 
602 $subhead s$$
603 The $icode rev_hes_sparse$$ argument $icode s$$ has prototype
604 $codei%
605  const CppAD::vector<bool>& %s%
606 %$$
607 and $icode%s%.size() >= %m%$$.
608 This specifies a sparsity pattern for the matrix
609 $latex S(x) = g^{(1)} (y) \in B^{1 \times m}$$.
610 
611 $subhead t$$
612 The $icode rev_hes_sparse$$ argument $icode t$$ has prototype
613 $codei%
614  CppAD::vector<bool>& %t%
615 %$$
616 and $icode%t%.size() >= %n%$$.
617 The input values of its elements
618 are not specified (must not matter).
619 Upon return it represents a sparsity pattern for the matrix
620 $latex T(x) \in B^{1 \times n}$$ defined by
621 $latex \[
622 T(x) = (g \circ f)^{(1)} (x) = S(x) * f^{(1)} (x)
623 \] $$
624 
625 $subhead u$$
626 The $icode rev_hes_sparse$$ argument $icode u$$ has prototype
627 $codei%
628  const CppAD::vector< std::set<size_t> >& %u%
629 %$$
630 and $icode%u%.size() >= %m%$$.
631 For $latex i = 0 , \ldots , m-1$$,
632 all the elements of $icode%u%[%i%]%$$
633 are between zero and $icode%q%-1%$$ inclusive.
634 This specifies a sparsity pattern
635 for the matrix $latex U(x) \in B^{m \times q}$$ defined by
636 $latex \[
637 \begin{array}{rcl}
638 U(x)
639 & = &
640 \partial_u \{ \partial_y g[ y + f^{(1)} (x) R u ] \}_{u=0}
641 \\
642 & = &
643 \partial_u \{ g^{(1)} [ y + f^{(1)} (x) R u ] \}_{u=0}
644 \\
645 & = &
646 g^{(2)} (y) f^{(1)} (x) R
647 \end{array}
648 \] $$
649 
650 $subhead v$$
651 The $icode rev_hes_sparse$$ argument $icode v$$ has prototype
652 $codei%
653  CppAD::vector< std::set<size_t> >& %v%
654 %$$
655 and $icode%v%.size() >= %n%$$.
656 The input values of its elements
657 are not specified (must not matter).
658 Upon return, for $latex j = 0, \ldots , n-1$$,
659 all the elements of $icode%v%[%j%]%$$
660 are between zero and $icode%q%-1%$$ inclusive.
661 This represents a sparsity pattern for the matrix
662 $latex V(x) \in B^{n \times q}$$ defined by
663 $latex \[
664 \begin{array}{rcl}
665 V(x)
666 & = &
667 \partial_u [ \partial_x (g \circ f) ( x + R u ) ]_{u=0}
668 \\
669 & = &
670 \partial_u [ (g \circ f)^{(1)}( x + R u ) ]_{u=0}
671 \\
672 & = &
673 (g \circ f)^{(2)}( x ) R
674 \\
675 & = &
676 f^{(1)} (x)^\R{T} g^{(2)} ( y ) f^{(1)} (x) R
677 +
678 \sum_{i=1}^m [ g^{(1)} (y) ]_i \; f_i^{(2)} (x) R
679 \\
680 & = &
681 f^{(1)} (x)^\R{T} U(x)
682 +
683 \sum_{i=1}^m S(x)_i \; f_i^{(2)} (x) R
684 \end{array}
685 \] $$
686 
687 $head clear$$
688 User atomic functions hold onto static work space in order to
689 increase speed by avoiding system memory allocation calls.
690 The function call $codei%
691  user_atomic<%Base%>::clear()
692 %$$
693 makes to work space $cref/available/ta_available/$$ to
694 for other uses by the same thread.
695 This should be called when you are done using the
696 user atomic functions for a specific value of $icode Base$$.
697 
698 $subhead Restriction$$
699 The user atomic $code clear$$ routine cannot be called
700 while in $cref/parallel/ta_in_parallel/$$ execution mode.
701 
702 $children%
703  example/deprecated/old_reciprocal.cpp%
704  example/deprecated/old_usead_1.cpp%
705  example/deprecated/old_usead_2.cpp%
706  example/deprecated/old_tan.cpp%
707  example/deprecated/old_mat_mul.cpp
708 %$$
709 $head Example$$
710 
711 $subhead Simple$$
712 The file $cref old_reciprocal.cpp$$ contains the simplest example and test
713 of a user atomic operation.
714 
715 $subhead Use AD$$
716 The examples
717 $cref old_usead_1.cpp$$ and $cref old_usead_2.cpp$$
718 use AD to compute the derivatives
719 inside a user defined atomic function.
720 This may have the advantage of reducing the size of the tape, because
721 a repeated section of code would only be taped once.
722 
723 $subhead Tangent Function$$
724 The file $cref old_tan.cpp$$ contains an example and test
725 implementation of the tangent function as a user atomic operation.
726 
727 $subhead Matrix Multiplication$$
728 The file $cref old_mat_mul.cpp$$ contains an example and test
729 implementation of matrix multiplication a a user atomic operation.
730 
731 $end
732 ------------------------------------------------------------------------------
733 */
734 # include <set>
735 # include <cppad/core/cppad_assert.hpp>
736 
737 // needed before one can use CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL
739 
740 namespace CppAD { // BEGIN_CPPAD_NAMESPACE
741 /*!
742 \file old_atomic.hpp
743 user defined atomic operations.
744 */
745 
746 /*!
747 \def CPPAD_USER_ATOMIC(afun, Tvector,
748  forward, reverse, for_jac_sparse, rev_jac_sparse, rev_hes_sparse
749 )
750 Defines the function <tt>afun(id, ax, ay)</tt>
751 where \c id is \c ax and \c ay are vectors with <tt>AD<Base></tt> elements.
752 
753 \par Tvector
754 the Simple Vector template class for this function.
755 
756 \par Base
757 the base type for the atomic operation.
758 
759 \par afun
760 name of the CppAD defined function that corresponding to this operation.
761 Note that \c afun, preceeded by a pound sign,
762 is a version of \c afun with quotes arround it.
763 
764 \par forward
765 name of the user defined function that computes corresponding
766 results during forward mode.
767 
768 \par reverse
769 name of the user defined function that computes corresponding
770 results during reverse mode.
771 
772 \par for_jac_sparse
773 name of the user defined routine that computes corresponding
774 results during forward mode jacobian sparsity sweeps.
775 
776 \par rev_jac_sparse
777 name of the user defined routine that computes corresponding
778 results during reverse mode jacobian sparsity sweeps.
779 
780 \par rev_hes_sparse
781 name of the user defined routine that computes corresponding
782 results during reverse mode Hessian sparsity sweeps.
783 
784 \par memory allocation
785 Note that old_atomic is used as a static object, so its objects
786 do note get deallocated until the program terminates.
787 */
788 # define CPPAD_USER_ATOMIC( \
789  afun , \
790  Tvector , \
791  Base , \
792  forward , \
793  reverse , \
794  for_jac_sparse , \
795  rev_jac_sparse , \
796  rev_hes_sparse \
797 ) \
798 inline void afun ( \
799  size_t id , \
800  const Tvector< CppAD::AD<Base> >& ax , \
801  Tvector< CppAD::AD<Base> >& ay \
802 ) \
803 { CPPAD_ASSERT_FIRST_CALL_NOT_PARALLEL; \
804  static CppAD::old_atomic<Base> fun( \
805  #afun , \
806  forward , \
807  reverse , \
808  for_jac_sparse , \
809  rev_jac_sparse , \
810  rev_hes_sparse \
811  ); \
812  fun(id, ax, ay); \
813 }
814 
815 /// link so that user_atomic<Base>::clear() still works
816 template <class Base> class user_atomic : public atomic_base<Base> {
817 };
818 
819 /*!
820 Class that actually implements the <tt>afun(id, ax, ay)</tt> calls.
821 
822 A new old_atomic object is generated each time the user invokes
823 the CPPAD_USER_ATOMIC macro; see static object in that macro.
824 */
825 template <class Base>
826 class old_atomic : public atomic_base<Base> {
827 public:
828  /// disable old_atomic<Base>::clear(void)
829  static void clear(void)
831  false,
832  "Depreacted API uses user_atomic<Base>::clear()"
833  );
834  }
835  /// type for user routine that computes forward mode results
836  typedef bool (*F) (
837  size_t id ,
838  size_t k ,
839  size_t n ,
840  size_t m ,
841  const vector<bool>& vx ,
842  vector<bool>& vy ,
843  const vector<Base>& tx ,
844  vector<Base>& ty
845  );
846  /// type for user routine that computes reverse mode results
847  typedef bool (*R) (
848  size_t id ,
849  size_t k ,
850  size_t n ,
851  size_t m ,
852  const vector<Base>& tx ,
853  const vector<Base>& ty ,
854  vector<Base>& px ,
855  const vector<Base>& py
856  );
857  /// type for user routine that computes forward mode Jacobian sparsity
858  typedef bool (*FJS) (
859  size_t id ,
860  size_t n ,
861  size_t m ,
862  size_t q ,
863  const vector< std::set<size_t> >& r ,
865  );
866  /// type for user routine that computes reverse mode Jacobian sparsity
867  typedef bool (*RJS) (
868  size_t id ,
869  size_t n ,
870  size_t m ,
871  size_t q ,
873  const vector< std::set<size_t> >& s
874  );
875  /// type for user routine that computes reverse mode Hessian sparsity
876  typedef bool (*RHS) (
877  size_t id ,
878  size_t n ,
879  size_t m ,
880  size_t q ,
881  const vector< std::set<size_t> >& r ,
882  const vector<bool>& s ,
883  vector<bool>& t ,
884  const vector< std::set<size_t> >& u ,
886  );
887 private:
888  /// id value corresponding to next virtual callback
889  size_t id_;
890  /// user's implementation of forward mode
891  const F f_;
892  /// user's implementation of reverse mode
893  const R r_;
894  /// user's implementation of forward jacobian sparsity calculations
895  const FJS fjs_;
896  /// user's implementation of reverse jacobian sparsity calculations
897  const RJS rjs_;
898  /// user's implementation of reverse Hessian sparsity calculations
899  const RHS rhs_;
900 
901 public:
902  /*!
903  Constructor called for each invocation of CPPAD_USER_ATOMIC.
904 
905  Put this object in the list of all objects for this class and set
906  the constant private data f_, r_, fjs_, rjs_, rhs_.
907 
908  \param afun
909  is the user's name for the AD version of this atomic operation.
910 
911  \param f
912  user routine that does forward mode calculations for this operation.
913 
914  \param r
915  user routine that does reverse mode calculations for this operation.
916 
917  \param fjs
918  user routine that does forward Jacobian sparsity calculations.
919 
920  \param rjs
921  user routine that does reverse Jacobian sparsity calculations.
922 
923  \param rhs
924  user routine that does reverse Hessian sparsity calculations.
925 
926  \par
927  This constructor can not be used in parallel mode because
928  atomic_base has this restriction.
929  */
930  old_atomic(const char* afun, F f, R r, FJS fjs, RJS rjs, RHS rhs) :
931  atomic_base<Base>(afun) // name = afun
932  , f_(f)
933  , r_(r)
934  , fjs_(fjs)
935  , rjs_(rjs)
936  , rhs_(rhs)
938  }
939  /*!
940  Implement the user call to <tt>afun(id, ax, ay)</tt>.
941 
942  \tparam ADVector
943  A simple vector class with elements of type <code>AD<Base></code>.
944 
945  \param id
946  extra information vector that is just passed through by CppAD,
947  and possibly used by user's routines.
948 
949  \param ax
950  is the argument vector for this call,
951  <tt>ax.size()</tt> determines the number of arguments.
952 
953  \param ay
954  is the result vector for this call,
955  <tt>ay.size()</tt> determines the number of results.
956  */
957  template <class ADVector>
958  void operator()(size_t id, const ADVector& ax, ADVector& ay)
959  { // call atomic_base function object
960  this->atomic_base<Base>::operator()(ax, ay, id);
961  return;
962  }
963  /*!
964  Store id for next virtual function callback
965 
966  \param id
967  id value corresponding to next virtual callback
968  */
969  virtual void set_old(size_t id)
970  { id_ = id; }
971  /*!
972  Link from old_atomic to forward mode
973 
974  \copydetails atomic_base::forward
975  */
976  virtual bool forward(
977  size_t p ,
978  size_t q ,
979  const vector<bool>& vx ,
980  vector<bool>& vy ,
981  const vector<Base>& tx ,
982  vector<Base>& ty )
983  { CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );
984  CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );
985  size_t n = tx.size() / (q+1);
986  size_t m = ty.size() / (q+1);
987  size_t i, j, k, ell;
988 
989  vector<Base> x(n * (q+1));
990  vector<Base> y(m * (q+1));
991  vector<bool> empty;
992 
993  // old_atomic interface can only handel one order at a time
994  // so must just throuh hoops to get multiple orders at one time.
995  bool ok = true;
996  for(k = p; k <= q; k++)
997  { for(j = 0; j < n; j++)
998  for(ell = 0; ell <= k; ell++)
999  x[ j * (k+1) + ell ] = tx[ j * (q+1) + ell ];
1000  for(i = 0; i < m; i++)
1001  for(ell = 0; ell < k; ell++)
1002  y[ i * (k+1) + ell ] = ty[ i * (q+1) + ell ];
1003  if( k == 0 )
1004  ok &= f_(id_, k, n, m, vx, vy, x, y);
1005  else
1006  ok &= f_(id_, k, n, m, empty, empty, x, y);
1007  for(i = 0; i < m; i++)
1008  ty[ i * (q+1) + k ] = y[ i * (k+1) + k];
1009  }
1010  return ok;
1011  }
1012  /*!
1013  Link from old_atomic to reverse mode
1014 
1015  \copydetails atomic_base::reverse
1016  */
1017  virtual bool reverse(
1018  size_t q ,
1019  const vector<Base>& tx ,
1020  const vector<Base>& ty ,
1021  vector<Base>& px ,
1022  const vector<Base>& py )
1023  { CPPAD_ASSERT_UNKNOWN( tx.size() % (q+1) == 0 );
1024  CPPAD_ASSERT_UNKNOWN( ty.size() % (q+1) == 0 );
1025  size_t n = tx.size() / (q+1);
1026  size_t m = ty.size() / (q+1);
1027  bool ok = r_(id_, q, n, m, tx, ty, px, py);
1028  return ok;
1029  }
1030  /*!
1031  Link from forward Jacobian sparsity sweep to old_atomic
1032 
1033  \copydetails atomic_base::for_sparse_jac
1034  */
1035  virtual bool for_sparse_jac(
1036  size_t q ,
1037  const vector< std::set<size_t> >& r ,
1038  vector< std::set<size_t> >& s ,
1039  const vector<Base>& x )
1040  { size_t n = r.size();
1041  size_t m = s.size();
1042  bool ok = fjs_(id_, n, m, q, r, s);
1043  return ok;
1044  }
1045 
1046  /*!
1047  Link from reverse Jacobian sparsity sweep to old_atomic.
1048 
1049  \copydetails atomic_base::rev_sparse_jac
1050  */
1051  virtual bool rev_sparse_jac(
1052  size_t q ,
1053  const vector< std::set<size_t> >& rt ,
1054  vector< std::set<size_t> >& st ,
1055  const vector<Base>& x )
1056  { size_t n = st.size();
1057  size_t m = rt.size();
1058  bool ok = rjs_(id_, n, m, q, st, rt);
1059  return ok;
1060  }
1061  /*!
1062  Link from reverse Hessian sparsity sweep to old_atomic
1063 
1064  \copydetails atomic_base::rev_sparse_hes
1065  */
1066  virtual bool rev_sparse_hes(
1067  const vector<bool>& vx,
1068  const vector<bool>& s ,
1069  vector<bool>& t ,
1070  size_t q ,
1071  const vector< std::set<size_t> >& r ,
1072  const vector< std::set<size_t> >& u ,
1073  vector< std::set<size_t> >& v ,
1074  const vector<Base>& x )
1075  { size_t m = u.size();
1076  size_t n = v.size();
1077  CPPAD_ASSERT_UNKNOWN( r.size() == n );
1078  CPPAD_ASSERT_UNKNOWN( s.size() == m );
1079  CPPAD_ASSERT_UNKNOWN( t.size() == n );
1080  //
1081  // old interface used id instead of vx
1082  bool ok = rhs_(id_, n, m, q, r, s, t, u, v);
1083  return ok;
1084  }
1085 };
1086 
1087 } // END_CPPAD_NAMESPACE
1088 # endif
bool(* F)(size_t id, size_t k, size_t n, size_t m, const vector< bool > &vx, vector< bool > &vy, const vector< Base > &tx, vector< Base > &ty)
type for user routine that computes forward mode results
Definition: old_atomic.hpp:836
bool(* R)(size_t id, size_t k, size_t n, size_t m, const vector< Base > &tx, const vector< Base > &ty, vector< Base > &px, const vector< Base > &py)
type for user routine that computes reverse mode results
Definition: old_atomic.hpp:847
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
virtual bool rev_sparse_hes(const vector< bool > &vx, const vector< bool > &s, vector< bool > &t, size_t q, const vector< std::set< size_t > > &r, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v, const vector< Base > &x)
Link from reverse Hessian sparsity sweep to old_atomic.
void operator()(size_t id, const ADVector &ax, ADVector &ay)
Implement the user call to afun(id, ax, ay).
Definition: old_atomic.hpp:958
bool(* RJS)(size_t id, size_t n, size_t m, size_t q, vector< std::set< size_t > > &r, const vector< std::set< size_t > > &s)
type for user routine that computes reverse mode Jacobian sparsity
Definition: old_atomic.hpp:867
old_atomic(const char *afun, F f, R r, FJS fjs, RJS rjs, RHS rhs)
Constructor called for each invocation of CPPAD_USER_ATOMIC.
Definition: old_atomic.hpp:930
virtual void set_old(size_t id)
Store id for next virtual function callback.
Definition: old_atomic.hpp:969
bool(* FJS)(size_t id, size_t n, size_t m, size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s)
type for user routine that computes forward mode Jacobian sparsity
Definition: old_atomic.hpp:858
virtual bool reverse(size_t q, const vector< Base > &tx, const vector< Base > &ty, vector< Base > &px, const vector< Base > &py)
Link from old_atomic to reverse mode.
Define the CppAD error checking macros (all of which begin with CPPAD_ASSERT_)
const FJS fjs_
user&#39;s implementation of forward jacobian sparsity calculations
Definition: old_atomic.hpp:895
virtual bool rev_sparse_jac(size_t q, const vector< std::set< size_t > > &rt, vector< std::set< size_t > > &st, const vector< Base > &x)
Link from reverse Jacobian sparsity sweep to old_atomic.
const RHS rhs_
user&#39;s implementation of reverse Hessian sparsity calculations
Definition: old_atomic.hpp:899
bool(* RHS)(size_t id, size_t n, size_t m, size_t q, const vector< std::set< size_t > > &r, const vector< bool > &s, vector< bool > &t, const vector< std::set< size_t > > &u, vector< std::set< size_t > > &v)
type for user routine that computes reverse mode Hessian sparsity
Definition: old_atomic.hpp:876
const F f_
user&#39;s implementation of forward mode
Definition: old_atomic.hpp:891
size_t size(void) const
number of elements currently in this vector.
Definition: vector.hpp:387
link so that user_atomic&lt;Base&gt;::clear() still works
Definition: old_atomic.hpp:816
void operator()(const ADVector &ax, ADVector &ay, size_t id=0)
Implement the user call to afun(ax, ay) and old_atomic call to afun(ax, ay, id).
size_t id_
id value corresponding to next virtual callback
Definition: old_atomic.hpp:889
static void clear(void)
disable old_atomic&lt;Base&gt;::clear(void)
Definition: old_atomic.hpp:829
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
virtual bool for_sparse_jac(size_t q, const vector< std::set< size_t > > &r, vector< std::set< size_t > > &s, const vector< Base > &x)
Link from forward Jacobian sparsity sweep to old_atomic.
Class that actually implements the afun(id, ax, ay) calls.
Definition: old_atomic.hpp:826
const RJS rjs_
user&#39;s implementation of reverse jacobian sparsity calculations
Definition: old_atomic.hpp:897
File used to define the CppAD multi-threading allocator class.
const R r_
user&#39;s implementation of reverse mode
Definition: old_atomic.hpp:893
void option(enum option_enum option_value)
virtual bool forward(size_t p, size_t q, const vector< bool > &vx, vector< bool > &vy, const vector< Base > &tx, vector< Base > &ty)
Link from old_atomic to forward mode.
Definition: old_atomic.hpp:976