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")