Skip to content

Commit 0016174

Browse files
authored
Merge pull request #66 from SparseDifferentiation/quad-form-chain-rule-jacobian
[Ready for review] Quad form chain rule
2 parents 0404d0d + dc84d46 commit 0016174

14 files changed

Lines changed: 485 additions & 262 deletions

File tree

include/problem.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ typedef struct
3636
int nnz_affine;
3737
int nnz_nonlinear; /* jacobian of nonlinear constraints */
3838
int nnz_hessian;
39+
int n_vars;
40+
int total_constraint_size;
3941
} Diff_engine_stats;
4042

4143
typedef struct problem

include/subexpr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct quad_form_expr
4848
{
4949
expr base;
5050
CSR_Matrix *Q;
51+
CSC_Matrix *QJf; /* Q * J_f in CSC (for chain rule hessian) */
5152
} quad_form_expr;
5253

5354
/* Sum reduction along an axis */

include/utils/CSC_Matrix.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,37 @@ CSC_Matrix *new_csc_matrix(int m, int n, int nnz);
2929
/* Free a CSC matrix */
3030
void free_csc_matrix(CSC_Matrix *matrix);
3131

32-
CSC_Matrix *csr_to_csc(const CSR_Matrix *A);
33-
34-
/* Allocate sparsity pattern for C = A^T D A for diagonal D */
32+
/* Fill sparsity of C = A^T D A for diagonal D */
3533
CSR_Matrix *ATA_alloc(const CSC_Matrix *A);
3634

37-
/* Allocate sparsity pattern for C = B^T D A for diagonal D */
35+
/* Fill sparsity of C = B^T D A for diagonal D */
3836
CSR_Matrix *BTA_alloc(const CSC_Matrix *A, const CSC_Matrix *B);
3937

40-
/* Compute values for C = A^T D A. C must have precomputed sparsity pattern */
38+
/* Fill sparsity of C = BA, where B is symmetric. */
39+
CSC_Matrix *symBA_alloc(const CSR_Matrix *B, const CSC_Matrix *A);
40+
41+
/* Compute values for C = A^T D A (null d corresponds to D as identity) */
4142
void ATDA_fill_values(const CSC_Matrix *A, const double *d, CSR_Matrix *C);
4243

43-
/* Compute values for C = B^T D A. C must have precomputed sparsity pattern */
44+
/* Compute values for C = B^T D A (null d corresonds to D as identity) */
4445
void BTDA_fill_values(const CSC_Matrix *A, const CSC_Matrix *B, const double *d,
4546
CSR_Matrix *C);
4647

47-
/* C = z^T A where A is in CSC format and C is assumed to have one row.
48-
* C must have column indices pre-computed. Fills in values of C only.
49-
*/
50-
void csc_matvec_fill_values(const CSC_Matrix *A, const double *z, CSR_Matrix *C);
48+
/* Fill values of C = BA. The matrix B does not have to be symmetric */
49+
void BA_fill_values(const CSR_Matrix *B, const CSC_Matrix *A, CSC_Matrix *C);
50+
51+
/* Fill values of C = x^T A. The matrix C must have filled sparsity. */
52+
void yTA_fill_values(const CSC_Matrix *A, const double *x, CSR_Matrix *C);
53+
54+
/* Count nonzero columns of a CSC matrix */
55+
int count_nonzero_cols_csc(const CSC_Matrix *A);
5156

52-
CSC_Matrix *csr_to_csc_fill_sparsity(const CSR_Matrix *A, int *iwork);
57+
/* convert from CSR to CSC format */
58+
CSC_Matrix *csr_to_csc_alloc(const CSR_Matrix *A, int *iwork);
5359
void csr_to_csc_fill_values(const CSR_Matrix *A, CSC_Matrix *C, int *iwork);
5460

55-
CSR_Matrix *csc_to_csr_fill_sparsity(const CSC_Matrix *A, int *iwork);
61+
/* convert from CSC to CSR format */
62+
CSR_Matrix *csc_to_csr_alloc(const CSC_Matrix *A, int *iwork);
5663
void csc_to_csr_fill_values(const CSC_Matrix *A, CSR_Matrix *C, int *iwork);
5764

5865
#endif /* CSC_MATRIX_H */

src/affine/left_matmul.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ static void jacobian_init_impl(expr *node)
8888

8989
/* initialize child's jacobian and precompute sparsity of its CSC */
9090
jacobian_init(x);
91-
lnode->Jchild_CSC = csr_to_csc_fill_sparsity(x->jacobian, node->work->iwork);
91+
lnode->Jchild_CSC = csr_to_csc_alloc(x->jacobian, node->work->iwork);
9292

9393
/* precompute sparsity of this node's jacobian in CSC and CSR */
9494
lnode->J_CSC = lnode->A->block_left_mult_sparsity(lnode->A, lnode->Jchild_CSC,
9595
lnode->n_blocks);
96-
node->jacobian = csc_to_csr_fill_sparsity(lnode->J_CSC, lnode->csc_to_csr_work);
96+
node->jacobian = csc_to_csr_alloc(lnode->J_CSC, lnode->csc_to_csr_work);
9797
}
9898

9999
static void eval_jacobian(expr *node)

src/bivariate_restricted_dom/quad_over_lin.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,7 @@ static void eval_jacobian(expr *node)
164164
}
165165

166166
/* chain rule (no derivative wrt y) using CSC format */
167-
csc_matvec_fill_values(x->work->jacobian_csc, node->work->dwork,
168-
node->jacobian);
167+
yTA_fill_values(x->work->jacobian_csc, node->work->dwork, node->jacobian);
169168

170169
/* insert derivative wrt y at right place (for correctness this assumes
171170
that y does not appear in the numerator, but this will always be

src/expr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ void jacobian_csc_init(expr *node)
5151
}
5252
node->work->csc_work = (int *) malloc(node->n_vars * sizeof(int));
5353
node->work->jacobian_csc =
54-
csr_to_csc_fill_sparsity(node->jacobian, node->work->csc_work);
54+
csr_to_csc_alloc(node->jacobian, node->work->csc_work);
5555
}
5656

5757
void free_expr(expr *node)

0 commit comments

Comments
 (0)