# Removing small elements from a sparse matrix

Hi, I am interested in removing entries in a sparse (SparseMatrixCSC{Float64,Int64}) matrix which are very small, for example, less than 1E-16 in absolute value. Often in the middle of operations with sparse matrices, these residual values build up, and it would be good to get rid of these.

Is there an inbuilt function to make all entries with values below a threshold zero ?

I tried writing my own routine

for x in A

end

I don’t know what to put in the …, as x is passed by value within the body of the loop,

The non-sparse values are stored in `A.nzval`, which is a vector, you should be able to set values below a threshold to `0` like in any other vector. This will not change the sparsity structure though, but may be sufficient for your purposes.

``````julia> a = sprand(5, 5, 1.0) / 10^6;

julia> SparseArrays.fkeep!(a, (i,j,x) -> abs(x) > 1e-4)
5×5 SparseMatrixCSC{Float64,Int64} with 0 stored entries
``````
3 Likes

I think `droptol!` is exactly what you need. The docstring contains an error. It should read

``````droptol!(A::SparseMatrixCSC, tol; trim::Bool = true)

Removes stored values from A whose absolute value is less or equal to tol,
optionally trimming resulting excess space from A.rowval and A.nzval when trim is
true.
``````

EDIT: The docstring is fixed now.

9 Likes

Thanks ! This is exactly what I need.

Thanks. I also found this function fkeep being used in the sparematrix.jl file

Thanks. I do want to trim the matrix though. So I could use droptol!, as suggested by @dkarrasch

1 Like

What a shame! I authored the erroneous docstring myself… Will fix it.

2 Likes

Although I see that `droptol!` makes most sense for sparse matrices I’d find it convenient to have a similar function for regular (or even abstract) arrays as well. Effective zeros occur frequently in numerics.

The `drop` in the name could be misleading in this case though. Maybe something like `zerotol!`?

It is rather trivial to do, eg

``````function zero_small!(M::AbstractMatrix, tol)
for ι in eachindex(M)
if abs(M[ι]) ≤ tol
M[ι] = 0
end
end
M
end
``````

or something similar. I don’t think it is worth packaging up in a library.

It makes sense to have a specialized version for sparse matrices though, because of the efficiency gains.

I fully agree. I gave a very related problem in an “introduction to programming (in julia, of course!)” exam last year, and tested several approaches that I thought student could come up with beforehand: logical indexing, `for` loop, `findall`, and I don’t remember what else I had in mind. I was very happy to see that the most straightforward for-loop with if-conditional (as written by @Tamas_Papp), using only the most elementary programming tools that you teach in a one-week course, yielded the fastest implementation.

2 Likes