CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
store_op.hpp
Go to the documentation of this file.
1 // $Id: store_op.hpp 3865 2017-01-19 01:57:55Z bradbell $
2 # ifndef CPPAD_LOCAL_STORE_OP_HPP
3 # define CPPAD_LOCAL_STORE_OP_HPP
4 
5 /* --------------------------------------------------------------------------
6 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
7 
8 CppAD is distributed under multiple licenses. This distribution is under
9 the terms of the
10  Eclipse Public License Version 1.0.
11 
12 A copy of this license is included in the COPYING file of this distribution.
13 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
14 -------------------------------------------------------------------------- */
15 
16 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
17 /*!
18 \file store_op.hpp
19 Changing the current value of a VecAD element.
20 */
21 /*
22 ==============================================================================
23 <!-- define preamble -->
24 The C++ source code corresponding to this operation is
25 \verbatim
26  v[x] = y
27 \endverbatim
28 where v is a VecAD<Base> vector, x is an AD<Base> object,
29 and y is AD<Base> or Base objects.
30 We define the index corresponding to v[x] by
31 \verbatim
32  i_v_x = index_by_ind[ arg[0] + i_vec ]
33 \endverbatim
34 where i_vec is defined under the heading arg[1] below:
35 <!-- end preamble -->
36 ==============================================================================
37 */
38 /*!
39 Shared documentation for zero order forward implementation of
40 op = StppOp, StpvOp, StvpOp, or StvvOp (not called).
41 
42 <!-- replace preamble -->
43 The C++ source code corresponding to this operation is
44 \verbatim
45  v[x] = y
46 \endverbatim
47 where v is a VecAD<Base> vector, x is an AD<Base> object,
48 and y is AD<Base> or Base objects.
49 We define the index corresponding to v[x] by
50 \verbatim
51  i_v_x = index_by_ind[ arg[0] + i_vec ]
52 \endverbatim
53 where i_vec is defined under the heading arg[1] below:
54 <!-- end preamble -->
55 
56 \tparam Base
57 base type for the operator; i.e., this operation was recorded
58 using AD<Base> and computations by this routine are done using type Base.
59 
60 \param i_z
61 is the index corresponding to the previous variable on the tape
62 (only used for error checking).
63 
64 \param arg
65 \n
66 arg[0]
67 \n
68 is the offset of this VecAD vector relative to the beginning
69 of the isvar_by_ind and index_by_ind arrays.
70 \n
71 \n
72 arg[1]
73 \n
74 If this is a StppOp or StpvOp operation (if x is a parameter),
75 i_vec is defined by
76 \verbatim
77  i_vec = arg[1]
78 \endverbatim
79 If this is a StvpOp or StvvOp operation (if x is a variable),
80 i_vec is defined by
81 \verbatim
82  i_vec = floor( taylor[ arg[1] * cap_order + 0 ] )
83 \endverbatim
84 where floor(c) is the greatest integer less that or equal c.
85 \n
86 \n
87 arg[2]
88 \n
89 index corresponding to the third operand for this operator;
90 i.e. the index corresponding to y.
91 
92 \param num_par
93 is the total number of parameters on the tape
94 (only used for error checking).
95 
96 \param cap_order
97 number of columns in the matrix containing the Taylor coefficients.
98 
99 \param taylor
100 In StvpOp and StvvOp cases, <code><taylor[ arg[1] * cap_order + 0 ]</code>
101 is used to compute the index in the definition of i_vec above.
102 
103 \param isvar_by_ind
104 If y is a varable (StpvOp and StvvOp cases),
105 <code>isvar_by_ind[ arg[0] + i_vec ] </code> is set to true.
106 Otherwise y is a paraemter (StppOp and StvpOp cases) and
107 <code>isvar_by_ind[ arg[0] + i_vec ] </code> is set to false.
108 
109 \param index_by_ind
110 <code>index_by_ind[ arg[0] - 1 ]</code>
111 is the number of elements in the user vector containing this element.
112 The value <code>index_by_ind[ arg[0] + i_vec]</code>
113 is set equal to arg[2].
114 
115 \par Check User Errors
116 \li Check that the index is with in range; i.e.
117 <code>i_vec < index_by_ind[ arg[0] - 1 ]</code>
118 Note that, if x is a parameter,
119 the corresponding vector index and it does not change.
120 In this case, the error above should be detected during tape recording.
121 
122 \par Checked Assertions
123 \li NumArg(op) == 3
124 \li NumRes(op) == 0
125 \li 0 < arg[0]
126 \li if y is a parameter, arg[2] < num_par
127 */
128 template <class Base>
129 inline void forward_store_op_0(
130  size_t i_z ,
131  const addr_t* arg ,
132  size_t num_par ,
133  size_t cap_order ,
134  Base* taylor ,
135  bool* isvar_by_ind ,
136  size_t* index_by_ind )
137 {
138  // This routine is only for documentaiton, it should not be used
139  CPPAD_ASSERT_UNKNOWN( false );
140 }
141 /*!
142 Shared documnetation for sparsity operations corresponding to
143 op = StpvOp or StvvOp (not called).
144 
145 \tparam Vector_set
146 is the type used for vectors of sets. It can be either
147 sparse_pack or sparse_list.
148 
149 \param op
150 is the code corresponding to this operator;
151 i.e., StpvOp, StvpOp, or StvvOp.
152 
153 \param arg
154 \n
155 \a arg[0]
156 is the offset corresponding to this VecAD vector in the combined array.
157 \n
158 \n
159 \a arg[2]
160 \n
161 The set with index \a arg[2] in \a var_sparsity
162 is the sparsity pattern corresponding to y.
163 (Note that \a arg[2] > 0 because y is a variable.)
164 
165 \param num_combined
166 is the total number of elements in the VecAD address array.
167 
168 \param combined
169 \a combined [ arg[0] - 1 ]
170 is the index of the set in \a vecad_sparsity corresponding
171 to the sparsity pattern for the vector v.
172 We use the notation i_v below which is defined by
173 \verbatim
174  i_v = combined[ \a arg[0] - 1 ]
175 \endverbatim
176 
177 \param var_sparsity
178 The set with index \a arg[2] in \a var_sparsity
179 is the sparsity pattern for y.
180 This is an input for forward mode operations.
181 For reverse mode operations:
182 The sparsity pattern for v is added to the spartisy pattern for y.
183 
184 \param vecad_sparsity
185 The set with index \a i_v in \a vecad_sparsity
186 is the sparsity pattern for v.
187 This is an input for reverse mode operations.
188 For forward mode operations, the sparsity pattern for y is added
189 to the sparsity pattern for the vector v.
190 
191 \par Checked Assertions
192 \li NumArg(op) == 3
193 \li NumRes(op) == 0
194 \li 0 < \a arg[0]
195 \li \a arg[0] < \a num_combined
196 \li \a arg[2] < \a var_sparsity.n_set()
197 \li i_v < \a vecad_sparsity.n_set()
198 */
199 template <class Vector_set>
200 inline void sparse_store_op(
201  OpCode op ,
202  const addr_t* arg ,
203  size_t num_combined ,
204  const size_t* combined ,
205  Vector_set& var_sparsity ,
206  Vector_set& vecad_sparsity )
207 {
208  // This routine is only for documentaiton, it should not be used
209  CPPAD_ASSERT_UNKNOWN( false );
210 }
211 
212 
213 /*!
214 Zero order forward mode implementation of op = StppOp.
215 
216 \copydetails CppAD::local::forward_store_op_0
217 */
218 template <class Base>
220  size_t i_z ,
221  const addr_t* arg ,
222  size_t num_par ,
223  size_t cap_order ,
224  Base* taylor ,
225  bool* isvar_by_ind ,
226  size_t* index_by_ind )
227 { size_t i_vec = arg[1];
228 
229  // Because the index is a parameter, this indexing error should be
230  // caught and reported to the user when the tape is recording.
231  CPPAD_ASSERT_UNKNOWN( i_vec < index_by_ind[ arg[0] - 1 ] );
232 
235  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
236  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
237 
238  isvar_by_ind[ arg[0] + i_vec ] = false;
239  index_by_ind[ arg[0] + i_vec ] = arg[2];
240 }
241 
242 /*!
243 Zero order forward mode implementation of op = StpvOp.
244 
245 \copydetails CppAD::local::forward_store_op_0
246 */
247 template <class Base>
249  size_t i_z ,
250  const addr_t* arg ,
251  size_t num_par ,
252  size_t cap_order ,
253  Base* taylor ,
254  bool* isvar_by_ind ,
255  size_t* index_by_ind )
256 { size_t i_vec = arg[1];
257 
258  // Because the index is a parameter, this indexing error should be
259  // caught and reported to the user when the tape is recording.
260  CPPAD_ASSERT_UNKNOWN( i_vec < index_by_ind[ arg[0] - 1 ] );
261 
264  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
265 
266  isvar_by_ind[ arg[0] + i_vec ] = true;
267  index_by_ind[ arg[0] + i_vec ] = arg[2];
268 }
269 
270 /*!
271 Zero order forward mode implementation of op = StvpOp.
272 
273 \copydetails CppAD::local::forward_store_op_0
274 */
275 template <class Base>
277  size_t i_z ,
278  const addr_t* arg ,
279  size_t num_par ,
280  size_t cap_order ,
281  Base* taylor ,
282  bool* isvar_by_ind ,
283  size_t* index_by_ind )
284 {
285  size_t i_vec = Integer( taylor[ arg[1] * cap_order + 0 ] );
287  i_vec < index_by_ind[ arg[0] - 1 ] ,
288  "VecAD: index during zero order forward sweep is out of range"
289  );
290 
293  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
294  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < num_par );
295 
296  isvar_by_ind[ arg[0] + i_vec ] = false;
297  index_by_ind[ arg[0] + i_vec ] = arg[2];
298 }
299 
300 /*!
301 Zero order forward mode implementation of op = StvvOp.
302 
303 \copydetails CppAD::local::forward_store_op_0
304 */
305 template <class Base>
307  size_t i_z ,
308  const addr_t* arg ,
309  size_t num_par ,
310  size_t cap_order ,
311  Base* taylor ,
312  bool* isvar_by_ind ,
313  size_t* index_by_ind )
314 {
315  size_t i_vec = Integer( taylor[ arg[1] * cap_order + 0 ] );
317  i_vec < index_by_ind[ arg[0] - 1 ] ,
318  "VecAD: index during zero order forward sweep is out of range"
319  );
320 
323  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
324 
325  isvar_by_ind[ arg[0] + i_vec ] = true;
326  index_by_ind[ arg[0] + i_vec ] = arg[2];
327 }
328 
329 /*!
330 Forward mode sparsity operations for StpvOp and StvvOp
331 
332 <!-- replace preamble -->
333 The C++ source code corresponding to this operation is
334 \verbatim
335  v[x] = y
336 \endverbatim
337 where v is a VecAD<Base> vector, x is an AD<Base> object,
338 and y is AD<Base> or Base objects.
339 We define the index corresponding to v[x] by
340 \verbatim
341  i_v_x = index_by_ind[ arg[0] + i_vec ]
342 \endverbatim
343 where i_vec is defined under the heading arg[1] below:
344 <!-- end preamble -->
345 
346 \param dependency
347 is this a dependency (or sparsity) calculation.
348 
349 \copydetails CppAD::local::sparse_store_op
350 */
351 template <class Vector_set>
353  bool dependency ,
354  OpCode op ,
355  const addr_t* arg ,
356  size_t num_combined ,
357  const size_t* combined ,
358  Vector_set& var_sparsity ,
359  Vector_set& vecad_sparsity )
360 {
361  CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
362  CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );
363  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
364  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
365  size_t i_v = combined[ arg[0] - 1 ];
366  CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
367  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() );
368 
369  if( dependency & ( (op == StvvOp) | (op == StvpOp) ) )
370  vecad_sparsity.binary_union(i_v, i_v, arg[1], var_sparsity);
371 
372  if( (op == StpvOp) | (op == StvvOp ) )
373  vecad_sparsity.binary_union(i_v, i_v, arg[2], var_sparsity);
374 
375  return;
376 }
377 
378 /*!
379 Reverse mode sparsity operations for StpvOp, StvpOp, and StvvOp
380 
381 <!-- replace preamble -->
382 The C++ source code corresponding to this operation is
383 \verbatim
384  v[x] = y
385 \endverbatim
386 where v is a VecAD<Base> vector, x is an AD<Base> object,
387 and y is AD<Base> or Base objects.
388 We define the index corresponding to v[x] by
389 \verbatim
390  i_v_x = index_by_ind[ arg[0] + i_vec ]
391 \endverbatim
392 where i_vec is defined under the heading arg[1] below:
393 <!-- end preamble -->
394 
395 This routine is given the sparsity patterns for
396 G(v[x], y , w , u ... ) and it uses them to compute the
397 sparsity patterns for
398 \verbatim
399  H(y , w , u , ... ) = G[ v[x], y , w , u , ... ]
400 \endverbatim
401 
402 \param dependency
403 is this a dependency (or sparsity) calculation.
404 
405 \copydetails CppAD::local::sparse_store_op
406 */
407 template <class Vector_set>
409  bool dependency ,
410  OpCode op ,
411  const addr_t* arg ,
412  size_t num_combined ,
413  const size_t* combined ,
414  Vector_set& var_sparsity ,
415  Vector_set& vecad_sparsity )
416 {
417  CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
418  CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );
419  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
420  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
421  size_t i_v = combined[ arg[0] - 1 ];
422  CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
423  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() );
424 
425  if( dependency & ( (op == StvpOp) | (op == StvvOp) ) )
426  var_sparsity.binary_union(arg[1], arg[1], i_v, vecad_sparsity);
427  if( (op == StpvOp) | (op == StvvOp) )
428  var_sparsity.binary_union(arg[2], arg[2], i_v, vecad_sparsity);
429 
430  return;
431 }
432 
433 /*!
434 Reverse mode sparsity operations for StpvOp and StvvOp
435 
436 <!-- replace preamble -->
437 The C++ source code corresponding to this operation is
438 \verbatim
439  v[x] = y
440 \endverbatim
441 where v is a VecAD<Base> vector, x is an AD<Base> object,
442 and y is AD<Base> or Base objects.
443 We define the index corresponding to v[x] by
444 \verbatim
445  i_v_x = index_by_ind[ arg[0] + i_vec ]
446 \endverbatim
447 where i_vec is defined under the heading arg[1] below:
448 <!-- end preamble -->
449 
450 This routine is given the sparsity patterns for
451 G(v[x], y , w , u ... )
452 and it uses them to compute the sparsity patterns for
453 \verbatim
454  H(y , w , u , ... ) = G[ v[x], y , w , u , ... ]
455 \endverbatim
456 
457 \copydetails CppAD::local::sparse_store_op
458 
459 \param var_jacobian
460 \a var_jacobian[ \a arg[2] ]
461 is false (true) if the Jacobian of G with respect to y is always zero
462 (may be non-zero).
463 
464 \param vecad_jacobian
465 \a vecad_jacobian[i_v]
466 is false (true) if the Jacobian with respect to x is always zero
467 (may be non-zero).
468 On input, it corresponds to the function G,
469 and on output it corresponds to the function H.
470 */
471 template <class Vector_set>
473  OpCode op ,
474  const addr_t* arg ,
475  size_t num_combined ,
476  const size_t* combined ,
477  Vector_set& var_sparsity ,
478  Vector_set& vecad_sparsity ,
479  bool* var_jacobian ,
480  bool* vecad_jacobian )
481 {
482  CPPAD_ASSERT_UNKNOWN( NumArg(op) == 3 );
483  CPPAD_ASSERT_UNKNOWN( NumRes(op) == 0 );
484  CPPAD_ASSERT_UNKNOWN( 0 < arg[0] );
485  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < num_combined );
486  size_t i_v = combined[ arg[0] - 1 ];
487  CPPAD_ASSERT_UNKNOWN( i_v < vecad_sparsity.n_set() );
488  CPPAD_ASSERT_UNKNOWN( size_t(arg[2]) < var_sparsity.n_set() );
489 
490  var_sparsity.binary_union(arg[2], arg[2], i_v, vecad_sparsity);
491 
492  var_jacobian[ arg[2] ] |= vecad_jacobian[i_v];
493 
494  return;
495 }
496 
497 } } // END_CPPAD_LOCAL_NAMESPACE
498 # endif
#define CPPAD_ASSERT_KNOWN(exp, msg)
Check that exp is true, if not print msg and terminate execution.
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
void forward_store_op_0(size_t i_z, const addr_t *arg, size_t num_par, size_t cap_order, Base *taylor, bool *isvar_by_ind, size_t *index_by_ind)
Shared documentation for zero order forward implementation of op = StppOp, StpvOp, StvpOp, or StvvOp (not called).
Definition: store_op.hpp:129
size_t NumArg(OpCode op)
Number of arguments for a specified operator.
Definition: op_code.hpp:175
size_t NumRes(OpCode op)
Number of variables resulting from the specified operation.
Definition: op_code.hpp:281
void forward_store_pp_op_0(size_t i_z, const addr_t *arg, size_t num_par, size_t cap_order, Base *taylor, bool *isvar_by_ind, size_t *index_by_ind)
Zero order forward mode implementation of op = StppOp.
Definition: store_op.hpp:219
OpCode
Type used to distinguish different AD&lt; Base &gt; atomic operations.
Definition: op_code.hpp:49
void forward_store_vv_op_0(size_t i_z, const addr_t *arg, size_t num_par, size_t cap_order, Base *taylor, bool *isvar_by_ind, size_t *index_by_ind)
Zero order forward mode implementation of op = StvvOp.
Definition: store_op.hpp:306
void reverse_sparse_jacobian_store_op(bool dependency, OpCode op, const addr_t *arg, size_t num_combined, const size_t *combined, Vector_set &var_sparsity, Vector_set &vecad_sparsity)
Reverse mode sparsity operations for StpvOp, StvpOp, and StvvOp.
Definition: store_op.hpp:408
void forward_store_vp_op_0(size_t i_z, const addr_t *arg, size_t num_par, size_t cap_order, Base *taylor, bool *isvar_by_ind, size_t *index_by_ind)
Zero order forward mode implementation of op = StvpOp.
Definition: store_op.hpp:276
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void forward_store_pv_op_0(size_t i_z, const addr_t *arg, size_t num_par, size_t cap_order, Base *taylor, bool *isvar_by_ind, size_t *index_by_ind)
Zero order forward mode implementation of op = StpvOp.
Definition: store_op.hpp:248
int Integer(const std::complex< double > &x)
void forward_sparse_store_op(bool dependency, OpCode op, const addr_t *arg, size_t num_combined, const size_t *combined, Vector_set &var_sparsity, Vector_set &vecad_sparsity)
Forward mode sparsity operations for StpvOp and StvvOp.
Definition: store_op.hpp:352
void sparse_store_op(OpCode op, const addr_t *arg, size_t num_combined, const size_t *combined, Vector_set &var_sparsity, Vector_set &vecad_sparsity)
Shared documnetation for sparsity operations corresponding to op = StpvOp or StvvOp (not called)...
Definition: store_op.hpp:200
void reverse_sparse_hessian_store_op(OpCode op, const addr_t *arg, size_t num_combined, const size_t *combined, Vector_set &var_sparsity, Vector_set &vecad_sparsity, bool *var_jacobian, bool *vecad_jacobian)
Reverse mode sparsity operations for StpvOp and StvvOp.
Definition: store_op.hpp:472