在Julia中使用Lsq拟合
我尝试在Julia中使用Lsq拟合函数进行拟合。 参数为\gamma和x_0的柯西分布的导数。 按照手册我试过了在Julia中使用Lsq拟合,julia,curve-fitting,Julia,Curve Fitting,我尝试在Julia中使用Lsq拟合函数进行拟合。 参数为\gamma和x_0的柯西分布的导数。 按照手册我试过了 f(x, x_0, γ) = -2*(x - x_0)*(π * γ^3 * (1 + ((x - x_0)/γ)^2)^2)^(-1) x_0 = 3350 γ = 50 xarr = range(3000, length = 5000, stop = 4000) yarr = [f(x, x_0, γ) for x in xarr] using LsqFit # p ≡ [x_
f(x, x_0, γ) = -2*(x - x_0)*(π * γ^3 * (1 + ((x - x_0)/γ)^2)^2)^(-1)
x_0 = 3350
γ = 50
xarr = range(3000, length = 5000, stop = 4000)
yarr = [f(x, x_0, γ) for x in xarr]
using LsqFit
# p ≡ [x_0, γ]
model(x, p) = -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1)
p0 = [3349, 49]
curve_fit(model, xarr, yarr, p0)
param = fit.param
。。。它不起作用,给出了一个方法错误:没有方法匹配-(::StepRangeLen[…]
,让我感到困惑。
谁能告诉我我做错了什么吗?你写的东西有几个问题:
model
函数时,其第一个参数(x
)是自变量的完整向量,而不仅仅是一个值。这就是您提到的错误的来源:
julia> model(x, p) = -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1);
julia> p0 = [3349, 49];
julia> model(xarr, p0);
ERROR: MethodError: no method matching -(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Float64)
解决此问题的一种方法是对所有运算符使用点表示法,以便它们在元素方面工作:
julia> model(x, p) = -2*(x .- p[1]) ./ (π * (p[2])^3 * (1 .+ ((x .- p[1])/p[2]).^2).^2);
julia> model(xarr, p0); # => No error
但如果这太单调,您可以让宏为您完成工作:
# just put @. in front of the expression to transform every
# occurrence of a-b into a.-b (and likewise for all operators)
# which means to compute the operation elementwise
julia> model(x, p) = @. -2*(x - p[1])*(π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)^(-1);
julia> model(xarr, p0); # => No error
p0
是用整数初始化的,这会混淆曲线拟合
。有两种方法可以解决此问题。将浮点值放入p0
:
julia> p0 = [3349.0, 49.0]
2-element Array{Float64,1}:
3349.0
49.0
或使用显式指定元素类型:
julia> p0 = Float64[3349, 49]
2-element Array{Float64,1}:
3349.0
49.0
a/b
比计算a*b^(-1)
更直观。此外,yarr
可以通过简单的广播而不是理解来计算f(x, x_0, γ) = -2*(x - x_0)*(π * γ^3 * (1 + ((x - x_0)/γ)^2)^2)^(-1)
(x_0, γ) = (3350, 50)
xarr = range(3000, length = 5000, stop = 4000);
# use dot-notation to "broadcast" f and map it
# elementwise to elements of xarr
yarr = f.(xarr, x_0, γ);
using LsqFit
model(x, p) = @. -2*(x - p[1]) / (π * (p[2])^3 * (1 + ((x - p[1])/p[2])^2)^2)
p0 = Float64[3300, 10]
fit = curve_fit(model, xarr, yarr, p0)
收益率:
julia> fit.param
2-element Array{Float64,1}:
3349.999986535933
49.99999203625603
你太棒了!非常感谢!:D在完成你的回答时,我还注意到我在第一次尝试中忘记初始化“fit”,我们称之为“code”-尝试。它现在工作正常。:-)我遇到的另一个问题是:如果方程式符号旁边没有“@”,我如何编写模型函数?我试着用它的点模拟来替换每个操作(+、-、/、*、^),但似乎没有成功?你尝试的应该成功。它编辑了我的答案,为所有必要的运算符显示了一个手动点表示法的示例。还请注意,您可以始终使用
@macroexpand@。a+b
以准确了解@
执行的转换类型(这当然适用于任何宏)