如何在 Julia 中指定函数的类型/签名?

Sea*_*ake 4 methods types signature julia

我正在实施牛顿在预编译库中查找根的方法。常见的情况是使用从Float64to 的函数Float64,我希望库中存在它的优化编译版本。当然,我也会实现一个类型泛型版本,但 Julia 需要某种方式通过签名区分方法,以便它知道在运行时调用哪个。目前,实现是:

#Float64 optimized version
function findrootNewton( func, funcder, guess::Float64,
                        rtol::Float64=1e-12, abstol::Float64=1e-12, maxiter::Int=100 )
    #make sure tolerances are positive
    if rtol <= 0.0
        error("findrootNewton: rtol must be a positive number")
    end

    if abstol <= 0.0
        error("findrootNewton: abstol must be a positive number")
    end

    if maxiter <= 0.0
        error("findrootNewton: maxiter must be a positive integer")
    end

    converged::Bool = false

    oldx::Float64 = guess
    newx::Float64 = oldx - ((func(oldx) / funcder(oldx))::Float64)
    absdiff = abs(oldx - newx)

    iter = 2
    while (absdiff < abstol || absdiff < rtol * abs(newx)) && iter <= maxiter
        oldx = newx
        newx = oldx - func(oldx) / funcder(oldx)
        absdiff = abs(oldx - newx)

        iter += 1
    end #while (absdiff < abstol || absdiff < rtol * abs(newx)) && newxiter <= maxiter

    if iter <= maxiter
        converged = true
    end

    return (newx, converged)
end #findzeroNewton

#Generic version
function findrootNewton( func, funcder, guess::Number,
                        rtol::Real=1e-12, abstol::Real=1e-12, maxiter::Int=100 )
    #make sure tolerances are positive
    if rtol <= 0
        error("findrootNewton: rtol must be a positive number")
    end

    if abstol <= 0
        error("findrootNewton: abstol must be a positive number")
    end

    if maxiter <= 0
        error("findrootNewton: maxiter must be a positive integer")
    end

    converged::Bool = false

    newx = oldx - func(oldx) / funcder(oldx)
    oldx = convert(typeof(newx), guess)
    absdiff = abs(oldx - newx)

    iter = 2
    while (absdiff < abstol || absdiff < rtol * abs(newx)) && iter <= maxiter
        oldx = newx
        newx = oldx - func(oldx) / funcder(oldx)
        absdiff = abs(oldx - newx)

        iter += 1
    end #while (absdiff < abstol || absdiff < rtol * abs(newx)) && newxiter <= maxiter

    if iter <= maxiter
        converged = true
    end

    return (newx, converged)
end #findzeroNewton
Run Code Online (Sandbox Code Playgroud)

这还没有被使用/调试过。例如,我不会检查导数是否为零,因为我正在为其编码的特定情况不需要它。

请注意,如果guessrtolabstol参数作为 给出Float64,但函数不返回Float64但是BigFloat,则代码将在 的定义中的类型断言点失败newx,即使有适用于泛型函数的方法可用。有没有办法避免这个问题?

编辑:我可以指定变量在 Julia 中存储的数据类型,例如:

x::Float64 = 2.5
Run Code Online (Sandbox Code Playgroud)

是否可以类似地指定可以存储(指向)函数的变量的签名?

Mic*_*ard 7

为清楚起见,我将我的评论写为答案:您不需要专门针对 Julia 中的类型进行函数签名,除非要在函数体中实现专门的处理。参数类型断言对代码速度或可编译性没有影响。请参阅http://docs.julialang.org/en/latest/manual/performance-tips/

julia 中函数参数中的类型断言主要用于控制多分派,即不同类型的输入参数的不同函数行为。当不声明类型时,编译器将自动为输入参数的每个组合编译一个类型专用版本。

如果出于其他原因,例如为了确保类型稳定性,您需要断言函数的返回类型与输入相同,则可以执行

function foo(x::T)::T where T
...
end
Run Code Online (Sandbox Code Playgroud)