# Help needed with some matrix manipulation

**URL:** <https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341>\
**Category:** General Usage\
**Created:** [March 26, 2019, 9:49am UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341 "2019-03-26T09:49:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![timueh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timueh/32/12379_2.png) [@timueh](https://discourse.julialang.org/u/timueh)\
**Post date:** [March 26, 2019, 9:49am UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341/1 "2019-03-26T09:49:13Z")

</div>

I need some code review… 🙂

Suppose you are given a matrix A \in \mathbb{N}^{m \times n} you are to determine all the rows k \leq m of A that have a given maximum interaction j which is given by

j = \sum\_{i=0}^{n} \mathbf{1}\_{A\_{k,i} }, \quad \text{where} \quad \mathbf{1}\_{A\_{k,i}} = \begin{cases} 1, & A\_{k,i} \> 0, \\ 0, & \text{otherwise}.\end{cases}

Here’s an example. Take

```julia
julia> inds
15×4 Array{Int64,2}:
 0 0 0 0
 1 0 0 0
 0 1 0 0
 0 0 1 0
 0 0 0 1
 2 0 0 0
 1 1 0 0
 1 0 1 0
 1 0 0 1
 0 2 0 0
 0 1 1 0
 0 1 0 1
 0 0 2 0
 0 0 1 1
 0 0 0 2

```

and set j = 2, then

```julia
julia> get_interaction(inds,2)
6×4 Array{Int64,2}:
 1 1 0 0
 1 0 1 0
 1 0 0 1
 0 1 1 0
 0 1 0 1
 0 0 1 1

```

So, the function `get_interaction` finds all rows of a matrix that have j non-zero entries.

```julia
function get_interaction(inds::Matrix{Int},j::Int)
    M = .!(iszero.(inds)) # auxiliary variable that is true for every non-zero element of inds
    J = findall(x->x==j,sum(M;dims=2))
    vcat(map(j->inds[j.I[1],:],J)'...) # return as a matrix of integers
end

```

This is _one_ way to implement this, but it feels too bulky. There’s probably a more clever way to exploit the CartesianIndices returned by `findall`.

thanks!

p.s.: The last row could be simplified to the more performant

```julia
    map(j->inds[j.I[1],:],J)

```

which would return an arrray of arrays of integers

```julia
julia> get_interaction(inds,2)
6-element Array{Array{Int64,1},1}:
 [1, 1, 0, 0]
 [1, 0, 1, 0]
 [1, 0, 0, 1]
 [0, 1, 1, 0]
 [0, 1, 0, 1]
 [0, 0, 1, 1]

```

---

<div class="post-metadata">

**Author:** ![under-Peter](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/under-peter/32/3626_2.png) [@under-Peter](https://discourse.julialang.org/u/under-Peter)\
**Post date:** [March 26, 2019, 10:01am UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341/2 "2019-03-26T10:01:01Z")

</div>

Imho a quite julian way would be:

```julia
 julia> interactions(inds,j) = Iterators.filter(x -> count(!iszero,x) == j, 
                                                eachrow(inds))

```

which quite closely matches your description. Note that this returns an iterator and to get the resulting vectors you need to `collect` the result or just iterate through it - might be advantageous if you only work on one row at a time.

The standard `filter` doesn’t work on `eachrow` unless you collect first - that’s why I used the one from `Iterators` but there might be a better solution.

edit:  
Comparing the performance for your example input I get roughly an order of magnitude speedup. For larger problems still factor 4 but note that even collecting the iterator returns `SubArrays`. To get the same, you can e.g. collect each vector individually - the performance advantage is smaller but still exists.

---

<div class="post-metadata">

**Author:** ![timueh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timueh/32/12379_2.png) [@timueh](https://discourse.julialang.org/u/timueh)\
**Post date:** [March 26, 2019, 10:45am UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341/3 "2019-03-26T10:45:53Z")

</div>

Thanks, this looks promising!

It’s not crucial to return a matrix type of integers, `SubArrays` are fine (as long as I adapt the functions that use `get_interactions` downstream).

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [March 26, 2019, 12:24pm UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341/4 "2019-03-26T12:24:13Z")

</div>

> [@timueh](#):
>
> This is _one_ way to implement this, but it feels too bulky. There’s probably a more clever way to exploit the CartesianIndices returned by `findall` .

If it’s only about bulkiness and not performance, I would do

```julia
get_interaction(inds, j) = inds[vec(sum(inds .!= 0, dims = 2)) .== j, :]

```

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [March 28, 2019, 1:48am UTC](https://discourse.julialang.org/t/help-needed-with-some-matrix-manipulation/22341/5 "2019-03-28T01:48:03Z")

</div>

This is quite fast and returns full array:

```julia
inds[[count(!iszero,r) == j for r in eachrow(inds)], : ]
6×4 Array{Int64,2}:
 1 1 0 0
 1 0 1 0
 1 0 0 1
 0 1 1 0
 0 1 0 1
 0 0 1 1

```
