I'm using Eigen's Levenberg-Marquardt implementation and wondering how to set some boundaries on the parameters which should be optimized.
As I'm migrating some GNU octave programs to Eigen I expected that there might be some boundaries which can be easily provided as parameters to the module.
The layout of my implemenation is nearly the same as in this example. I'm not providing the df() implemenatation but rather use Eigen::NumericalDiff in order to approximate it.
So how do I enforce some boundaries on the parameters which are supplied to minimize()? I thought about setting the errors(fvec) in the operator() to some high values when leaving my expected ranges, but in some small tests this resulted in strange results.
I found a solution which is at least working for me.
The idea is to increase the error vector once the parameters are leaving their sanity boundaries.
This can be achieved by the following function:
penalize(x1, x2) = 1 + (exp(x1-x1max)*b1) + exp((x1min-x1)*b1) + exp((x2-x2max)*b2) + exp((x2min-x2)*b2)
b1/b2/... must be picked dependent on the boundaries. In my case I started with b1=0.1 for a range of 1600...3200. The function can be easily extended to the used amount of parameters.
Use the function like that:
int operator(x, fvec) const
{
fvec(i) = ... * penalize(x(1), x(2))
}