问题描述
我正在使用 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))
}