2014-03-24 53 views
0

我想对一些数据拟合二次函数y = a + bx + cx^2,使得c在最终结果中总是大于或等于0。也就是说,我想将我的搜索域限制在c范围内([0,Double.MAX_VALUE])。目前,我有下面的代码片段:Apache Commons Math:限制优化域

final CurveFitter<Parametric> fitter = new CurveFitter<Parametric>(new LevenbergMarquardtOptimizer()); 

fitter.addObservedPoint(0, 0); 
fitter.addObservedPoint(1, -1); 
fitter.addObservedPoint(-1, -1); 
fitter.addObservedPoint(2, -4); 
fitter.addObservedPoint(-2, -4); 

final double[] init = { 1, 2, 3 }; 
final double[] best = fitter.fit(new PositivePolynomialFunctionParametric(), init); 
final PolynomialFunction fitted = new PolynomialFunction(best); 
System.out.println(Arrays.toString(fitted.getCoefficients())); 

其中:

private static class PositivePolynomialFunctionParametric extends PolynomialFunction.Parametric { 
    @Override 
    public double value(double x, double... parameters) { 
     parameters[parameters.length - 1] = Math.abs(parameters[parameters.length - 1]); 
     return super.value(x, parameters); 
    } 

    @Override 
    public double[] gradient(double x, double... parameters) { 
     parameters[parameters.length - 1] = Math.abs(parameters[parameters.length - 1]); 
     return super.gradient(x, parameters); 
    } 
} 

输出是有道理的:

[-1.4286835350284688, -8.489786562989103E-17, 1.0300498244514197E-11] 

这似乎在这个特定的应用程序正常运行,但它不是为限制搜索域的一般情况提供了一个非常优雅的解决方案。有一个更好的方法吗?

回答

1

您应该使用其中一个优化器来实现/扩展* BoundsOptimizer类型,或者在OptimizationData中支持SimpleBounds。 the user guide on optimization的第12.4节也提到了一种调整正在优化的函数的方法,但建议使用其中一种边界支持算法。

+0

非常感谢小费 - 好主意! – zetches