CppAD: A C++ Algorithmic Differentiation Package  20171217
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
sparse_binary_op.hpp
Go to the documentation of this file.
1 // $Id: sparse_binary_op.hpp 3865 2017-01-19 01:57:55Z bradbell $
2 # ifndef CPPAD_LOCAL_SPARSE_BINARY_OP_HPP
3 # define CPPAD_LOCAL_SPARSE_BINARY_OP_HPP
4 /* --------------------------------------------------------------------------
5 CppAD: C++ Algorithmic Differentiation: Copyright (C) 2003-17 Bradley M. Bell
6 
7 CppAD is distributed under multiple licenses. This distribution is under
8 the terms of the
9  Eclipse Public License Version 1.0.
10 
11 A copy of this license is included in the COPYING file of this distribution.
12 Please visit http://www.coin-or.org/CppAD/ for information on other licenses.
13 -------------------------------------------------------------------------- */
14 
15 namespace CppAD { namespace local { // BEGIN_CPPAD_LOCAL_NAMESPACE
16 /*!
17 \file sparse_binary_op.hpp
18 Forward and reverse mode sparsity patterns for binary operators.
19 */
20 
21 
22 /*!
23 Forward mode Jacobian sparsity pattern for all binary operators.
24 
25 The C++ source code corresponding to a binary operation has the form
26 \verbatim
27  z = fun(x, y)
28 \endverbatim
29 where fun is a C++ binary function and both x and y are variables,
30 or it has the form
31 \verbatim
32  z = x op y
33 \endverbatim
34 where op is a C++ binary unary operator and both x and y are variables.
35 
36 \tparam Vector_set
37 is the type used for vectors of sets. It can be either
38 sparse_pack or sparse_list.
39 
40 \param i_z
41 variable index corresponding to the result for this operation;
42 i.e., z.
43 
44 \param arg
45 \a arg[0]
46 variable index corresponding to the left operand for this operator;
47 i.e., x.
48 \n
49 \n arg[1]
50 variable index corresponding to the right operand for this operator;
51 i.e., y.
52 
53 \param sparsity
54 \b Input:
55 The set with index \a arg[0] in \a sparsity
56 is the sparsity bit pattern for x.
57 This identifies which of the independent variables the variable x
58 depends on.
59 \n
60 \n
61 \b Input:
62 The set with index \a arg[1] in \a sparsity
63 is the sparsity bit pattern for y.
64 This identifies which of the independent variables the variable y
65 depends on.
66 \n
67 \n
68 \b Output:
69 The set with index \a i_z in \a sparsity
70 is the sparsity bit pattern for z.
71 This identifies which of the independent variables the variable z
72 depends on.
73 
74 \par Checked Assertions:
75 \li \a arg[0] < \a i_z
76 \li \a arg[1] < \a i_z
77 */
78 
79 template <class Vector_set>
81  size_t i_z ,
82  const addr_t* arg ,
83  Vector_set& sparsity )
84 {
85  // check assumptions
86  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
87  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
88 
89  sparsity.binary_union(i_z, arg[0], arg[1], sparsity);
90 
91  return;
92 }
93 
94 /*!
95 Reverse mode Jacobian sparsity pattern for all binary operators.
96 
97 The C++ source code corresponding to a unary operation has the form
98 \verbatim
99  z = fun(x, y)
100 \endverbatim
101 where fun is a C++ unary function and x and y are variables,
102 or it has the form
103 \verbatim
104  z = x op y
105 \endverbatim
106 where op is a C++ bianry operator and x and y are variables.
107 
108 This routine is given the sparsity patterns
109 for a function G(z, y, x, ... )
110 and it uses them to compute the sparsity patterns for
111 \verbatim
112  H( y, x, w , u , ... ) = G[ z(x,y) , y , x , w , u , ... ]
113 \endverbatim
114 
115 \tparam Vector_set
116 is the type used for vectors of sets. It can be either
117 sparse_pack or sparse_list.
118 
119 \param i_z
120 variable index corresponding to the result for this operation;
121 i.e., z.
122 
123 \param arg
124 \a arg[0]
125 variable index corresponding to the left operand for this operator;
126 i.e., x.
127 
128 \n
129 \n arg[1]
130 variable index corresponding to the right operand for this operator;
131 i.e., y.
132 
133 \param sparsity
134 The set with index \a i_z in \a sparsity
135 is the sparsity pattern for z corresponding ot the function G.
136 \n
137 \n
138 The set with index \a arg[0] in \a sparsity
139 is the sparsity pattern for x.
140 On input, it corresponds to the function G,
141 and on output it corresponds to H.
142 \n
143 \n
144 The set with index \a arg[1] in \a sparsity
145 is the sparsity pattern for y.
146 On input, it corresponds to the function G,
147 and on output it corresponds to H.
148 \n
149 \n
150 
151 \par Checked Assertions:
152 \li \a arg[0] < \a i_z
153 \li \a arg[1] < \a i_z
154 */
155 template <class Vector_set>
157  size_t i_z ,
158  const addr_t* arg ,
159  Vector_set& sparsity )
160 {
161  // check assumptions
162  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
163  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
164 
165  sparsity.binary_union(arg[0], arg[0], i_z, sparsity);
166  sparsity.binary_union(arg[1], arg[1], i_z, sparsity);
167 
168  return;
169 }
170 // ---------------------------------------------------------------------------
171 /*!
172 Reverse mode Hessian sparsity pattern for add and subtract operators.
173 
174 The C++ source code corresponding to a unary operation has the form
175 \verbatim
176  z = x op y
177 \endverbatim
178 where op is + or - and x, y are variables.
179 
180 \copydetails CppAD::local::reverse_sparse_hessian_binary_op
181 */
182 template <class Vector_set>
184  size_t i_z ,
185  const addr_t* arg ,
186  bool* jac_reverse ,
187  const Vector_set& for_jac_sparsity ,
188  Vector_set& rev_hes_sparsity )
189 {
190  // check assumptions
191  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
192  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
193 
194  rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
195  rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
196 
197  jac_reverse[arg[0]] |= jac_reverse[i_z];
198  jac_reverse[arg[1]] |= jac_reverse[i_z];
199 
200  return;
201 }
202 
203 /*!
204 Reverse mode Hessian sparsity pattern for multiplication operator.
205 
206 The C++ source code corresponding to a unary operation has the form
207 \verbatim
208  z = x * y
209 \endverbatim
210 where x and y are variables.
211 
212 \copydetails CppAD::local::reverse_sparse_hessian_binary_op
213 */
214 template <class Vector_set>
216  size_t i_z ,
217  const addr_t* arg ,
218  bool* jac_reverse ,
219  const Vector_set& for_jac_sparsity ,
220  Vector_set& rev_hes_sparsity )
221 {
222  // check assumptions
223  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
224  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
225 
226  rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
227  rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
228 
229  if( jac_reverse[i_z] )
230  { rev_hes_sparsity.binary_union(
231  arg[0], arg[0], arg[1], for_jac_sparsity);
232  rev_hes_sparsity.binary_union(
233  arg[1], arg[1], arg[0], for_jac_sparsity);
234  }
235 
236  jac_reverse[arg[0]] |= jac_reverse[i_z];
237  jac_reverse[arg[1]] |= jac_reverse[i_z];
238  return;
239 }
240 
241 /*!
242 Reverse mode Hessian sparsity pattern for division operator.
243 
244 The C++ source code corresponding to a unary operation has the form
245 \verbatim
246  z = x / y
247 \endverbatim
248 where x and y are variables.
249 
250 \copydetails CppAD::local::reverse_sparse_hessian_binary_op
251 */
252 template <class Vector_set>
254  size_t i_z ,
255  const addr_t* arg ,
256  bool* jac_reverse ,
257  const Vector_set& for_jac_sparsity ,
258  Vector_set& rev_hes_sparsity )
259 {
260  // check assumptions
261  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
262  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
263 
264  rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
265  rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
266 
267  if( jac_reverse[i_z] )
268  { rev_hes_sparsity.binary_union(
269  arg[0], arg[0], arg[1], for_jac_sparsity);
270  rev_hes_sparsity.binary_union(
271  arg[1], arg[1], arg[0], for_jac_sparsity);
272  rev_hes_sparsity.binary_union(
273  arg[1], arg[1], arg[1], for_jac_sparsity);
274  }
275 
276  jac_reverse[arg[0]] |= jac_reverse[i_z];
277  jac_reverse[arg[1]] |= jac_reverse[i_z];
278  return;
279 }
280 
281 /*!
282 Reverse mode Hessian sparsity pattern for power function.
283 
284 The C++ source code corresponding to a unary operation has the form
285 \verbatim
286  z = pow(x, y)
287 \endverbatim
288 where x and y are variables.
289 
290 \copydetails CppAD::local::reverse_sparse_hessian_binary_op
291 */
292 template <class Vector_set>
294  size_t i_z ,
295  const addr_t* arg ,
296  bool* jac_reverse ,
297  const Vector_set& for_jac_sparsity ,
298  Vector_set& rev_hes_sparsity )
299 {
300  // check assumptions
301  CPPAD_ASSERT_UNKNOWN( size_t(arg[0]) < i_z );
302  CPPAD_ASSERT_UNKNOWN( size_t(arg[1]) < i_z );
303 
304  rev_hes_sparsity.binary_union(arg[0], arg[0], i_z, rev_hes_sparsity);
305  rev_hes_sparsity.binary_union(arg[1], arg[1], i_z, rev_hes_sparsity);
306 
307  if( jac_reverse[i_z] )
308  {
309  rev_hes_sparsity.binary_union(
310  arg[0], arg[0], arg[0], for_jac_sparsity);
311  rev_hes_sparsity.binary_union(
312  arg[0], arg[0], arg[1], for_jac_sparsity);
313 
314  rev_hes_sparsity.binary_union(
315  arg[1], arg[1], arg[0], for_jac_sparsity);
316  rev_hes_sparsity.binary_union(
317  arg[1], arg[1], arg[1], for_jac_sparsity);
318  }
319 
320  // I cannot think of a case where this is necessary, but it including
321  // it makes it like the other cases.
322  jac_reverse[arg[0]] |= jac_reverse[i_z];
323  jac_reverse[arg[1]] |= jac_reverse[i_z];
324  return;
325 }
326 // ---------------------------------------------------------------------------
327 /*!
328 Forward mode Hessian sparsity pattern for multiplication operator.
329 
330 The C++ source code corresponding to this operation is
331 \verbatim
332  w(x) = v0(x) * v1(x)
333 \endverbatim
334 
335 \param arg
336 is the index of the argument vector for the multiplication operation; i.e.,
337 arg[0], arg[1] are the left and right operands.
338 
339 \param for_jac_sparsity
340 for_jac_sparsity(arg[0]) constains the Jacobian sparsity for v0(x),
341 for_jac_sparsity(arg[1]) constains the Jacobian sparsity for v1(x).
342 
343 \param for_hes_sparsity
344 On input, for_hes_sparsity includes the Hessian sparsity for v0(x)
345 and v1(x); i.e., the sparsity can be a super set.
346 Upon return it includes the Hessian sparsity for w(x)
347 */
348 template <class Vector_set>
350  const addr_t* arg ,
351  const Vector_set& for_jac_sparsity ,
352  Vector_set& for_hes_sparsity )
353 { // --------------------------------------------------
354  // set of independent variables that v0 depends on
355  typename Vector_set::const_iterator itr_0(for_jac_sparsity, arg[0]);
356 
357  // loop over dependent variables with non-zero partial
358  size_t i_x = *itr_0;
359  while( i_x < for_jac_sparsity.end() )
360  { // N(i_x) = N(i_x) union L(v1)
361  for_hes_sparsity.binary_union(i_x, i_x, arg[1], for_jac_sparsity);
362  i_x = *(++itr_0);
363  }
364  // --------------------------------------------------
365  // set of independent variables that v1 depends on
366  typename Vector_set::const_iterator itr_1(for_jac_sparsity, arg[1]);
367 
368  // loop over dependent variables with non-zero partial
369  i_x = *itr_1;
370  while( i_x < for_jac_sparsity.end() )
371  { // N(i_x) = N(i_x) union L(v0)
372  for_hes_sparsity.binary_union(i_x, i_x, arg[0], for_jac_sparsity);
373  i_x = *(++itr_1);
374  }
375  return;
376 }
377 /*!
378 Forward mode Hessian sparsity pattern for division operator.
379 
380 The C++ source code corresponding to this operation is
381 \verbatim
382  w(x) = v0(x) / v1(x)
383 \endverbatim
384 
385 \param arg
386 is the index of the argument vector for the division operation; i.e.,
387 arg[0], arg[1] are the left and right operands.
388 
389 \param for_jac_sparsity
390 for_jac_sparsity(arg[0]) constains the Jacobian sparsity for v0(x),
391 for_jac_sparsity(arg[1]) constains the Jacobian sparsity for v1(x).
392 
393 \param for_hes_sparsity
394 On input, for_hes_sparsity includes the Hessian sparsity for v0(x)
395 and v1(x); i.e., the sparsity can be a super set.
396 Upon return it includes the Hessian sparsity for w(x)
397 */
398 template <class Vector_set>
400  const addr_t* arg ,
401  const Vector_set& for_jac_sparsity ,
402  Vector_set& for_hes_sparsity )
403 { // --------------------------------------------------
404  // set of independent variables that v0 depends on
405  typename Vector_set::const_iterator itr_0(for_jac_sparsity, arg[0]);
406 
407  // loop over dependent variables with non-zero partial
408  size_t i_x = *itr_0;
409  while( i_x < for_jac_sparsity.end() )
410  { // N(i_x) = N(i_x) union L(v1)
411  for_hes_sparsity.binary_union(i_x, i_x, arg[1], for_jac_sparsity);
412  i_x = *(++itr_0);
413  }
414  // --------------------------------------------------
415  // set of independent variables that v1 depends on
416  typename Vector_set::const_iterator itr_1(for_jac_sparsity, arg[1]);
417 
418  // loop over dependent variables with non-zero partial
419  i_x = *itr_1;
420  while( i_x < for_jac_sparsity.end() )
421  { // N(i_x) = N(i_x) union L(v0)
422  for_hes_sparsity.binary_union(i_x, i_x, arg[0], for_jac_sparsity);
423  // N(i_x) = N(i_x) union L(v1)
424  for_hes_sparsity.binary_union(i_x, i_x, arg[1], for_jac_sparsity);
425  i_x = *(++itr_1);
426  }
427  return;
428 }
429 /*!
430 Forward mode Hessian sparsity pattern for power operator.
431 
432 The C++ source code corresponding to this operation is
433 \verbatim
434  w(x) = pow( v0(x) , v1(x) )
435 \endverbatim
436 
437 \param arg
438 is the index of the argument vector for the power operation; i.e.,
439 arg[0], arg[1] are the left and right operands.
440 
441 \param for_jac_sparsity
442 for_jac_sparsity(arg[0]) constains the Jacobian sparsity for v0(x),
443 for_jac_sparsity(arg[1]) constains the Jacobian sparsity for v1(x).
444 
445 \param for_hes_sparsity
446 On input, for_hes_sparsity includes the Hessian sparsity for v0(x)
447 and v1(x); i.e., the sparsity can be a super set.
448 Upon return it includes the Hessian sparsity for w(x)
449 */
450 template <class Vector_set>
452  const addr_t* arg ,
453  const Vector_set& for_jac_sparsity ,
454  Vector_set& for_hes_sparsity )
455 { // --------------------------------------------------
456  // set of independent variables that v0 depends on
457  typename Vector_set::const_iterator itr_0(for_jac_sparsity, arg[0]);
458 
459  // loop over dependent variables with non-zero partial
460  size_t i_x = *itr_0;
461  while( i_x < for_jac_sparsity.end() )
462  { // N(i_x) = N(i_x) union L(v0)
463  for_hes_sparsity.binary_union(i_x, i_x, arg[0], for_jac_sparsity);
464  // N(i_x) = N(i_x) union L(v1)
465  for_hes_sparsity.binary_union(i_x, i_x, arg[1], for_jac_sparsity);
466  i_x = *(++itr_0);
467  }
468  // --------------------------------------------------
469  // set of independent variables that v1 depends on
470  typename Vector_set::const_iterator itr_1(for_jac_sparsity, arg[1]);
471 
472  // loop over dependent variables with non-zero partial
473  i_x = *itr_1;
474  while( i_x < for_jac_sparsity.end() )
475  { // N(i_x) = N(i_x) union L(v0)
476  for_hes_sparsity.binary_union(i_x, i_x, arg[0], for_jac_sparsity);
477  // N(i_x) = N(i_x) union L(v1)
478  for_hes_sparsity.binary_union(i_x, i_x, arg[1], for_jac_sparsity);
479  i_x = *(++itr_1);
480  }
481  return;
482 }
483 // ---------------------------------------------------------------------------
484 } } // END_CPPAD_LOCAL_NAMESPACE
485 # endif
CPPAD_TAPE_ADDR_TYPE addr_t
Definition: declare_ad.hpp:44
void reverse_sparse_hessian_addsub_op(size_t i_z, const addr_t *arg, bool *jac_reverse, const Vector_set &for_jac_sparsity, Vector_set &rev_hes_sparsity)
Reverse mode Hessian sparsity pattern for add and subtract operators.
void forward_sparse_hessian_mul_op(const addr_t *arg, const Vector_set &for_jac_sparsity, Vector_set &for_hes_sparsity)
Forward mode Hessian sparsity pattern for multiplication operator.
void forward_sparse_hessian_pow_op(const addr_t *arg, const Vector_set &for_jac_sparsity, Vector_set &for_hes_sparsity)
Forward mode Hessian sparsity pattern for power operator.
void reverse_sparse_hessian_pow_op(size_t i_z, const addr_t *arg, bool *jac_reverse, const Vector_set &for_jac_sparsity, Vector_set &rev_hes_sparsity)
Reverse mode Hessian sparsity pattern for power function.
void reverse_sparse_hessian_mul_op(size_t i_z, const addr_t *arg, bool *jac_reverse, const Vector_set &for_jac_sparsity, Vector_set &rev_hes_sparsity)
Reverse mode Hessian sparsity pattern for multiplication operator.
#define CPPAD_ASSERT_UNKNOWN(exp)
Check that exp is true, if not terminate execution.
void reverse_sparse_hessian_div_op(size_t i_z, const addr_t *arg, bool *jac_reverse, const Vector_set &for_jac_sparsity, Vector_set &rev_hes_sparsity)
Reverse mode Hessian sparsity pattern for division operator.
void forward_sparse_jacobian_binary_op(size_t i_z, const addr_t *arg, Vector_set &sparsity)
Forward mode Jacobian sparsity pattern for all binary operators.
void reverse_sparse_jacobian_binary_op(size_t i_z, const addr_t *arg, Vector_set &sparsity)
Reverse mode Jacobian sparsity pattern for all binary operators.
void forward_sparse_hessian_div_op(const addr_t *arg, const Vector_set &for_jac_sparsity, Vector_set &for_hes_sparsity)
Forward mode Hessian sparsity pattern for division operator.