使用 Eigen 的 Levenberg-Marquardt 的参数边界

问题描述

我正在使用 Eigen 的 Levenberg-Marquardt 实现,想知道如何为应该优化的参数设置一些边界。

当我将一些 GNU Octave 程序迁移到 Eigen 时,我预计可能会有一些边界可以轻松地作为参​​数提供给模块。

我的实现布局与this example中的几乎相同。 我没有提供 df() 实现,而是使用 Eigen::NumericalDiff 来近似它。

那么我如何对提供给minimize() 的参数施加一些边界? 我想过在离开预期范围时将 operator() 中的错误 (fvec) 设置为一些较高的值,但在一些小型测试中,这导致了奇怪的结果。

解决方法

我找到了一个至少对我有用的解决方案。

这个想法是在参数离开其合理边界后增加误差向量。

这可以通过以下函数实现:

penalize(x1,x2) = 1 + (exp(x1-x1max)*b1) + exp((x1min-x1)*b1) + exp((x2-x2max)*b2) + exp((x2min-x2)*b2)

b1/b2/... 必须根据边界选择。就我而言,我从 b1=0.1 开始,范围为 1600...3200。 该功能可以很容易地扩展到使用的参数量。

使用这样的功能:

int operator(x,fvec) const
{
    fvec(i) = ... * penalize(x(1),x(2))
}