@@ -36,25 +36,18 @@ static void jacobian_init(expr *node)
3636 }
3737
3838 node -> jacobian = new_csr_matrix (node -> size , node -> n_vars , nnz );
39- }
40-
41- static void eval_jacobian (expr * node )
42- {
43- hstack_expr * hnode = (hstack_expr * ) node ;
4439
45- /* evaluate children 's jacobians */
40+ /* precompute sparsity pattern of this jacobian 's node */
4641 int row_offset = 0 ;
4742 CSR_Matrix * A = node -> jacobian ;
4843 A -> nnz = 0 ;
4944
5045 for (int i = 0 ; i < hnode -> n_args ; i ++ )
5146 {
5247 expr * child = hnode -> args [i ];
53- child -> eval_jacobian (child );
5448 CSR_Matrix * B = child -> jacobian ;
5549
56- /* copy columns and values */
57- memcpy (A -> x + A -> nnz , B -> x , B -> nnz * sizeof (double ));
50+ /* copy columns */
5851 memcpy (A -> i + A -> nnz , B -> i , B -> nnz * sizeof (int ));
5952
6053 /* set row pointers */
@@ -69,9 +62,27 @@ static void eval_jacobian(expr *node)
6962 A -> p [node -> size ] = A -> nnz ;
7063}
7164
72- static bool is_affine (expr * node )
65+ static void eval_jacobian (expr * node )
7366{
7467 hstack_expr * hnode = (hstack_expr * ) node ;
68+ CSR_Matrix * A = node -> jacobian ;
69+ A -> nnz = 0 ;
70+
71+ for (int i = 0 ; i < hnode -> n_args ; i ++ )
72+ {
73+ expr * child = hnode -> args [i ];
74+ child -> eval_jacobian (child );
75+
76+ /* copy values */
77+ memcpy (A -> x + A -> nnz , child -> jacobian -> x ,
78+ child -> jacobian -> nnz * sizeof (double ));
79+ A -> nnz += child -> jacobian -> nnz ;
80+ }
81+ }
82+
83+ static bool is_affine (const expr * node )
84+ {
85+ const hstack_expr * hnode = (const hstack_expr * ) node ;
7586
7687 for (int i = 0 ; i < hnode -> n_args ; i ++ )
7788 {
@@ -92,33 +103,6 @@ static void free_type_data(expr *node)
92103 }
93104}
94105
95- /* Helper function to initialize an hstack expr */
96- void init_hstack (expr * node , int d1 , int d2 , int n_vars )
97- {
98- node -> d1 = d1 ;
99- node -> d2 = d2 ;
100- node -> size = d1 * d2 ;
101- node -> n_vars = n_vars ;
102- node -> var_id = -1 ;
103- node -> refcount = 1 ;
104- node -> left = NULL ;
105- node -> right = NULL ;
106- node -> dwork = NULL ;
107- node -> iwork = NULL ;
108- node -> value = (double * ) calloc (node -> size , sizeof (double ));
109- node -> jacobian = NULL ;
110- node -> wsum_hess = NULL ;
111- node -> jacobian_init = jacobian_init ;
112- node -> wsum_hess_init = NULL ;
113- node -> eval_jacobian = eval_jacobian ;
114- node -> eval_wsum_hess = NULL ;
115- node -> local_jacobian = NULL ;
116- node -> local_wsum_hess = NULL ;
117- node -> forward = forward ;
118- node -> is_affine = is_affine ;
119- node -> free_type_data = free_type_data ;
120- }
121-
122106expr * new_hstack (expr * * args , int n_args , int n_vars )
123107{
124108 /* compute second dimension */
@@ -129,20 +113,18 @@ expr *new_hstack(expr **args, int n_args, int n_vars)
129113 }
130114
131115 /* Allocate the type-specific struct */
132- hstack_expr * hnode = (hstack_expr * ) malloc (sizeof (hstack_expr ));
133- if (!hnode ) return NULL ;
134-
116+ hstack_expr * hnode = (hstack_expr * ) calloc (1 , sizeof (hstack_expr ));
135117 expr * node = & hnode -> base ;
136118
137- /* Initialize base hstack fields */
138- init_hstack (node , args [0 ]-> d1 , d2 , n_vars );
119+ /* Initialize basic fields */
120+ init_expr (node , args [0 ]-> d1 , d2 , n_vars );
139121
140- /* Check if allocation succeeded */
141- if (! node -> value )
142- {
143- free ( hnode ) ;
144- return NULL ;
145- }
122+ /* Set function pointers */
123+ node -> forward = forward ;
124+ node -> jacobian_init = jacobian_init ;
125+ node -> eval_jacobian = eval_jacobian ;
126+ node -> is_affine = is_affine ;
127+ node -> free_type_data = free_type_data ;
146128
147129 /* Set type-specific fields */
148130 hnode -> args = args ;
0 commit comments