2017-10-26 9 views
1

나는 julia를 처음 사용하며 Gadfly에서 정의한 값 범위를 넘어서 함수를 그려보기 위해 노력하고 있습니다. 함수 자체는 매우 간단합니다.값의 순서에 따라 Gadfly에 의해 유발 된 InexactError

function metropolis(dU, b) 
    if dU < 0 
     1 
    else 
     exp(-dU * b) 
    end 
end 

이 함수를 플롯하려고하면 julia에서 InexactError이 나옵니다.

using Gadfly 
x = linspace(-5, 5, 100) 
b = 1 
plot(x=x, y=metropolis.(x, b), Geom.line) 

정확한 오류가

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) 

작동합니다. 이 동작은 나에게 매우 이상합니다. 어떤 도움을 주셔서 감사합니다.

+0

주어진 답은 상황을 잘 설명합니다. 그러나 FYI, 함수를 작성하는 깔끔한 방법은 간단합니다 :'metropolis (dU, b) = dU <0? 1.0 : Float64 (exp (-dU * b))'. 가능하다면'exp' 호출의 반환 값은 항상'Float64'로 변환되기 때문에 이것은 타입 안정입니다. 'Complex'에서 당신의 입력 중 하나. 'Complex'와 같은 입력을 만날 수 있다면 가장 간단한 해결책은이 경우를 명시 적으로 다루는 두 번째 메소드를 추가하는 것입니다. –

답변

3

그 이유는 함수가 형식이 안정적이지 않기 때문입니다. 반환 값은 형식의 인수뿐만 아니라 인수 값에 따라 달라집니다. 는 여기에 간단한 (하지만 빠른) 기능을 코딩하는 당신에게 적절한 방법을 보여주는 수정 : 일반적으로

function metropolis(dU, b) 
    if dU < 0 
     zero(exp(-dU * b)) 
    else 
     exp(-dU * b) 
    end 
end 

- 보장하는 것과 같은 형식을 반환하는 경우 - 다른 두 가지. 귀찮 실패

이유는 코드의이 부분에 기인한다 : 실제로 Array{Real}에 대해 잘못된 결정이다 최초의 구체적인 유형에 break을 수행으로 https://github.com/GiovineItalia/Gadfly.jl/blob/master/src/scale.jl#L194

아마도 고정되어야한다.

+0

서명'metropolis {T <: Real} (dU :: T, b :: T)'를 사용할 때 함수 안에'T' 형의 변수를 만드는 방법이 있습니까? –

+0

현재 줄리아의 올바른 서명은'대도시 (dU :: T, b :: T)입니다. 여기서 T <: Real'입니다. 그러면'T ([some value])'를 써서 함수 안에서'T '로 변환 할 수 있습니다. 그러나 'dU'와 'b'가 모두 'T'유형 인 경우 'exp'는 'T'유형의 값을 반환 할 필요가 없습니다. 인수가'Int'이지만'exp (1)'은'Float64'입니다. –