# Removing small elements from a sparse matrix

**URL:** <https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405>\
**Category:** General Usage\
**Created:** [April 22, 2019, 2:32pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405 "2019-04-22T14:32:43Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 22, 2019, 2:32pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/1 "2019-04-22T14:32:44Z")

</div>

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,

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 22, 2019, 2:39pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/2 "2019-04-22T14:39:34Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)\
**Post date:** [April 22, 2019, 3:59pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/3 "2019-04-22T15:59:03Z")

</div>

```julia
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

```

---

<div class="post-metadata">

**Author:** ![dkarrasch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dkarrasch/32/7410_2.png) [@dkarrasch](https://discourse.julialang.org/u/dkarrasch)\
**Post date:** [April 22, 2019, 4:50pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/4 "2019-04-22T16:50:45Z")

</div>

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

```julia
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.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 22, 2019, 7:58pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/5 "2019-04-22T19:58:21Z")

</div>

> [@mohamed82008](#):
>
> a = sprand(5, 5, 1.0) / 10^6;

Thanks ! This is exactly what I need.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 22, 2019, 7:59pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/6 "2019-04-22T19:59:01Z")

</div>

> [@dkarrasch](#):
>
> 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.

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

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 22, 2019, 8:00pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/7 "2019-04-22T20:00:00Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![dkarrasch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dkarrasch/32/7410_2.png) [@dkarrasch](https://discourse.julialang.org/u/dkarrasch)\
**Post date:** [April 23, 2019, 9:58am UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/8 "2019-04-23T09:58:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [April 23, 2019, 10:43am UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/9 "2019-04-23T10:43:54Z")

</div>

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!`?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 23, 2019, 11:36am UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/10 "2019-04-23T11:36:39Z")

</div>

> [@carstenbauer](#):
>
> I’d find it convenient to have a similar function for regular (or even abstract) arrays as well

It is rather trivial to do, eg

```julia
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.

---

<div class="post-metadata">

**Author:** ![dkarrasch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dkarrasch/32/7410_2.png) [@dkarrasch](https://discourse.julialang.org/u/dkarrasch)\
**Post date:** [April 23, 2019, 2:31pm UTC](https://discourse.julialang.org/t/removing-small-elements-from-a-sparse-matrix/23405/11 "2019-04-23T14:31:29Z")

</div>

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.
