2015-07-10 106 views
2

我正在使用Apache commons math3开发一个适合的应用程序。我已经成功地创建了ParametricUnivariateFunction为Apache Math3拟合添加参数约束

public class MyFunc implements ParametricUnivariateFunction { 
@Override 
public double value(double x, double... Parameters) { 
    double m = parameters[0], k = parameters[1], b = parameters[2]; 
    return m * k * b * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1); 
} 
@Override 
public double[] gradient(double x, double... Parameters) { 
    final double m = parameters[0]; 
    final double k = parameters[1]; 
    final double b = parameters[2]; 
    return new double[]{ 
     b * k * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1), 
     (b - 1) * b * k * m * x * Math.exp(-2 * k * x) * Math.pow(1 - Math.exp(-k * x), b - 2) + b * m * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1) - b * k * m * x * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1), 
     k * m * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1) + b * k * m * Math.exp(-k * x) * Math.pow(1 - Math.exp(-k * x), b - 1) * Math.log(1 - Math.exp(-k * x)) 
    }; 
} 

} 

而且AbstractCurveFitter

public class MyFuncFitter extends AbstractCurveFitter { 

@Override 
protected LeastSquaresProblem getProblem(Collection<WeightedObservedPoint> points) { 
    final int len = points.size(); 
    final double[] target = new double[len]; 
    final double[] weights = new double[len]; 
    final double[] initialGuess = {50, 1.0, 1.0}; 

    int i = 0; 
    for (WeightedObservedPoint point : points) { 
     target[i] = point.getY(); 
     weights[i] = point.getWeight(); 
     i += 1; 
    } 

    final AbstractCurveFitter.TheoreticalValuesFunction model = new AbstractCurveFitter.TheoreticalValuesFunction(new MyFunc(), points); 

    return new LeastSquaresBuilder(). 
      maxEvaluations(Integer.MAX_VALUE). 
      maxIterations(Integer.MAX_VALUE). 
      start(initialGuess). 
      target(target). 
      weight(new DiagonalMatrix(weights)). 
      model(model.getModelFunction(), model.getModelFunctionJacobian()).build(); 
} 

}

我在主

public static void main(String[] args) { 

    MyFuncFitter fitter = new MyFuncFitter(); 
    ArrayList<WeightedObservedPoint> points = new ArrayList<>(); 

    points.add(new WeightedObservedPoint(1.0, 0.25, 3.801713179)); 
    ///... 
    points.add(new WeightedObservedPoint(1.0, 4, 10.46561902)); 

    final double coeffs[] = fitter.fit(points); 
    System.out.println(Arrays.toString(coeffs)); 
} 

这个作品非常好使用它们!

现在我必须对参数添加约束(特别是m < = 100,k> = 0 e b> = 1)。

如何将这些约束条件添加到上面的系统中?

回答

0

我找到了解决方法:使用Java的优化建模

OptimizationProblem op = new OptimizationProblem(); 
... 
op.addDecisionVariable("m", false, new int[]{1, 1}); 
... 
op.addConstraint("m<=100");//<- the constraints 
... 
op.setInitialSolution("m", 50);//optional 
... 
op.setObjectiveFunction("minimize", str);//where str is the string representing the function to minimize 
... 
System.loadLibrary("Ipopt38"); 
op.solve("ipopt"); 
... 
if (!op.solutionIsOptimal()) { 
     return null; 
} 

features[0] = op.getPrimalSolution("m").toValue(); 
... 
features[3] = op.getOptimalCost(); 
+0

你也可以给缺少的部分?我是否需要定义渐变和所有? –