我正在使用Apache commons math3开发一个合适的应用程序。我已经成功创建了ParametricUnivariateFunction
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&lt; = 100,k&gt; = 0 e b&gt; = 1)。
如何将这些约束添加到上面的系统?
答案 0 :(得分:0)
我找到了一个解决方案:使用Java Optimization Modeler
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();