# Generating a sparse matrix from a piecewise function

**URL:** <https://discourse.julialang.org/t/generating-a-sparse-matrix-from-a-piecewise-function/91119>\
**Category:** Performance\
**Tags:** question, sparse, random\
**Created:** [December 2, 2022, 12:21am UTC](https://discourse.julialang.org/t/generating-a-sparse-matrix-from-a-piecewise-function/91119 "2022-12-02T00:21:37Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![RobertGregg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/robertgregg/32/22105_2.png) [@RobertGregg](https://discourse.julialang.org/u/RobertGregg)\
**Post date:** [December 2, 2022, 12:21am UTC](https://discourse.julialang.org/t/generating-a-sparse-matrix-from-a-piecewise-function/91119/1 "2022-12-02T00:21:37Z")

</div>

I’m trying to generate a random sparse matrix R where each element in R can take on the following values:

r\_{ij}= \left\{ \begin{array}{ll} 1 & \text{with probability } \frac{1}{6}\\ 0 & \text{with probability } \frac{2}{3} \\ -1 & \text{with probability } \frac{1}{6} \\ \end{array} \right.

What would be the best way to do this in Julia? My first approach looks like this:

```julia
using SparseArrays

function genR1(n,m)
    R = spzeros(n,m)

    for i in eachindex(R)
        r = rand()
        if r > 5/6
            R[i] = 1
        elseif r > 2/3
            R[i] = -1
        end
    end
    
    return R
end

```

however, I found this to be slower and allocate more than not using sparse matrices at all.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [December 2, 2022, 12:32am UTC](https://discourse.julialang.org/t/generating-a-sparse-matrix-from-a-piecewise-function/91119/2 "2022-12-02T00:32:48Z")

</div>

Don’t use a sparse matrix for this. Sparse matrices are only for sparsity of 95% or greater.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 2, 2022, 12:36am UTC](https://discourse.julialang.org/t/generating-a-sparse-matrix-from-a-piecewise-function/91119/3 "2022-12-02T00:36:46Z")

</div>

No matter what you do, mutating a sparse array element-by-element is very slow (because the [compressed column format](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format)) needs to be re-packed each time you insert a new nonzero).

Here, your matrix isn’t very sparse, so I wouldn’t use a sparse matrix at all in this case. You could just do

```julia
R = rand([1,-1,0,0,0,0], n, m)

```

If you want you can convert this to a sparse matrix with `sparse(R)`, but it’s generally not worth using a sparse-matrix data structure with a matrix that is only 2/3 sparse.

However, it is possible to generate such a sparse matrix directly, by calling `sprand` with a custom random-number generator. (This would be worth it if the probability p of a nonzero entry were _much_ smaller than 1/3.) In particular, you could do:

```julia
p = 1/3 # probability of nonzero (±1) entry
R = sprand(n, m, p, N -> rand((-1,1), N))

```
