Julia非线性最小二乘包中的Levenberg-Marquardt

Julia非线性最小二乘包中的Levenberg-Marquardt,julia,nonlinear-optimization,Julia,Nonlinear Optimization,我有一个参数估计问题,可以通过非线性最小二乘优化来解决。我有一个带有两个未知参数的分析模型x[0]和x[1]。我有一个测量数据样本的向量,我用它编写成本函数 function cost_function(x) measured = data_read() # This is where I read my measured samples model = analytical_model(x) # I calculate the values from my

我有一个参数估计问题,可以通过非线性最小二乘优化来解决。我有一个带有两个未知参数的分析模型
x[0]
x[1]
。我有一个测量数据样本的向量,我用它编写
成本函数

function cost_function(x)
    measured = data_read()   # This is where I read my measured samples
    model = analytical_model(x)  # I calculate the values from my 
                                   analytical model method
    residual = abs.(measured - model)
    return residual
end
LsqFit
在Julia中,它有
Levenberg-Marquardt(LM)
实现,只有方法
curve\u fit
采用
model
analytical\u model()
),
xdata
p
ydata
,并将此函数传递给
LM
优化器。(即)
模型(扩展数据,p)-ydata
成为残差。但对我来说,我的
测量值
模型
都是复数,这就是我必须返回
abs的原因。(

我试过了

import LsqFit
result = LsqFit.levenberg_marquardt(cost_function, rand(2)) 

但它需要我的成本函数(x)的雅可比矩阵作为另一个参数。我不知道雅可比矩阵,我希望我的优化器使用前向差分近似为我计算雅可比矩阵。Julia有没有办法做到这一点?

以下调用应该可以:

LsqFit.lmfit(cost_function, [0.5, 0.5], Float64[])
(请让我知道它是否有效,
[0.5,0.5]
是一个示例起点)

以下是一个例子:

julia> function cost_function(x)
           measured = [2:2:20;] .+ 0.5im
           model = [1:10;] .* x[1] .+ x[2] .* im
           residual = abs.(measured .- model)
           return residual
       end
cost_function (generic function with 1 method)

julia> LsqFit.lmfit(cost_function, [0.5, 0.5], Float64[])
LsqFit.LsqFitResult{Array{Float64,1},Array{Float64,1},Array{Float64,2},Array{Float64,1}}([2.0, 0.5], [5.18665e-8, 5.36734e-8, 5.65567e-8, 6.03625e-8, 6.49286e-8, 7.01067e-8, 7.57714e-8, 8.18218e-8, 8.81784e-8, 9.47796e-8], [0.000658313 -0.00846345; 0.00131663 -0.00846342; … ; 0.00592487 -0.00846286; 0.00658318 -0.00846272], true, Float64[])

julia> LsqFit.lmfit(cost_function, [0.5, 0.5], Float64[], autodiff=:forward)
LsqFit.LsqFitResult{Array{Float64,1},Array{Float64,1},Array{Float64,2},Array{Float64,1}}([2.0, 0.5], [4.44089e-16, 8.88178e-16, 1.77636e-15, 1.77636e-15, 1.77636e-15, 3.55271e-15, 3.55271e-15, 3.55271e-15, 3.55271e-15, 3.55271e-15], [-1.0 -0.0; -2.0 -0.0; … ; -9.0 -0.0; -10.0 -0.0], true, Float64[])

我们看到返回了正确的解决方案
[2.0,0.5]

最简单的方法可能是使用函数并返回
求和(残差)
。请注意,Julia使用基于1的索引,因此您可能有
x[1]
x[2]
@BogumiłKamiński,谢谢您的回复。我确实试过Optim.jl包-他们没有在这个包中实现
Levenberg-Marquardt
函数。我找到的最接近的二次非线性优化器是
newontrustergion()
,它对我来说效率不高。关于索引,我是python用户,我正在慢慢地转向Julia。但是我确实在我的代码中使用了
x[1]
x[2]
。)为什么严格要求L-M优化器?在LsqFit.jl中有
curve\u fit
函数,在该函数中,您不必通过雅可比矩阵,并且可以通过
autodiff
kwarg选择前向差分近似值。正如我前面所说的,我查看了
curve\u fit
代码,它实现了我在总结中提到的功能。Julia中的LsqFit包具有Levenberg-Marquardt(LM)实现,其中只有方法曲线拟合,它采用
模型(此处为分析模型)
xdata
p
ydata
,并将此函数传递给LM优化器。(即)
模型(扩展数据,p)-ydata
成为残差。但是我想
abs.(model(xdata,p)-ydata)
作为残差的输入。好了,现在我知道了。很抱歉错过了评论。我已经发布了我认为应该有效的内容(假设您使用的是
Float64
值;如果它们是例如
BigFloat
,则相应地更改第三个参数)。