Re: Apache Commons Math of Curve Fitting how to constraint Parameters

2022-01-23 Thread qiqi tang
*HI Gilles Sadowski,*



@Overridepublic double[] fit(Collection points) {
final double[] p = super.fit(points);
return new double[] {
constrainedM.value(p[0]),
constrainedK.value(p[1]),
p[2]
};
}

This method Just maps  the end result to the range I want.I think I need to
let the return value of the fit method fall within the set range, rather
than processing the return value of the fit method twice. Just like example:

@Overridepublic double[] fit(Collection points) {
return  super.fit(points);}

The above method returns a value that is directly in the range of the
parameter variable I want.

Regards,
Qiqi


Apache Commons Math of Curve Fitting how to constraint Parameters

2022-01-20 Thread qiqi tang
Dear Sir/Madam,
   I recently used the CurveFitter tool inside the commons package and
I found a problem that I couldn't constrain the relevant parameters.
The specific relevant codes are as follows:

public class MyFuncFitter extends AbstractCurveFitter {

@Override
protected LeastSquaresProblem
getProblem(Collection 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 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))
};
}

public static void main(String[] args) {
MyFuncFitter fitter = new MyFuncFitter();
ArrayList 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));
}}

Then, What should I do to limit the parameters 'm' to 1 to 100 and 'k'
to 100 to 10,000,It would be nice if the code dome was available.
Please help me thank you very much!
Best Regards