gpt4 book ai didi

julia - 复数的通用最大/最小函数

转载 作者:行者123 更新时间:2023-12-04 04:24:42 24 4
gpt4 key购买 nike

在 julia 中,可以找到(据说)有效的 min 实现。/minimummax/maximum在实数的集合上。
由于这些概念不是为复数唯一定义的,我想知道是否已经在某处实现了这些函数的参数化版本。
我目前正在对感兴趣的数组的元素进行排序,然后取最后一个值,据我所知,这比找到具有最大绝对值(或其他值)的值要昂贵得多。
这主要是为了重现 max 的 Matlab 行为。复杂数组上的函数。
这是我当前的代码

a = rand(ComplexF64,4)
b = sort(a,by = (x) -> abs(x))
c = b[end]
可能的函数调用看起来像
c = maximum/minimum(a,by=real/imag/abs/phase)
编辑 使用提供的解决方案在 Julia 1.5.3 中进行一些性能测试
function maxby0(f,iter)
b = sort(iter,by = (x) -> f(x))
c = b[end]
end

function maxby1(f, iter)
reduce(iter) do x, y
f(x) > f(y) ? x : y
end
end

function maxby2(f, iter; default = zero(eltype(iter)))
isempty(iter) && return default
res, rest = Iterators.peel(iter)
fa = f(res)
for x in rest
fx = f(x)
if fx > fa
res = x
fa = fx
end
end

return res
end

compmax(CArray) = CArray[ (abs.(CArray) .== maximum(abs.(CArray))) .& (angle.(CArray) .== maximum( angle.(CArray))) ][1]


Main.isless(u1::ComplexF64, u2::ComplexF64) = abs2(u1) < abs2(u2)

function maxby5(arr)
arr_max = arr[argmax(map(abs, arr))]
end

a = rand(ComplexF64,10)

using BenchmarkTools
@btime maxby0(abs,$a)
@btime maxby1(abs,$a)
@btime maxby2(abs,$a)
@btime compmax($a)
@btime maximum($a)
@btime maxby5($a)
长度为 10 的向量的输出:
>841.653 ns (1 allocation: 240 bytes)
>214.797 ns (0 allocations: 0 bytes)
>118.961 ns (0 allocations: 0 bytes)
>Execution fails
>20.340 ns (0 allocations: 0 bytes)
>144.444 ns (1 allocation: 160 bytes)
长度为 1000 的向量的输出:
>315.100 μs (1 allocation: 15.75 KiB)
>25.299 μs (0 allocations: 0 bytes)
>12.899 μs (0 allocations: 0 bytes)
>Execution fails
>1.520 μs (0 allocations: 0 bytes)
>14.199 μs (1 allocation: 7.94 KiB)
长度为 1000 的向量的输出(使用 abs2 进行所有比较):
>35.399 μs (1 allocation: 15.75 KiB)
>3.075 μs (0 allocations: 0 bytes)
>1.460 μs (0 allocations: 0 bytes)
>Execution fails
>1.520 μs (0 allocations: 0 bytes)
>2.211 μs (1 allocation: 7.94 KiB)
一些评论:
  • 清晰地排序(和预期的一样)会减慢操作速度
  • 使用 abs2节省了很多性能(预期也是如此)

  • 总结:
  • 由于内置函数将在 1.7 中提供此功能,因此我将避免使用额外的 Main.isless方法,虽然它被认为是最有效的方法,但不修改我的 julia 的核心
  • maxby1maxby2什么都不分配
  • maxby1感觉更易读

  • 因此,获胜者是安德烈·奥斯金(Andrej Oskin)!
    编辑 n°2 使用更正后的新基准 compmax执行
    julia> @btime maxby0(abs2,$a)
    36.799 μs (1 allocation: 15.75 KiB)
    julia> @btime maxby1(abs2,$a)
    3.062 μs (0 allocations: 0 bytes)
    julia> @btime maxby2(abs2,$a)
    1.160 μs (0 allocations: 0 bytes)
    julia> @btime compmax($a)
    26.899 μs (9 allocations: 12.77 KiB)
    julia> @btime maximum($a)
    1.520 μs (0 allocations: 0 bytes)
    julia> @btime maxby5(abs2,$a)
    2.500 μs (4 allocations: 8.00 KiB)

    最佳答案

    在 Julia 1.7 中你可以使用 argmax

    julia> a = rand(ComplexF64,4)
    4-element Vector{ComplexF64}:
    0.3443509906876845 + 0.49984979589871426im
    0.1658370274750809 + 0.47815764287341156im
    0.4084798173736195 + 0.9688268736875587im
    0.47476987432458806 + 0.13651720575229853im

    julia> argmax(abs2, a)
    0.4084798173736195 + 0.9688268736875587im
    由于达到1.7需要一些时间,可以使用下面的模拟
    maxby(f, iter) = reduce(iter) do x, y
    f(x) > f(y) ? x : y
    end
    julia> maxby(abs2, a)
    0.4084798173736195 + 0.9688268736875587im
    UPD:找到这种最大值的更有效的方法是使用类似的东西
    function maxby(f, iter; default = zero(eltype(iter)))
    isempty(iter) && return default
    res, rest = Iterators.peel(iter)
    fa = f(res)
    for x in rest
    fx = f(x)
    if fx > fa
    res = x
    fa = fx
    end
    end

    return res
    end

    关于julia - 复数的通用最大/最小函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66260858/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com