Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find the extrema on a more general range of parameters

Tags:

julia

Suppose I have the following v and w as follows:

julia> v = [1:3, 4:6, 1:2, 3:6, 1:6, 1:6];

julia> w = [1:3, 4:6, 1:6, 1:6, 1:6, 1:4, 5:6, 1:6];

and I want a function to return the minimum and the maximum which would cover all the values in the ranges, i.e. (1,6) in this case.

Currently, I've tried:

flatextrema(q) = 
  foldl((r,b)->
    (min(first(r),first(b)),max(last(r),last(b))), q; 
    init=(first(first(q)),last(first(q))))

flatextrema(q,r...) = 
  flatextrema((flatextrema(q),flatextrema.(r)...))

which gives me:

julia> flatextrema(v,w)
(1, 6)

Is there some nicer/shorter/faster way?

This version of flatextrema takes quite a wide range of possible parameters and returns a tuple.

Another example would be:

julia> flatextrema([1:3,2:4,3:5],[-3:3,1:4],10)
(-3, 10)

The idea is to get a minimum and a maximum which would include all scalars in the parameters.

like image 425
Dan Getz Avatar asked Dec 05 '25 13:12

Dan Getz


1 Answers

You like any of these?

v = [1:3, 4:6, 1:2, 3:6, 1:6, 1:6]
w = [1:3, 4:6, 1:6, 1:6, 1:6, 1:4, 5:6, 1:6]

function flatextrema1(vs...)
   all_ranges = Iterators.flatten(vs)
   minimum(minimum.(all_ranges)), maximum(maximum.(all_ranges))
end

function flatextrema2(vs...)
   all_extrema = extrema.(Iterators.flatten(vs))
   minimum(first.(all_extrema)), maximum(last.(all_extrema))
end

function flatextrema3(vs...)
   all_extrema = extrema.(Iterators.flatten(vs))
   extrema(Iterators.flatten(all_extrema))
end

# flatextrema = flatextrema1
# flatextrema = flatextrema2
flatextrema = flatextrema3

flatextrema(v, w) # (1, 6)
flatextrema(v, w, 10) # (1, 10)

May be some cool way to do this with JuliaFolds/Transducers.jl - I need to check that package out properly.


Edit (after benchmark comment):

Ok here's a faster version

function flatextrema4(vs...)
   mn,mx = typemax(Int), typemin(Int)
   for cc in vs, c in cc
      cmn, cmx = extrema(c)
      mn, mx = min(mn, cmn), max(mx, cmx)
   end
   return mn, mx
end

Edit 2 (post accept): Bonus Transducer version (pretty fast and concise)

using Transducers
function flatextrema5(vs...)
   foldxl(ProductRF(min, max), vs |> Cat() |> Map(extrema))
end

I will note that while these solutions handle the amount of nesting in your examples, none of them are generic enough to handle arbitrary nesting. To do that you'd need a more generic, and likely slower, flattening step.

like image 81
JobJob Avatar answered Dec 09 '25 18:12

JobJob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!