Search code examples
juliamaxargmax

Julia find the index of the maximum element in a list that satisfies another list condition


I want to find the index of the maximum element in a list that satisfy certain conditions.

I have two lists a = [13, 17, 11, 24, 30] and b = [10, 12, 13, 20, 28]. I want to find the index i of the maximum element in b such that a[i]-b[i]>0. The answer here is i=5. Mathematically, I am looking for argmax_{i in S} b where S = {i : a_i - b_i > 0}.

My solution sorts the list and filters it. Is there a better approach?

filter(in(findall(>(0), a .- b)), sortperm(b, rev=true))

Solution

  • The following shows a method without a loop. Using a loop should be the easiest go-to solution. Additionally, benchmarking is demonstrated. Also, the let block shows how to avoid allocations from capturing variables in a closure.

    julia> a = [13, 17, 11, 24, 30] ; b = [10, 12, 13, 20, 28];
    
    julia> @btime let a = $a, b = $b 
           findmax(i->a[i]>b[i] ? b[i] : typemin(Int), eachindex(a))
           end
      5.714 ns (0 allocations: 0 bytes)
    (28, 5)
    

    For completeness, a benchmark of a loop version:

    julia> @btime begin 
           mi = 0 ; m = typemin(Int); for i in eachindex($a)
           if $a[i] > $b[i] && $b[i] > m
               m = $b[i]
               mi = i
           end
           end; (m, mi)
           end
      5.495 ns (0 allocations: 0 bytes)
    (28, 5)