Home > Software engineering >  Find index of maximum element satisfying condition (Julia)
Find index of maximum element satisfying condition (Julia)

Time:08-26

In Julia I can use argmax(X) to find max element. If I want to find all element satisfying condition C I can use findall(C,X). But how can I combine the two? What's the most efficient/idiomatic/concise way to find maximum index satisfying some condition in Julia?

CodePudding user response:

From what I understand from your question you can use findmax() (requires Julia >= v1.7) to find the maximum index on the result of findall():

julia> v = [10, 20, 30, 40, 50]
5-element Vector{Int64}:
 10
 20
 30
 40
 50

julia> findmax(findall(x -> x > 30, v))[1]
5

Performance of the above function:

julia> v = collect(10:1:10_000_000);

julia> @btime findmax(findall(x -> x > 30, v))[1]
  33.471 ms (10 allocations: 77.49 MiB)
9999991

Update: solution suggested by @dan-getz of using last() and findlast() perform better than findmax() but findlast() is the winner:

julia> @btime last(findall(x -> x > 30, v))
  19.961 ms (9 allocations: 77.49 MiB)
9999991

julia> @btime findlast(x -> x > 30, v)
  81.422 ns (2 allocations: 32 bytes)

CodePudding user response:

If you'd like to avoid allocations, filtering the array lazily would work:

idx_filtered = (i for (i, el) in pairs(X) if C(el))
argmin(i -> X[i], idx_filtered)

Unfortunately, this is about twice as slow as a hand-written version (in my testing):

function byhand(X, C)
    start = findfirst(C, X)
    (start == nothing) && return nothing
    imax, max = start, X[start]
    for i = start:lastindex(X)
        if C(X[i]) && X[i] > max
            imax, max = i, X[i]
        end
     end
     imax, max
end
  • Related