# Generic code for elementwise minimum

**URL:** <https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 8, 2019, 1:46pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921 "2019-04-08T13:46:56Z")\
**Posts on this page:** 9\
**Page:** 1

<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 8, 2019, 1:46pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/1 "2019-04-08T13:46:57Z")

</div>

I am wondering how to program a generic elementwise minimum of, say, vectors, with the following in mind: the result from an `AbstractVector{T}` is a `T`, eg `SVector` and `Vector` would be preserved.

Data-generating MWE:

```julia
using StaticArrays
v = [randn(3) for _ in 1:10] # Vector
s = [SVector(v...) for v in v] # SVector
m = minimum(reduce(hcat, v); dims = 2) # for testing

```

Eg for `elementwise_min(v)` I want a `Vector{Float64}`, and for `elementwise_min(s)` an `SArray{Tuple{3},Float64,1,3}`.

---

<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 8, 2019, 2:10pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/2 "2019-04-08T14:10:25Z")

</div>

`min.(v...)` works but is probably a bad idea when `v` is large.

---

<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:** [April 8, 2019, 2:27pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/3 "2019-04-08T14:27:31Z")

</div>

> [@Tamas\_Papp](#):
>
> Eg for `elementwise_min(v)` I want a `Vector{Float64}` , and for `elementwise_min(s)` an `SArray{Tuple{3},Float64,1,3}` .

Don’t you want an `SArray{Tuple{10},Float64,1,10}`?  
Anyway that would involve getting the `eltype` of your input and, depending on your type, calculating the type parameters (e.g. for the vector of `StaticArrays` the length is not known at compile time and thus the parameter of the resulting static vector is not known).

I don’t think it gets much better than applying a function elementwise and converting the resulting array explicitly with a helper-function, i.e.

```julia
julia> foo(f,xs) = myconv(eltype(xs),map(f,xs))
       myconv(::Type{<:SArray}, xs) = SVector(xs...)
       myconv(::Type{<:Array}, xs) = xs

```

but would be happy to learn otherwise.

---

<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 8, 2019, 2:35pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/4 "2019-04-08T14:35:03Z")

</div>

This gave me an idea:

```julia
julia> elementwise_f(f, v) = reduce((x, y) -> f.(x, y), v)
elementwise_f (generic function with 1 method)

julia> elementwise_f(min, v) == m
true

julia> elementwise_f(min, s) == m
true

```

Thanks!

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [September 30, 2020, 11:18pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/5 "2020-09-30T23:18:21Z")

</div>

> [@mohamed82008](#):
>
> `min.(v...)` works but is probably a bad idea when `v` is large.

Why is this a bad idea when `v` is large?

---

<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:** [September 30, 2020, 11:26pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/6 "2020-09-30T23:26:58Z")

</div>

splatting is inefficient for large sizes.

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [October 8, 2020, 1:08am UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/7 "2020-10-08T01:08:57Z")

</div>

I thought `min.(...)` was broadcasting?

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 8, 2020, 2:41am UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/8 "2020-10-08T02:41:34Z")

</div>

`min.(x, y)` will broadcast `min` over `x` and `y`. `min.(v...)` will first splat `v` into the arguments to `min` and then broadcast over those splatted arguments. It’s the splatting that is extremely inefficient for large sizes.

```julia
julia> let v = [randn(3) for _ in 1:100]
           @btime min.($v...)
           @btime reduce((x, y) -> min.(x, y), $v)
       end
  1.674 ms (33681 allocations: 1.44 MiB)
  5.292 μs (99 allocations: 10.83 KiB)

```

---

<div class="post-metadata">

**Author:** ![Samuel\_Ainsworth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuel_ainsworth/32/15644_2.png) [@Samuel\_Ainsworth](https://discourse.julialang.org/u/Samuel_Ainsworth)\
**Post date:** [October 8, 2020, 10:14pm UTC](https://discourse.julialang.org/t/generic-code-for-elementwise-minimum/22921/9 "2020-10-08T22:14:31Z")

</div>

Ah, gotcha. Thanks for the explanation!
