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