julia - Julia 使用 LsqFit 进行洛伦兹曲线拟合
问题描述
Julia 中的以下代码绘制洛伦兹曲线,然后使用 curve_fit 函数确定参数。
using LsqFit
model(x,p)=p[1] ./(p[1]^2 .+(x .-p[2]).^2)
#Test values
p0=[10,50]
tdata=range(-150,stop=150,length=300)
ydata = model(tdata, p0)
fit=curve_fit(model,tdata,ydata,p0)
在这种情况下,结果应该是准确的,因为我使用模型计算 y 值,然后将这些准确的 y 值传递给 curve_fit 函数。但是,Julia 返回错误:
InexactError: Int64(NaN)
Int64(::Float64) at float.jl:710
x_of_nans(::Array{Int64,1}, ::Type{T} where T) at NLSolversBase.jl:60
x_of_nans(::Array{Int64,1}) at NLSolversBase.jl:60
NLSolversBase.OnceDifferentiable(::Function, ::Function, ::Function, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}; inplace::Bool) at oncedifferentiable.jl:229
NLSolversBase.OnceDifferentiable(::Function, ::Function, ::Function, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}) at oncedifferentiable.jl:225
NLSolversBase.OnceDifferentiable(::NLSolversBase.var"#ff!#1"{LsqFit.var"#18#20"{typeof(model),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}}, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}, ::Symbol, ::ForwardDiff.Chunk{2}) at oncedifferentiable.jl:147
NLSolversBase.OnceDifferentiable(::Function, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}, ::Symbol) at oncedifferentiable.jl:96
NLSolversBase.OnceDifferentiable(::Function, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}; inplace::Bool, autodiff::Symbol) at oncedifferentiable.jl:28
(::Core.var"#Type##kw")(::NamedTuple{(:inplace, :autodiff),Tuple{Bool,Symbol}}, ::Type{NLSolversBase.OnceDifferentiable}, ::Function, ::Array{Int64,1}, ::Array{Float64,1}, ::Array{Float64,2}) at oncedifferentiable.jl:26
(::Core.var"#Type##kw")(::NamedTuple{(:inplace, :autodiff),Tuple{Bool,Symbol}}, ::Type{NLSolversBase.OnceDifferentiable}, ::Function, ::Array{Int64,1}, ::Array{Float64,1}) at oncedifferentiable.jl:26
lmfit(::LsqFit.var"#18#20"{typeof(model),StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},Array{Float64,1}}, ::Array{Int64,1}, ::Array{Float64,1}; autodiff::Symbol, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at curve_fit.jl:63
lmfit(::Function, ::Array{Int64,1}, ::Array{Float64,1}) at curve_fit.jl:61
curve_fit(::typeof(model), ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Array{Float64,1}, ::Array{Int64,1}; inplace::Bool, kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at curve_fit.jl:115
curve_fit(::Function, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Array{Float64,1}, ::Array{Int64,1}) at curve_fit.jl:106
top-level scope at mcconnel_simulation.jl:71
为什么 curve_fit 无法解决这个简单的案例?
解决方案
p0
需要有浮动eltype
(例如Float64
):
julia> p0=[10.0,50.0]
2-element Array{Float64,1}:
10.0
50.0
julia> fit=curve_fit(model,collect(tdata),ydata,p0)
LsqFit.LsqFitResult{Array{Float64,1},Array{Float64,1},Array{Float64,2},Array{Float64,1}}([10.0, 50.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 … -2.168404344971009e-19, -6.505213034913027e-19, 2.168404344971009e-19, 4.336808689942018e-19, 2.168404344971009e-19, 2.168404344971009e-19, 0.0, 0.0, 0.0, 0.0], [2.4813278524001437e-5 -2.4875467192362816e-6; 2.506222852629442e-5 -2.52523618286487e-6; … ; 9.896618565083517e-5 2.0199959191107846e-5; 9.704930889082663e-5 1.9605920988595578e-5], true, Float64[])
您也可以编写p0 = Float64[10,50]
以确保它eltype
是Float64
.
推荐阅读
- java - 如何从 zip 文件中读取 XML 文件?
- javascript - Razor Pages 从 javascript 验证函数调用 asp-page-handler 方法
- python-3.x - 在txt文件中插入空格 - Python
- java - 在类构造函数中使用枚举
- ubuntu - 无法在jetson agx xavier上安装anaconda
- html - Safari Web 和移动浏览器上的导航栏包装
- flutter - 显示所有用户数据,想在我的个人资料部分显示仅记录的用户数据
- ios - 从 3d 模型测量 iOS 中的建筑面积
- python - 匹配单个表中的记录,然后比较每条记录中的特定列
- laravel-8 - 触发事件并重新渲染组件后,Livewire 加载 javascript