Julia 朱莉娅:使用CurveFit包非线性
为什么下面的代码不起作用Julia 朱莉娅:使用CurveFit包非线性,julia,curve-fitting,non-linear-regression,Julia,Curve Fitting,Non Linear Regression,为什么下面的代码不起作用 xa = [0 0.200000000000000 0.400000000000000 1.00000000000000 1.60000000000000 1.80000000000000 2.00000000000000 2.60000000000000 2.80000000000000 3.00000000000000 3.80000000000000 4.80000000000000 5.00000000000000 5.200000000
xa = [0 0.200000000000000 0.400000000000000 1.00000000000000 1.60000000000000 1.80000000000000 2.00000000000000 2.60000000000000 2.80000000000000 3.00000000000000 3.80000000000000 4.80000000000000 5.00000000000000 5.20000000000000 6.00000000000000 6.20000000000000 7.40000000000000 7.60000000000000 7.80000000000000 8.60000000000000 8.80000000000000 9.00000000000000 9.20000000000000 9.40000000000000 10.0000000000000 10.6000000000000 10.8000000000000 11.2000000000000 11.6000000000000 11.8000000000000 12.2000000000000 12.4000000000000];
ya = [-0.183440428023042 -0.131101157495126 0.0268875670852843 0.300000000120000 0.579048247883555 0.852605831272159 0.935180993484717 1.13328608090532 1.26893326843583 1.10202945535186 1.09201137189664 1.14279083803453 0.811302535321072 0.909735376251797 0.417067545528244 0.460107770989798 -0.516307074859654 -0.333994077331822 -0.504124744955962 -0.945794320817293 -0.915934553082780 -0.975458595671737 -1.09943707404275 -1.11254211607374 -1.29739980589100 -1.23440439602665 -0.953807504156356 -1.12240274852172 -0.609284630192522 -0.592560286759450 -0.402521296049042 -0.510090363150962];
x0 = vec(xa)
y0 = vec(ya)
fun(x,a) = a[1].*sin(a[2].*x - a[3])
a0 = [1,2,3]
eps = 0.000001
maxiter=200
coefs, converged, iter = CurveFit.nonlinear_fit(x0 , fun , a0 , eps, maxiter )
y0b = fit(x0)
Winston.plot(x0, y0, "ob", x0, y0b, "r-", linewidth=3)
错误:LoadError:MethodError:convert
没有与convert匹配的方法(::Type{Float64},::Array{Float64,1})这可能是由于
调用构造函数Float64(…),因为类型构造函数
返回以转换方法。最接近的候选者是:call{T}(::Type{T},
::任意)转换(::类型{Float64},!Matched::Int8)
转换(::类型{Float64},!Matched::Int16)
在[269]中加载时,在从第8行开始的表达式中
非线性拟合在/home/jmarcellopereira/.julia/v0.4/CurveFit/src/nonlinfit.jl:75
从文件:
我们正在尝试调整关系fun(x,a)=0
因此,如果您希望以如下方式查找a
的元素:对于[x0 y0]
=>a[1].*sin(a[2].*xi-a[3])==yi中的每个xi,则正确的方法是:
fun(xy,a) = a[1].*sin(a[2].*xy[1] - a[3])-xy[2];
xy=hcat(x0,y0);
coefs,converged,iter = CurveFit.nonlinear_fit(xy,fun,a0,eps,maxiter);
fun
函数必须返回r
类型的Float64
残值,在每次数据迭代时计算,如下所示:
r = y - fun(x, coefs)
因此,您的函数y=a1*sin(x*a2-a3)
将被定义为:
fun(x,a) = x[2]-a[1]*sin(a[2]*x[1] - a[3])
其中:
x[2] is a value of 'y' vector
x[1] is a value of 'x' vector
a[...] is the set of parameters
fun
函数必须返回单个Float64
,因此运算符不能是“点版本”(*
)
通过调用非线性拟合函数,第一个参数必须是数组Nx2,第一列包含N个值x
,第二列包含N个值y
,因此必须在两列数组中串联两个向量x
和y
:
xy = [x y]
最后,调用函数:
coefs, converged, iter = CurveFit.nonlinear_fit(xy , fun , a0 , eps, maxiter )
对您关于返回系数的评论的回答不正确:
y=1*sin(x*a2-a3)
是一个谐波函数,因此从函数调用返回的系数在很大程度上取决于将作为第三个参数发送的参数a0
(“每个拟合参数的初始猜测”):
我认为你得到的结果是谐波,如图所示:
其中:
blue line:
f1(xx)=0.2616335317043578*sin(xx*1.1471991302529982-0.7048665905560775)
yellow line:
f2(xx)=1.192007321713507*sin(xx*0.49426296880933257-0.19863645732313934)
pink line:
f3(xx)=-0.4077952060368059*sin(xx*90.52328921205392-96.75331155303707)
blue dots are your initial data.
该图由以下内容生成:
使用Julia版本0.4.3进行测试后,我发现使用更简单,只需首先定义模型并用数据“拟合”即可:
using DataFrames, Plots, LsqFit
xa = [0 0.200000000000000 0.400000000000000 1.00000000000000 1.60000000000000 1.80000000000000 2.00000000000000 2.60000000000000 2.80000000000000 3.00000000000000 3.80000000000000 4.80000000000000 5.00000000000000 5.20000000000000 6.00000000000000 6.20000000000000 7.40000000000000 7.60000000000000 7.80000000000000 8.60000000000000 8.80000000000000 9.00000000000000 9.20000000000000 9.40000000000000 10.0000000000000 10.6000000000000 10.8000000000000 11.2000000000000 11.6000000000000 11.8000000000000 12.2000000000000 12.4000000000000];
ya = [-0.183440428023042 -0.131101157495126 0.0268875670852843 0.300000000120000 0.579048247883555 0.852605831272159 0.935180993484717 1.13328608090532 1.26893326843583 1.10202945535186 1.09201137189664 1.14279083803453 0.811302535321072 0.909735376251797 0.417067545528244 0.460107770989798 -0.516307074859654 -0.333994077331822 -0.504124744955962 -0.945794320817293 -0.915934553082780 -0.975458595671737 -1.09943707404275 -1.11254211607374 -1.29739980589100 -1.23440439602665 -0.953807504156356 -1.12240274852172 -0.609284630192522 -0.592560286759450 -0.402521296049042 -0.510090363150962];
x0 = vec(xa)
y0 = vec(ya)
xbase = collect(linspace(minimum(x0),maximum(x0),100))
p0 = [1.2, 0.5, 0.5] # initial value of parameters
fun(x0, p) = p[1] .* sin.(p[2] .* x0 .- p[3]) # definition of the model
fit = curve_fit(fun,x0,y0,p0) # actual fitting job
yFit = [fit.param[1] * sin(fit.param[2] * x - fit.param[3]) for x in xbase] # building the fitted values
# Plotting..
scatter(x0, y0, label="obs")
plot!(xbase, yFit, label="fitted")
请注意,使用LsqFit并不能解决Gomiero强调的初始条件的依赖性问题 你好,Reza Afzalan,谢谢你的帮助;)。我调整了代码:x0=vec(x)y0=vec(y)a=[1.51.51.0]eps=0.000000000001 maxiter=200.0 fun(xy,a)=a[1].*sin(a[2].-xy[1]-a[3])-xy[2];xy=hcat(x0,y0);coefs,收敛,iter=CurveFit.非线性拟合(xy,fun,a,eps,maxiter);但系数(0.2617123978289815,1.1472347006194563,0.7051280422828665)不正确(1.19211,0.494285,0.198769)。这是一个很好的例子。口琴是一种非常重要的国际性基本乐器。一个优秀的解释,推荐的科莫邮政指南,没有github的曲线,一个关于科莫的“juleiros”的指南,一个关于大规模语言的指南,一个关于科尔加斯的指南,一个关于语言的指南。作为观察者,我的生活是一场灾难。你是朱丽亚吗。
plot(layer(x=x,y=y,Geom.point),layer([f1,f2,f3],0.0, 15.0,Geom.line))
using DataFrames, Plots, LsqFit
xa = [0 0.200000000000000 0.400000000000000 1.00000000000000 1.60000000000000 1.80000000000000 2.00000000000000 2.60000000000000 2.80000000000000 3.00000000000000 3.80000000000000 4.80000000000000 5.00000000000000 5.20000000000000 6.00000000000000 6.20000000000000 7.40000000000000 7.60000000000000 7.80000000000000 8.60000000000000 8.80000000000000 9.00000000000000 9.20000000000000 9.40000000000000 10.0000000000000 10.6000000000000 10.8000000000000 11.2000000000000 11.6000000000000 11.8000000000000 12.2000000000000 12.4000000000000];
ya = [-0.183440428023042 -0.131101157495126 0.0268875670852843 0.300000000120000 0.579048247883555 0.852605831272159 0.935180993484717 1.13328608090532 1.26893326843583 1.10202945535186 1.09201137189664 1.14279083803453 0.811302535321072 0.909735376251797 0.417067545528244 0.460107770989798 -0.516307074859654 -0.333994077331822 -0.504124744955962 -0.945794320817293 -0.915934553082780 -0.975458595671737 -1.09943707404275 -1.11254211607374 -1.29739980589100 -1.23440439602665 -0.953807504156356 -1.12240274852172 -0.609284630192522 -0.592560286759450 -0.402521296049042 -0.510090363150962];
x0 = vec(xa)
y0 = vec(ya)
xbase = collect(linspace(minimum(x0),maximum(x0),100))
p0 = [1.2, 0.5, 0.5] # initial value of parameters
fun(x0, p) = p[1] .* sin.(p[2] .* x0 .- p[3]) # definition of the model
fit = curve_fit(fun,x0,y0,p0) # actual fitting job
yFit = [fit.param[1] * sin(fit.param[2] * x - fit.param[3]) for x in xbase] # building the fitted values
# Plotting..
scatter(x0, y0, label="obs")
plot!(xbase, yFit, label="fitted")