functions {
matrix sparse_matrix(){
int m = 2;
vector[3] a = [1, 2, 3]';
int b[3] = {1, 2, 2};
int c[3] = {1, 1, 2};
matrix[m, m] d = csr_to_dense_matrix(m, m, a, b, c);
return(d);
}
}
Which I thought would give me the matrix d = \begin{bmatrix} 1 & 2 \\ 0 & 3\end{bmatrix} but instead I get:
> expose_stan_functions("model/csr_matrix.stan")
> sparse_matrix()
Error in sparse_matrix() :
Exception: csr_to_dense_matrix: u/z (1) and v (3) must match in size (in 'unknown file name' at line 8)
The way you set up indices does not follow the compressed sparse row (csr) format: https://mc-stan.org/math/dc/d79/group__csr__format.html. In this format, elements are listed row-wise, and rowstarts lists the index at which a new row starts (plus the last element which is the number of rows + 1).
This works:
functions {
matrix sparse_matrix(){
int m = 2;
vector[3] x = [1, 2, 3]';
int colidx[3] = {1, 2, 2};
int rowstarts[3] = {1, 3, 4};
matrix[m, m] d = csr_to_dense_matrix(m, m, x, colidx, rowstarts);
return(d);
}
}
rowstarts indexes which element in the sparse matrix starts a new row.
Take this example:
[ 0 2 0 4
5 0 0 8
0 10 0 0
13 0 15 0]
Here, nz = {2, 4, 5, 8, 10, 13, 15}, colidx = {2, 4, 1, 4, 2, 1, 3}, and rowstarts would be {1, 3, 5, 6, 8}. Which means that row 1 starts at the first nonzero element (the 2), row 2 starts at the 3rd (the 5), and so on. The last element is one plus the total number of nonzeros in the matrix.
It seems that the documentation of csr_to_dense_matrix in the functions reference is wrong, in that it says that u and v must have the same size, which is clearly not the case an in my example before. I’ll post a patch to fix it.