# commons-user mailing list archives

##### Site index · List index
Message view
Top
From South Light <southligh...@gmail.com>
Subject Re: [math] Curve fitting ...
Date Thu, 14 Aug 2014 18:59:10 GMT
```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 <luc@spaceroots.org>:

> 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 <tv@apache.org>:
> >
> >> I take it, you ask for help for doing your homework?
> >>
> >> Bye, Thomas
> >>
> >>> Am 14.08.2014 um 15:56 schrieb South Light <southlight25@gmail.com>:
> >>>
> >>> 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 <ted.dunning@gmail.com>:
> >>>
> >>>> 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 <southlight25@gmail.com>
> >>>> 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: user-unsubscribe@commons.apache.org
> >> For additional commands, e-mail: user-help@commons.apache.org
> >>
> >>
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: user-unsubscribe@commons.apache.org
> For additional commands, e-mail: user-help@commons.apache.org
>
>

```
Mime
• Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message