1 // $Id: sparse_unary_op.hpp 3865 2017-01-19 01:57:55Z bradbell $
2 # ifndef CPPAD_LOCAL_SPARSE_UNARY_OP_HPP
3 # define CPPAD_LOCAL_SPARSE_UNARY_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_unary_op.hpp
18 Forward and reverse mode sparsity patterns for unary operators.
19 */
20
21
22 /*!
23 Forward mode Jacobian sparsity pattern for all unary operators.
24
25 The C++ source code corresponding to a unary operation has the form
26 \verbatim
27 z = fun(x)
28 \endverbatim
29 where fun is a C++ unary function, or it has the form
30 \verbatim
31 z = x op q
32 \endverbatim
33 where op is a C++ binary unary operator and q is a parameter.
34
35 \tparam Vector_set
36 is the type used for vectors of sets. It can be either
37 sparse_pack or sparse_list.
38
39 \param i_z
40 variable index corresponding to the result for this operation;
41 i.e., z.
42
43 \param i_x
44 variable index corresponding to the argument for this operator;
45 i.e., x.
46
47
48 \param sparsity
49 \b Input: The set with index \a arg[0] in \a sparsity
50 is the sparsity bit pattern for x.
51 This identifies which of the independent variables the variable x
52 depends on.
53 \n
54 \n
55 \b Output: The set with index \a i_z in \a sparsity
56 is the sparsity bit pattern for z.
57 This identifies which of the independent variables the variable z
58 depends on.
59 \n
60
61 \par Checked Assertions:
62 \li \a i_x < \a i_z
63 */
64
65 template <class Vector_set>
forward_sparse_jacobian_unary_op(size_t i_z,size_t i_x,Vector_set & sparsity)66 inline void forward_sparse_jacobian_unary_op(
67 size_t i_z ,
68 size_t i_x ,
69 Vector_set& sparsity )
70 {
71 // check assumptions
72 CPPAD_ASSERT_UNKNOWN( i_x < i_z );
73
74 sparsity.assignment(i_z, i_x, sparsity);
75 }
76 /*!
77 Reverse mode Jacobian sparsity pattern for all unary operators.
78
79 The C++ source code corresponding to a unary operation has the form
80 \verbatim
81 z = fun(x)
82 \endverbatim
83 where fun is a C++ unary function, or it has the form
84 \verbatim
85 z = x op q
86 \endverbatim
87 where op is a C++ bianry operator and q is a parameter.
88
89 This routine is given the sparsity patterns
90 for a function G(z, y, ... )
91 and it uses them to compute the sparsity patterns for
92 \verbatim
93 H( x , w , u , ... ) = G[ z(x) , x , w , u , ... ]
94 \endverbatim
95
96 \tparam Vector_set
97 is the type used for vectors of sets. It can be either
98 sparse_pack or sparse_list.
99
100
101 \param i_z
102 variable index corresponding to the result for this operation;
103 i.e. the row index in sparsity corresponding to z.
104
105 \param i_x
106 variable index corresponding to the argument for this operator;
107 i.e. the row index in sparsity corresponding to x.
108
109 \param sparsity
110 \b Input:
111 The set with index \a i_z in \a sparsity
112 is the sparsity bit pattern for G with respect to the variable z.
113 \n
114 \b Input:
115 The set with index \a i_x in \a sparsity
116 is the sparsity bit pattern for G with respect to the variable x.
117 \n
118 \b Output:
119 The set with index \a i_x in \a sparsity
120 is the sparsity bit pattern for H with respect to the variable x.
121
122 \par Checked Assertions:
123 \li \a i_x < \a i_z
124 */
125
126 template <class Vector_set>
reverse_sparse_jacobian_unary_op(size_t i_z,size_t i_x,Vector_set & sparsity)127 inline void reverse_sparse_jacobian_unary_op(
128 size_t i_z ,
129 size_t i_x ,
130 Vector_set& sparsity )
131 {
132 // check assumptions
133 CPPAD_ASSERT_UNKNOWN( i_x < i_z );
134
135 sparsity.binary_union(i_x, i_x, i_z, sparsity);
136
137 return;
138 }
139 // ---------------------------------------------------------------------------
140 /*!
141 Reverse mode Hessian sparsity pattern for linear unary operators.
142
143 The C++ source code corresponding to this operation is
144 \verbatim
145 z = fun(x)
146 \endverbatim
147 where fun is a linear functions; e.g. abs, or
148 \verbatim
149 z = x op q
150 \endverbatim
151 where op is a C++ binary operator and q is a parameter.
152
153 \copydetails CppAD::local::reverse_sparse_hessian_unary_op
154 */
155 template <class Vector_set>
reverse_sparse_hessian_linear_unary_op(size_t i_z,size_t i_x,bool * rev_jacobian,const Vector_set & for_jac_sparsity,Vector_set & rev_hes_sparsity)156 inline void reverse_sparse_hessian_linear_unary_op(
157 size_t i_z ,
158 size_t i_x ,
159 bool* rev_jacobian ,
160 const Vector_set& for_jac_sparsity ,
161 Vector_set& rev_hes_sparsity )
162 {
163 // check assumptions
164 CPPAD_ASSERT_UNKNOWN( i_x < i_z );
165
166 rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity);
167
168 rev_jacobian[i_x] |= rev_jacobian[i_z];
169 return;
170 }
171
172 /*!
173 Reverse mode Hessian sparsity pattern for non-linear unary operators.
174
175 The C++ source code corresponding to this operation is
176 \verbatim
177 z = fun(x)
178 \endverbatim
179 where fun is a non-linear functions; e.g. sin. or
180 \verbatim
181 z = q / x
182 \endverbatim
183 where q is a parameter.
184
185
186 \copydetails CppAD::local::reverse_sparse_hessian_unary_op
187 */
188 template <class Vector_set>
reverse_sparse_hessian_nonlinear_unary_op(size_t i_z,size_t i_x,bool * rev_jacobian,const Vector_set & for_jac_sparsity,Vector_set & rev_hes_sparsity)189 inline void reverse_sparse_hessian_nonlinear_unary_op(
190 size_t i_z ,
191 size_t i_x ,
192 bool* rev_jacobian ,
193 const Vector_set& for_jac_sparsity ,
194 Vector_set& rev_hes_sparsity )
195 {
196 // check assumptions
197 CPPAD_ASSERT_UNKNOWN( i_x < i_z );
198
199 rev_hes_sparsity.binary_union(i_x, i_x, i_z, rev_hes_sparsity);
200 if( rev_jacobian[i_z] )
201 rev_hes_sparsity.binary_union(i_x, i_x, i_x, for_jac_sparsity);
202
203 rev_jacobian[i_x] |= rev_jacobian[i_z];
204 return;
205 }
206
207 // ---------------------------------------------------------------------------
208 /*!
209 Forward mode Hessian sparsity pattern for non-linear unary operators.
210
211 The C++ source code corresponding to this operation is
212 \verbatim
213 w(x) = fun( v(x) )
214 \endverbatim
215 where fun is a non-linear function.
216
217 \param i_v
218 is the index of the argument variable v
219
220 \param for_jac_sparsity
221 for_jac_sparsity(i_v) constains the Jacobian sparsity for v(x).
222
223 \param for_hes_sparsity
224 On input, for_hes_sparsity includes the Hessian sparsity for v(x); i.e.,
225 the sparsity can be a super set.
226 Upon return it includes the Hessian sparsity for w(x)
227 */
228 template <class Vector_set>
forward_sparse_hessian_nonlinear_unary_op(size_t i_v,const Vector_set & for_jac_sparsity,Vector_set & for_hes_sparsity)229 inline void forward_sparse_hessian_nonlinear_unary_op(
230 size_t i_v ,
231 const Vector_set& for_jac_sparsity ,
232 Vector_set& for_hes_sparsity )
233 {
234 // set of independent variables that v depends on
235 typename Vector_set::const_iterator itr(for_jac_sparsity, i_v);
236
237 // next independent variables that v depends on
238 size_t i_x = *itr;
239
240 // loop over dependent variables with non-zero partial
241 while( i_x < for_jac_sparsity.end() )
242 { // N(i_x) = N(i_x) union L(i_v)
243 for_hes_sparsity.binary_union(i_x, i_x, i_v, for_jac_sparsity);
244 i_x = *(++itr);
245 }
246 return;
247 }
248
249 } } // END_CPPAD_LOCAL_NAMESPACE
250 # endif
251