== Sparse Matrix-Vector Multiplication == In this example, we verify the functional correctness of a matrix-vector multiplication routine where the matrix is represented in a sparse (Compressed Sparse Row) representation. File `csr.h`: {{{ #ifndef _CSR_H #define _CSR_H /* Compressed Sparse Row (CSR) sparse matrix representation. */ struct csr_matrix { double *val; // length NZ (number of non-0s) int *col_ind; // length NZ int *row_ptr; // length N+1. row_ptr[N]=NZ. int rows, cols; // number of rows (N), number of columns }; /* Multiplies matrix m and (dense) vector v, storing result in already allocated vector p. If m has dimensions NxM then v has length M and p has length N. */ void csr_matrix_vector_multiply(struct csr_matrix *m, double *v, double *p); #endif }}} File `csr.c`: {{{ /* Implementation of CSR matrix-vector multiplication from "LAProof: A Library of Formal Proofs of Accuracy and Correctness for Linear Algebra Programs" by Kellison, Appel, Tekriwal, and Bindel, IEEE 30th Symposium on Computer Arithmetic, 2023. That paper cites Barrett et al., "Templates for the Solution of Linear Systems: Building Blocks for Iterative Methods", SIAM, 1994, as the source of the algorithm. */ #include "csr.h" #define fma(x,y,s) (x*y+s) void csr_matrix_vector_multiply(struct csr_matrix *m, double *v, double *p) { int i, rows=m->rows; double *val = m->val; int *col_ind = m->col_ind; int *row_ptr = m->row_ptr; int next=row_ptr[0]; for (i=0; i #include #include #include "csr.h" // N,M=number of rows,columns. N_B,M_B=upper bounds on N,M $input int N_B = 3, M_B = 3, N, M; $assume (1<=N && N<=N_B && 1<=M && M<=M_B); // the non-0 entries for the matrix and the (dense) vector $input double A[N*M], V[M]; /* Fills in p[0],...,p[len-1] with a strictly increasing sequence of integers in [0,max]. Precondition: 0 <= len <= max+1 */ void strict_inc(int * p, int len, int max) { $assert(0<=len && len <= max+1); for (int i=0; i j) break; } return 0.0; } /* Makes a dense matrix from the given CSR matrix */ double ** make_dense(struct csr_matrix mat) { int n = mat.rows, m = mat.cols; double ** dense = malloc(n*sizeof(double*)); for (int i=0; i