Skip to content

Commit ee7fed2

Browse files
authored
Pre-release v0.1.0 (#39)
* added nnz hessian to statistics * separate jacobian init function
1 parent 7d8783d commit ee7fed2

2 files changed

Lines changed: 94 additions & 74 deletions

File tree

include/problem.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ typedef struct
3333
double time_forward_constraints;
3434

3535
int nnz_affine;
36-
int nnz_nonlinear;
36+
int nnz_nonlinear; /* jacobian of nonlinear constraints */
37+
int nnz_hessian;
3738
} Diff_engine_stats;
3839

3940
typedef struct problem
@@ -66,6 +67,8 @@ typedef struct problem
6667
/* Retains objective and constraints (shared ownership with caller) */
6768
problem *new_problem(expr *objective, expr **constraints, int n_constraints,
6869
bool verbose);
70+
void problem_init_jacobian(problem *prob);
71+
void problem_init_hessian(problem *prob);
6972
void problem_init_derivatives(problem *prob);
7073
void free_problem(problem *prob);
7174

src/problem.c

Lines changed: 90 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -70,77 +70,6 @@ problem *new_problem(expr *objective, expr **constraints, int n_constraints,
7070
return prob;
7171
}
7272

73-
void problem_init_derivatives(problem *prob)
74-
{
75-
Timer timer;
76-
clock_gettime(CLOCK_MONOTONIC, &timer.start);
77-
78-
// -------------------------------------------------------------------------------
79-
// Jacobian structure
80-
// -------------------------------------------------------------------------------
81-
prob->objective->jacobian_init(prob->objective);
82-
int nnz = 0;
83-
for (int i = 0; i < prob->n_constraints; i++)
84-
{
85-
expr *c = prob->constraints[i];
86-
c->jacobian_init(c);
87-
nnz += c->jacobian->nnz;
88-
89-
if (c->is_affine(c))
90-
{
91-
prob->stats.nnz_affine += c->jacobian->nnz;
92-
}
93-
else
94-
{
95-
prob->stats.nnz_nonlinear += c->jacobian->nnz;
96-
}
97-
}
98-
99-
prob->jacobian = new_csr_matrix(prob->total_constraint_size, prob->n_vars, nnz);
100-
101-
/* set sparsity pattern of jacobian */
102-
CSR_Matrix *H = prob->jacobian;
103-
H->p[0] = 0;
104-
int row_offset = 0;
105-
int nnz_offset = 0;
106-
for (int i = 0; i < prob->n_constraints; i++)
107-
{
108-
expr *c = prob->constraints[i];
109-
110-
for (int r = 1; r <= c->jacobian->m; r++)
111-
{
112-
H->p[row_offset + r] = nnz_offset + c->jacobian->p[r];
113-
}
114-
115-
memcpy(H->i + nnz_offset, c->jacobian->i, c->jacobian->nnz * sizeof(int));
116-
row_offset += c->jacobian->m;
117-
nnz_offset += c->jacobian->nnz;
118-
}
119-
assert(nnz_offset == nnz);
120-
121-
// -------------------------------------------------------------------------------
122-
// Lagrange Hessian structure
123-
// -------------------------------------------------------------------------------
124-
prob->objective->wsum_hess_init(prob->objective);
125-
nnz = prob->objective->wsum_hess->nnz;
126-
127-
for (int i = 0; i < prob->n_constraints; i++)
128-
{
129-
prob->constraints[i]->wsum_hess_init(prob->constraints[i]);
130-
nnz += prob->constraints[i]->wsum_hess->nnz;
131-
}
132-
133-
prob->lagrange_hessian = new_csr_matrix(prob->n_vars, prob->n_vars, nnz);
134-
memset(prob->lagrange_hessian->x, 0, nnz * sizeof(double)); /* affine shortcut */
135-
prob->hess_idx_map = (int *) malloc(nnz * sizeof(int));
136-
int *iwork = (int *) malloc(MAX(nnz, prob->n_vars) * sizeof(int));
137-
problem_lagrange_hess_fill_sparsity(prob, iwork);
138-
free(iwork);
139-
140-
clock_gettime(CLOCK_MONOTONIC, &timer.end);
141-
prob->stats.time_init_derivatives += GET_ELAPSED_SECONDS(timer);
142-
}
143-
14473
static void problem_lagrange_hess_fill_sparsity(problem *prob, int *iwork)
14574
{
14675
expr **constrs = prob->constraints;
@@ -226,6 +155,93 @@ static void problem_lagrange_hess_fill_sparsity(problem *prob, int *iwork)
226155
}
227156
}
228157

