Many many thanks Luc. Your feedback is much more then welcome.
Will try it and test it. Again many thanks for your time. 2014-08-14 15:28 GMT-03:00 Luc Maisonobe <[email protected]>: > Hi South Light, > > Le 14/08/2014 19:05, South Light a écrit : > > Hi Thomas, > > > > My problem is to find the best A value in y = 10 ^ ((x + 82) / (-10 * A)) > > that fits better in a set of data. I'll be getting different sets of > data. > > > > I'm new in the use of the math lib and the examples found are all based > > on deprecated classes. > > > > Now I'm a little lost in terms of which class will be better to solve the > > problem, was thinking CurveFitter was the way to go. > > > > Can someone help me and clear my ideas ? > > Here is what I would suggest to you (beware, I did not check it, just > scribbled it in a few minutes). > > Given your specific function, create a dedicated curve fitter, taking > the GaussianCurveFitter class as an example, slightly edited: > > public class MyFitter extends AbstractCurveFitter { > > /** Center. */ > private final double center; > > /** Initial guess. */ > private final double guessedA; > > private MyFitter(final double center, final double guessedA) { > this.center = center; > this.guessedA = guessedA; > } > > protected LeastSquaresProblem > getProblem(Collection<WeightedObservedPoint> points) { > > // Prepare least-squares problem. > final int len = observations.size(); > final double[] target = new double[len]; > final double[] weights = new double[len]; > > int i = 0; > for (WeightedObservedPoint obs : observations) { > target[i] = obs.getY(); > weights[i] = obs.getWeight(); > ++i; > } > > ParametricUnivariateFunction function = > new ParametricUnivariateFunction() { > @Override > public double value(double x, double ... p) { > // get the single "a" parameter > double a = p[0]; > // value of the function f(x), with current a > return FastMath.pow(10, ((x + center) / (-10 * a)); > } > > @Override > public double[] gradient(double x, double ... p) { > // get the single "a" parameter > double a = p[0]; > // derivative df/da > return new double[] { > -FastMath.ln(10) / (10 * a * value(x, p)); > }; > } > }; > > final AbstractCurveFitter.TheoreticalValuesFunction model = > new AbstractCurveFitter.TheoreticalValuesFunction(function, > observations); > > // Return a new least squares problem set up to fit curve > // to the observed points. > return new LeastSquaresBuilder(). > maxEvaluations(Integer.MAX_VALUE). > maxIterations(100). > start(new double[] { guessedA }). > target(target). > weight(new DiagonalMatrix(weights)). > model(model.getModelFunction(), > model.getModelFunctionJacobian()). > build(); > > } > > } > > This consider the center (85.0 in your example) is fixed and never > adjusted, while the parameter a is adjusted during the fitting. > > Use this as follows: > > // set up observed points > List<WeightedObservedPoint> observations = > new ArrayList<WeightedObservedPoint>(); > for (int i = 0; i < n; i++) { > observations.add(new WeightedObservedPoint(1.0, x[i], y[i)); > } > > // set up fitter, initial guess is a = 1.0 here > MyFitter fitter = new MyFitter(85.0, 1.0); > > // perform fitting > double[] fitted = fitter.fit(observations); > > // get the fitted value a: > System.out.println("fitted a = " + fitted[0]); > > > Once again, beware this is a quick answer, it probably needs soem > adjustments. Typically, the fitter is completely hard-coded (except for > the center value which you can provide at construction). The curve > fitters provided in Apache Commons Math for some classical curves > (harmonic, gaussian, polynomial) have more bells and whistles, in order > to change for example the start value or the max number of iterations. I > don't know if you need this level of flexibility in your case. > > Hope this helps, > Luc > > > > > Many thanks for all your feedback. > > > > > > Thanks a lot > > . > > > > > > > > 2014-08-14 13:47 GMT-03:00 Thomas Vandahl <[email protected]>: > > > >> I take it, you ask for help for doing your homework? > >> > >> Bye, Thomas > >> > >>> Am 14.08.2014 um 15:56 schrieb South Light <[email protected]>: > >>> > >>> Hi Ted, > >>> > >>> Thanks a lot for your suggestion but I need to add it using java. > >>> > >>> Thanks > >>> again > >>> . > >>> > >>> > >>> > >>> 2014-08-14 2:22 GMT-03:00 Ted Dunning <[email protected]>: > >>> > >>>> Have you considered using an interactive system like R, Matlab or > >> Octave? > >>>> > >>>> You might be happier. > >>>> > >>>> Or even have you considered goal search in Excel? > >>>> > >>>> > >>>> > >>>> > >>>> On Wed, Aug 13, 2014 at 6:08 PM, South Light <[email protected]> > >>>> wrote: > >>>> > >>>>> Hi, > >>>>> > >>>>> May be someone can help me with this problem. > >>>>> > >>>>> Given the follow function: y = 10 ^ ((x + 82) / (-10 * A)) > >>>>> > >>>>> I would like to found the A value witch curve fit better for a set of > >> x,y > >>>>> values, usually the set is about 20 to 25 x,y values. > >>>>> > >>>>> I use the CurveFitter class and the ParametricUnivariateFunction > >>>>> > >>>>> > >>>>> ParametricUnivariateFunction function = new > >>>> ParametricUnivariateFunction() > >>>>> { > >>>>> > >>>>> > >>>>> @Override > >>>>> > >>>>> public double[] gradient(double x, double[] params) { > >>>>> > >>>>> (????? comment) > >>>>> > >>>>> } > >>>>> > >>>>> > >>>>> @Override > >>>>> > >>>>> public double value(double x, double[] params) { > >>>>> > >>>>> > >>>>> double a = params[0]; > >>>>> > >>>>> > >>>>> return Math.pow(10, ((x + 82) / > >>>>> ( > >>>>> -10 * > >>>>> a > >>>>> ) > >>>>> )); > >>>>> > >>>>> > >>>>> } > >>>>> > >>>>> }; > >>>>> > >>>>> LevenbergMarquardtOptimizer optimizer = new > >>>> LevenbergMarquardtOptimizer(); > >>>>> > >>>>> CurveFitter<ParametricUnivariateFunction> fitter = new > >>>>> CurveFitter<ParametricUnivariateFunction>(optimizer); > >>>>> > >>>>> double[] x = { > >>>>> -82 > >>>>> , > >>>>> -85 > >>>>> , > >>>>> -89 > >>>>> }; > >>>>> > >>>>> double[] y = { > >>>>> 1 > >>>>> , > >>>>> 1.4 > >>>>> , > >>>>> 2 > >>>>> }; > >>>>> > >>>>> for (int i = 0; i < x.length; i++) > >>>>> > >>>>> fitter.addObservedPoint(x[i], y[i]); > >>>>> > >>>>> double[] result = fitter.fit(function, new double[] { 1, 10 }); > >>>>> > >>>>> > >>>>> > >>>>> A. Is this the best way to solve the problem or there's another > >> better > >>>>> way? > >>>>> > >>>>> B. What do we need to write on the gradient area (????? comment) ? > >>>>> > >>>>> Any help will be more then welcome. > >>>>> > >>>>> Many thanks !! > >>>> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [email protected] > >> For additional commands, e-mail: [email protected] > >> > >> > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >
