2017-10-26 11 views
1

私はjuliaを使い慣れていません.Gadflyで自分自身を定義した値の範囲に関数をプロットしようとしています。関数自体はかなりシンプルです。値の順序によってGadflyによってスローされるInexactError

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

私がこの機能をプロットしようとすると、私はジュリアから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'のような入力に遭遇する可能性がある場合、最も単純な解決策は、そのケースを明示的に扱う第2のメソッドを追加することです。 –

答えて

3

あなたの関数は型が安定していないからです。その戻り値は型の値だけでなく引数の値によって異なります。 - のif-elseの両方のブランチが同じ型を返すことを確認してください一般的に

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

:ここ はあなたの関数をコードする適切な方法を示す修正(最速ではない)のが最も簡単です。

あぶは、コードのこの部分に起因して失敗した理由:それは実際にに対して誤った決定である第1の具体タイプに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'型の値を返す必要はないことに注意してください。 'exp(1)'は引数が 'Int'でも' Float64'です。 –

関連する問題