158+
void problem_init_jacobian(problem *prob)
159+
{
160+
Timer timer;
161+
clock_gettime(CLOCK_MONOTONIC, &timer.start);
162+
163+
// -------------------------------------------------------------------------------
164+
// Jacobian structure
165+
// -------------------------------------------------------------------------------
166+
prob->objective->jacobian_init(prob->objective);
167+
int nnz = 0;
168+
for (int i = 0; i < prob->n_constraints; i++)
169+
{
170+
expr *c = prob->constraints[i];
171+
c->jacobian_init(c);
172+
nnz += c->jacobian->nnz;
173+
174+
if (c->is_affine(c))
175+
{
176+
prob->stats.nnz_affine += c->jacobian->nnz;
177+
}
178+
else
179+
{
180+
prob->stats.nnz_nonlinear += c->jacobian->nnz;
181+
}
182+
}
183+
184+
prob->jacobian = new_csr_matrix(prob->total_constraint_size, prob->n_vars, nnz);
185+
186+
/* set sparsity pattern of jacobian */
187+
CSR_Matrix *H = prob->jacobian;
188+
H->p[0] = 0;
189+
int row_offset = 0;
190+
int nnz_offset = 0;
191+
for (int i = 0; i < prob->n_constraints; i++)
192+
{
193+
expr *c = prob->constraints[i];
194+
195+
for (int r = 1; r <= c->jacobian->m; r++)
196+
{
197+
H->p[row_offset + r] = nnz_offset + c->jacobian->p[r];
198+
}
199+
200+
memcpy(H->i + nnz_offset, c->jacobian->i, c->jacobian->nnz * sizeof(int));
201+
row_offset += c->jacobian->m;
202+
nnz_offset += c->jacobian->nnz;
203+
}
204+
assert(nnz_offset == nnz);
205+
206+
clock_gettime(CLOCK_MONOTONIC, &timer.end);
207+
prob->stats.time_init_derivatives += GET_ELAPSED_SECONDS(timer);
208+
}
209+
210+
void problem_init_hessian(problem *prob)
211+
{
212+
Timer timer;
213+
clock_gettime(CLOCK_MONOTONIC, &timer.start);
214+
215+
// -------------------------------------------------------------------------------
216+
// Lagrange Hessian structure
217+
// -------------------------------------------------------------------------------
218+
prob->objective->wsum_hess_init(prob->objective);
219+
int nnz = prob->objective->wsum_hess->nnz;
220+
221+
for (int i = 0; i < prob->n_constraints; i++)
222+
{
223+
prob->constraints[i]->wsum_hess_init(prob->constraints[i]);
224+
nnz += prob->constraints[i]->wsum_hess->nnz;
225+
}
226+
227+
prob->lagrange_hessian = new_csr_matrix(prob->n_vars, prob->n_vars, nnz);
228+
memset(prob->lagrange_hessian->x, 0, nnz * sizeof(double)); /* affine shortcut */
229+
prob->stats.nnz_hessian = nnz;
230+
prob->hess_idx_map = (int *) malloc(nnz * sizeof(int));
231+
int *iwork = (int *) malloc(MAX(nnz, prob->n_vars) * sizeof(int));
232+
problem_lagrange_hess_fill_sparsity(prob, iwork);
233+
free(iwork);
234+
235+
clock_gettime(CLOCK_MONOTONIC, &timer.end);
236+
prob->stats.time_init_derivatives += GET_ELAPSED_SECONDS(timer);
237+
}
238+
239+
void problem_init_derivatives(problem *prob)
240+
{
241+
problem_init_jacobian(prob);
242+
problem_init_hessian(prob);
243+
}
244+
229245
static inline void print_end_message(const Diff_engine_stats *stats)
230246
{
231247
printf("\n"
@@ -236,8 +252,9 @@ static inline void print_end_message(const Diff_engine_stats *stats)
236252
DIFF_ENGINE_VERSION);
237253

238254
printf("\nProblem statistics:\n");
239-
printf(" Nonzeros in affine constraints: %d\n", stats->nnz_affine);
240-
printf(" Nonzeros in nonlinear constraints: %d\n", stats->nnz_nonlinear);
255+
printf(" Affine constraints (nnz): %d\n", stats->nnz_affine);
256+
printf(" Jacobian nonlinear constraints (nnz): %d\n", stats->nnz_nonlinear);
257+
printf(" Lagrange Hessian (nnz): %d\n", stats->nnz_hessian);
241258

242259
printf("\nTiming (seconds):\n");
243260
printf(" Derivative structure (sparsity): %8.3f\n",

0 commit comments

Comments
 (0)