# Function to return number of non-zero elements in a matrix

I’d like to use Stan’s sparse matrix functions, such as `csr_extract_w`, but I need to known the number of non-zero values in order to declare this vector inside a Stan script.

Could you elaborate a little bit on your use case? I’m pretty sure (but not completely positive) that because Stan does not support discrete parameters, the only way for a matrix element to be a literal zero is if either

• the matrix is data or transformed data
• the matrix is of some constrained data type where certain elements are constrained to zero a priori.

In either case, the number of zeros should be a priori known.

1 Like

I have a sparse (random effects) matrix mostly filled with 0’s, by construction that I will multiply by a vector of regression coefficients under a sparse configuration. For reasons of how the associated regression coefficients are indexed, I am not able to render the sparse (w,v,u) representation outside of Stan (in R). I must do so within Stan and it has explicit functions for this purpose; e.g. `csr_extract_w()`. The problem is that to declare a Stan vector to hold the output of `csr_extract_w(A)` where `A` is some sparse matrix, I need to know the number of non-zero elements in `A` (to dimension the length of the output vector). Now, I can’t use R to get the number of non-zero elements in `A` because I will be embedding the sparse matrix multiplication within a `reduce_sum()` function.

Got it. Yeah, that seems like a tough indexing problem to solve. I imagine there is a way to handle all the indices in a super clever way, but also that it might not be worth anyone’s time to figure it out (note that it would be a potential efficiency gain, however, to slice the sparse representation rather than the full matrix in `reduce_sum`, because it would ensure that each chunk gets a similar number of nonzero elements).

Anyway, here is a function for the number of nonzero elements. Whether to double-loop over the matrix elements or (as I did) to flatten the matrix and loop once is a matter of taste.

``````  int nnz(matrix x) {
int N = num_elements(x);
vector[N] x2 = to_vector(x);
int out = 0;
for(i in 1:N){
if(x2[i] != 0) {
out += 1;
}
}
return(out);
}
``````