@@ -128,23 +128,29 @@ static void wsum_hess_init_impl(expr *node)
128128 else
129129 {
130130 /* chain rule: the Hessian is in this case given by
131- wsum_hess = term1 + term1 ^T + term2 + term3 where
131+ wsum_hess = C + C ^T + term2 + term3 where
132132
133- * term1 = J_{g2}^T diag(w) J_{g1}
133+ * C = J_{g2}^T diag(w) J_{g1}
134134 * term2 = sum_k w_k g2_k H_{g1_k}
135135 * term3 = sum_k w_k g1_k H_{g2_k}
136136
137- The two last terms are nonzero only if g1 and g2 are nonlinear.
137+ The two last terms are nonzero only if g1 and g2 are nonlinear.
138+ Here, we view multiply as the composition h(x) = f(g1(x), g2(x)) where f
139+ is the elementwise multiplication operator, and g1 and g2 are the left and
140+ right child nodes.
138141 */
139142
143+ /* prepare sparsity pattern of csc conversion */
144+ jacobian_csc_init (x );
145+ jacobian_csc_init (y );
146+
140147 /* both are linear operators */
141- CSC_Matrix * A = (( linear_op_expr * ) x ) -> A_csc ;
142- CSC_Matrix * B = (( linear_op_expr * ) y ) -> A_csc ;
148+ CSC_Matrix * Jg1 = x -> work -> jacobian_csc ;
149+ CSC_Matrix * Jg2 = y -> work -> jacobian_csc ;
143150
144151 /* Allocate workspace for Hessian computation */
145152 elementwise_mult_expr * mul_node = (elementwise_mult_expr * ) node ;
146- CSR_Matrix * C ; /* C = B^T diag(w) A */
147- C = BTA_alloc (A , B );
153+ CSR_Matrix * C = BTA_alloc (Jg1 , Jg2 ); /* C = Jg2^T diag(w) Jg1 */
148154 node -> work -> iwork = (int * ) malloc (C -> m * sizeof (int ));
149155
150156 CSR_Matrix * CT = AT_alloc (C , node -> work -> iwork );
@@ -174,14 +180,42 @@ static void eval_wsum_hess(expr *node, const double *w)
174180 }
175181 else
176182 {
183+ // ----------------------------------------------------------------------
184+ // convert Jacobians of children to CSC format
185+ // (we only need to do this once if the child is affine)
186+ // TODO: what if we have parameters? Should we set jacobian_csc_filled
187+ // to false whenever parameters change value?
188+ // ----------------------------------------------------------------------
189+ if (!x -> work -> jacobian_csc_filled )
190+ {
191+ csr_to_csc_fill_values (x -> jacobian , x -> work -> jacobian_csc ,
192+ x -> work -> csc_work );
193+
194+ if (x -> is_affine (x ))
195+ {
196+ x -> work -> jacobian_csc_filled = true;
197+ }
198+ }
199+
200+ if (!y -> work -> jacobian_csc_filled )
201+ {
202+ csr_to_csc_fill_values (y -> jacobian , y -> work -> jacobian_csc ,
203+ y -> work -> csc_work );
204+
205+ if (y -> is_affine (y ))
206+ {
207+ y -> work -> jacobian_csc_filled = true;
208+ }
209+ }
210+
177211 /* both are linear operators */
178- CSC_Matrix * A = (( linear_op_expr * ) x ) -> A_csc ;
179- CSC_Matrix * B = (( linear_op_expr * ) y ) -> A_csc ;
212+ CSC_Matrix * Jg1 = x -> work -> jacobian_csc ;
213+ CSC_Matrix * Jg2 = y -> work -> jacobian_csc ;
180214 CSR_Matrix * C = ((elementwise_mult_expr * ) node )-> CSR_work1 ;
181215 CSR_Matrix * CT = ((elementwise_mult_expr * ) node )-> CSR_work2 ;
182216
183217 /* Compute C = B^T diag(w) A */
184- BTDA_fill_values (A , B , w , C );
218+ BTDA_fill_values (Jg1 , Jg2 , w , C );
185219
186220 /* Compute CT = C^T = A^T diag(w) B */
187221 AT_fill_values (C , CT , node -> work -> iwork );
0 commit comments