Generic code for elementwise minimum

question
#1

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:

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}.

#2

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

#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> 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.

#4

This gave me an idea:

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!

5 Likes