Gilles, Thanks so much for your patiently response! I know I can write a gradient method for a specific function, but my purpose is to make the gradient method suitable for any function of yi = f(xi, p1, p2, p3, ...). That means the users don't need to override a new fixed gradient method for a new function, just like the SciPy's curve_fit ( https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html). So I tried to calculate gradient array through numerical differentiation ( https://github.com/meteoinfo/MeteoInfo/blob/master/meteoinfo-math/src/main/java/org/meteoinfo/math/optimize/MyParametricUnivariateFunction.java#L33-L56, the code also is attache below), and please let me know whether the code is correct for my purpose? Thanks!
@Override public double[] gradient(double v, double... parameters) { function.setParameters(parameters); // create a differentiator FiniteDifferencesDifferentiator differentiator = new FiniteDifferencesDifferentiator(nbPoints, stepSize); // create a new function that computes both the value and the derivatives // using DerivativeStructure UnivariateDifferentiableFunction diffFunc = differentiator.differentiate(function); double y = function.value(v); int n = parameters.length; double[] gradients = new double[n]; for (int i = 0; i < n; i++) { DerivativeStructure xDS = new DerivativeStructure(n, 1, i, parameters[i]); DerivativeStructure yDS = diffFunc.value(xDS); int[] idx = new int[n]; idx[i] = 1; gradients[i] = yDS.getPartialDerivative(idx); } return gradients; } By the way, I am using Apache commons math 3.6.1 at present. Today I also tried the 4.0-SNAPSHOT version but the result is the same. Regards Yaqiang On Mon, Aug 1, 2022 at 8:33 PM Gilles Sadowski <gillese...@gmail.com> wrote: > Hi. > > Le dim. 31 juil. 2022 à 18:05, Yaqiang Wang <yaqiang.w...@gmail.com> a > écrit : > > > > Currently I just want to fit univariate function such as the following > Python function: > > > > def func(x, a, b, c): > > return a * exp(-b * x) + c > > > > > > I also tried using SimpleCurveFitter to do it. > MyParametricUnivariateFunction implements ParametricUnivariateFunction and > overrides value and gradient methods ( > https://github.com/meteoinfo/MeteoInfo/blob/master/meteoinfo-math/src/main/java/org/meteoinfo/math/optimize/MyParametricUnivariateFunction.java), > and the gradient array is calculated through numerical differentiation. > > Given a list of points, { xi } (i = 0, 1, ... , N), and their associated > values, > { y_i }, "SimpleCurveFitter" aims at finding the best fit of an assumed > function "f" > yi = f(xi, p1, p2, p3, ...) > whose parameters p1, p2, p3, ... can be adjusted. > Internally, "SimpleCurveFitter" computes the Jacobian matrix > df(x0)/dp1 df(x0)/dp2 df(x0)/dp3 ... > df(x1)/dp1 df(x1)/dp2 df(x1)/dp3 ... > .... > df(xN)/dp1 df(xN)/dp2 df(xN)/dp3 ... > needed by the "Levenberg-Marquardt" least-squares optimizer. > The gradient of "f" is an array where each slot contains the partial > derivative of the univariate function (at the given "x") wrt to each > _parameter_. > For your function above, the code would be (untested): > ---CUT--- > public class MyFunction implements ParametricUnivariateFunction { > > public double value(double x, double ... parameters) { > final double a = parameters[0]; > final double b = parameters[1]; > final double c = parameters[2]; > return a * Math.exp(-b * x) + c > } > > public double[] gradient(double x, double ... parameters) { > final double a = parameters[0]; > final double b = parameters[1]; > final double c = parameters[2]; > final double[] grad = new double[3]; > grad[0] = Math.exp(-b * x); > grad[1] = -a * x * grad[0]; > grad[2] = 1; > return grad; > } > } > ---CUT--- > > HTH, > Gilles > > > [...] > > --------------------------------------------------------------------- > To unsubscribe, e-mail: user-unsubscr...@commons.apache.org > For additional commands, e-mail: user-h...@commons.apache.org > > -- ************************************************* Dr. Yaqiang Wang Chinese Academy of Meteorological Sciences (CAMS) 46, Zhong-Guan-Cun South Avenue Beijing, 100081 China yaqiang.w...@gmail.com www.meteothink.org **************************************************