Julia Gadfly根据值的顺序引发的不精确错误

Julia Gadfly根据值的顺序引发的不精确错误,julia,gadfly,Julia,Gadfly,我是julia的新手,我试图在我用Gadfly定义的一系列值上绘制一个函数。函数本身非常简单 function metropolis(dU, b) if dU < 0 1 else exp(-dU * b) end end 确切的错误是 Stacktrace: [1] apply_scale_typed!(::Array{Int64,1}, ::Array{Real,1}, ::Gadfly.Scale.ContinuousSca

我是julia的新手,我试图在我用Gadfly定义的一系列值上绘制一个函数。函数本身非常简单

function metropolis(dU, b)
    if dU < 0
        1
    else
        exp(-dU * b)
    end
end
确切的错误是

Stacktrace:
[1] apply_scale_typed!(::Array{Int64,1}, ::Array{Real,1},  ::Gadfly.Scale.ContinuousScale) at /home/max/.julia/v0.6/Gadfly/src/scale.jl:249
[2] apply_scale(::Gadfly.Scale.ContinuousScale, ::Array{Gadfly.Aesthetics,1}, ::Gadfly.Data, ::Vararg{Gadfly.Data,N} where N) at /home/max/.julia/v0.6/Gadfly/src/scale.jl:206
[3] apply_scales(::IterTools.Distinct{Base.ValueIterator{Dict{Symbol,Gadfly.ScaleElement}},Gadfly.ScaleElement}, ::Array{Gadfly.Aesthetics,1}, ::Gadfly.Data, ::Vararg{Gadfly.Data,N} where N) at /home/max/.julia/v0.6/Gadfly/src/scale.jl:33
[4] apply_scales(::IterTools.Distinct{Base.ValueIterator{Dict{Symbol,Gadfly.ScaleElement}},Gadfly.ScaleElement}, ::Gadfly.Data) at /home/max/.julia/v0.6/Gadfly/src/scale.jl:52
[5] render_prepare(::Gadfly.Plot) at /home/max/.julia/v0.6/Gadfly/src/Gadfly.jl:670
[6] render(::Gadfly.Plot) at /home/max/.julia/v0.6/Gadfly/src/Gadfly.jl:748
[7] show at /home/max/.julia/v0.6/Gadfly/src/Gadfly.jl:952 [inlined]
[8] limitstringmime(::MIME{Symbol("image/svg+xml")}, ::Gadfly.Plot) at /home/max/.julia/v0.6/IJulia/src/inline.jl:24
[9] display_dict(::Gadfly.Plot) at /home/max/.julia/v0.6/IJulia/src/execute_request.jl:29
[10] execute_request(::ZMQ.Socket, ::IJulia.Msg) at /home/max/.julia/v0.6/IJulia/src/execute_request.jl:182
[11] eventloop(::ZMQ.Socket) at /home/max/.julia/v0.6/IJulia/src/eventloop.jl:8
[12] (::IJulia.##14#17)() at ./task.jl:335
但奇怪的是,当我使用
-x
时,它就工作了

plot(x=x, metropolis.(-x, b), Geom.line)

这只是颠倒了值的顺序。这种行为对我来说很奇怪。非常感谢您的帮助。

原因是您的函数的类型不稳定-它的返回值取决于参数的值,而不仅仅取决于它们的类型。 下面是最简单(但不是最快)的修复程序,它向您展示了编写函数的正确方法:

function metropolis(dU, b)
    if dU < 0
        zero(exp(-dU * b))
    else
        exp(-dU * b)
    end
end
功能都市(dU,b)
如果dU<0
零(exp(-dU*b))
其他的
exp(-dU*b)
结束
结束
通常-确保if-else的两个分支返回相同的类型

Gadfly失败的原因在于这部分代码:


当它在第一个具体类型上执行
break
时,它可能应该被修复,这对于
Array{Real}

实际上是一个错误的决定。当我使用签名
metropolis时,有没有办法在函数内部构造
T
类型的变量{T当前Julia中正确的签名是
metropolis(dU::T,b::T),其中给出的答案很好地解释了这种情况。但仅供参考,编写函数的简洁方法是:
metropolis(dU,b)=dU<0?1.0:Float64(exp(-dU*b))
。这现在是类型稳定的,因为
exp
调用的返回总是转换为
Float64
,如果可能的话,或者如果出现错误,例如
Complex
中的一个输入。如果您可能遇到类似
Complex
的输入,那么最简单的解决方案就是添加第二个方法来显式处理那个案子。
function metropolis(dU, b)
    if dU < 0
        zero(exp(-dU * b))
    else
        exp(-dU * b)
    end
end