# Subtracting row minima

**URL:** <https://discourse.julialang.org/t/subtracting-row-minima/22508>\
**Category:** Performance\
**Created:** [March 29, 2019, 4:05pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508 "2019-03-29T16:05:33Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 29, 2019, 4:05pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/1 "2019-03-29T16:05:33Z")

</div>

I know that arrays are column based in julia but maybe I’m missing something.  
Want to subtract the column minimum from each column in a matrix and then the same with rows.

Currently doing this:

```julia
# subtract col minimum
for c=1:ncols
    @views mat[:,c] .-= minimum(mat[:,c])
end
    
# subtract row minimum
row_minima = findmin(mat, dims=2)[1]
for r=1:nrows
    @views mat[r,:] .-= row_minima[r]
 end

```

which takes about 6s for a 16000\*16000 UInt16 matrix.  
The first part (col minimum) takes about 0.3s so is way faster than the second one.

First I used:

```julia
for r=1:nrows
       @views mat[r,:] .-= minimum(mat[r,:])
 end

```

which takes 10s so mine is at least faster but maybe there is something I’m missing out. Thanks in advance.

---

<div class="post-metadata">

**Author:** ![improbable22](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/improbable22/32/5464_2.png) [@improbable22](https://discourse.julialang.org/u/improbable22)\
**Post date:** [March 29, 2019, 4:23pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/2 "2019-03-29T16:23:46Z")

</div>

You can also just write ` mat .-= minimum(mat, dims=1)` etc. I haven’t timed it but this should be pretty efficient.

---

<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 29, 2019, 4:34pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/3 "2019-03-29T16:34:40Z")

</div>

How about:

```julia
julia> function foocol!(mat)
           for col in eachcol(mat)
               col .-= minimum(col)
           end
           return mat
       end;
       foocol(mat) = foocol!(copy(mat));

julia> function foorow!(mat)
           rmins = vec(minimum(mat, dims=2))
           for col in eachcol(mat)
               col .-= rmins
           end
           return mat
       end;
       foorow(mat) = foorow!(copy(mat));

julia> mat = rand(UInt16, 16000, 16000);
julia> @time foocol(mat);
       @time foorow(mat);
  0.477268 seconds (16.01 k allocations: 489.014 MiB, 1.75% gc time)
  0.395470 seconds (16.03 k allocations: 489.045 MiB, 10.38% gc time)

```

Not 100% sure it does what you want but might be close enough. Basically you just want to traverse the array along the columns in both functions.

Edit:  
Didn’t see/parse the answer before mine but it’s superior. Fraction of memory and time required (probably due to allocating views).  
Hope that learning about `eachcol` is still useful but don’t use it for your problem.

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 29, 2019, 4:34pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/4 "2019-03-29T16:34:42Z")

</div>

> [@improbable22](#):
>
> minimum(mat, dims=1)

You mean `dims=2`, right? For the row minimum

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 29, 2019, 4:39pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/5 "2019-03-29T16:39:02Z")

</div>

> [@under-Peter](#):
>
> rmins = vec(minimum(mat, dims=2)) for col in eachcol(mat) col .-= rmins end

Oh loving it. Thank you very much! Didn’t know about `eachcol`. Pretty neat. Maybe I can use it somewhere else in the code base.

---

<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:** [March 29, 2019, 4:47pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/6 "2019-03-29T16:47:45Z")

</div>

> [@Wikunia](#):
>
> You mean `dims=2` , right? For the row minimum

`A .-= minimum(A, dims=1)` subtracts the minimum from each column, and `A .-= minimum(A, dims=2)` subtracts the minimum from each row.

I’m guessing that using broadcasting like this will be faster than using `eachrow` and `eachcol` iterators. It’s certainly easier and more compact.

---

<div class="post-metadata">

**Author:** ![Wikunia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wikunia/32/2180_2.png) [@Wikunia](https://discourse.julialang.org/u/Wikunia)\
**Post date:** [March 29, 2019, 4:56pm UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/7 "2019-03-29T16:56:41Z")

</div>

Ah yeah it seems to be neither faster nor slower but yes easier to read. Thx!

---

<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 30, 2019, 1:13am UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/8 "2019-03-30T01:13:37Z")

</div>

If you want it be super fast, write a single nested-loop for both operations like this:

```julia
function subMins!(mat)
    mcols = minimum(mat, dims=1)
    mrows = minimum(mat, dims=2)
    for j = 1:size(mat,2), i = 1:size(mat,1)
        mat[i,j] -= mrows[i] + mcols[j] 
    end  
end 

using BenchmarkTools
mat = rand(UInt16, 16000, 16000)
@btime subMins!($mat)
  290.291 ms (32 allocations: 63.41 KiB)

```

---

<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:** [March 30, 2019, 2:06am UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/9 "2019-03-30T02:06:59Z")

</div>

> [@Seif\_Shebl](#):
>
> If you want it be super fast, write a single nested-loop for both operations like this:

You can also do that with broadcasting. However, it is not equivalent to the original code, which computed the row minimums _after_ subtracting the column minimums.

---

<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 30, 2019, 2:22am UTC](https://discourse.julialang.org/t/subtracting-row-minima/22508/10 "2019-03-30T02:22:59Z")

</div>

Yes, the above is not equivalent to the original code, the following should. But broadcasting is still not as fast though!

```julia
function subMins!(mat)
    mcols = minimum(mat, dims=1)
    for j = 1:size(mat,2), i = 1:size(mat,1)
        mat[i,j] -= mcols[j] 
    end  
    mrows = minimum(mat, dims=2)
    for j = 1:size(mat,2), i = 1:size(mat,1)
        mat[i,j] -= mrows[i]
    end 
end 

using BenchmarkTools
mat = rand(UInt16, 16000, 16000)
@btime subMins!($mat)

@btime begin 
    $mat .-= minimum($mat, dims=1)
    $mat .-= minimum($mat, dims=2)
end

  343.362 ms (32 allocations: 63.41 KiB) # loops
  474.813 ms (32 allocations: 63.41 KiB) # broadcasting

```
