1
$\begingroup$

I have a set of data, how can I fit the best function to that? i use FindFit and then I guess the function myself, but I want Mathematica to find the best fit. How can it be done?

y1 = {48.999, 57.180, 63.8421, 68.81, 72.228, 74.428, 75.782, 76.60, 
   77.138, 77.531, 77.886, 78.264, 78.697, 79.201, 79.784, 80.444, 
   81.180, 81.986, 82.857, 83.786, 84.7678, 85.796, 86.866, 87.974`, 
   89.113, 90.281, 91.474, 92.687`, 93.920, 95.167, 96.428, 97.700, 
   98.981, 100.268, 101.562, 102.859, 104.158, 105.460, 106.761, 
   108.062, 109.361, 110.658, 111.951};

y2 = Table[y2, {y2, 50, 470, 10}];

data = Transpose[{y2, y1}];
x1 = ListLinePlot[data]
    

enter image description here

FindFit[data, d x^4 + a x^3 + b x^2 + c x + f, {d, a, b, c, f}, x]

Show[ListPlot[data, PlotStyle -> Red], 
 Plot[d x^4 + a x^3 + b x^2 + c x + 
    f /. {d -> -1.2911673126124723`*^-8, 
    a -> 0.000014771971357899056`, b -> -0.005794083194578543`, 
    c -> 0.9998897221123239`, f -> 16.20821389434905`}, {x, 50, 500}]]

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ Easiest would be to get some inspiration from theoretical insights. Where do these data come from? What do you know about the asymptotes? etc. $\endgroup$
    – Roman
    Commented Oct 12, 2023 at 19:42
  • $\begingroup$ Put in plots of data and fit. Revert if you don't want those shown. $\endgroup$
    – Hugh
    Commented Oct 12, 2023 at 20:53
  • 3
    $\begingroup$ If you wish to use the fitted function in further analysis then an interpolation function could be suitable. You can do everything with an interpolation function that you could do with a fitted function. Do you need an example of the approach. What are you going to do with your fitted function? $\endgroup$
    – Hugh
    Commented Oct 12, 2023 at 20:56
  • $\begingroup$ @Hugh i want to enter it in another formula. $\endgroup$
    – li xu
    Commented Oct 12, 2023 at 21:12
  • $\begingroup$ You can put an interpolation function in a formula. It will work fine. $\endgroup$
    – Hugh
    Commented Oct 12, 2023 at 21:15

2 Answers 2

2
$\begingroup$

I couldn't resist devoting 30 seconds of DataModeler at this. FindFormula[ ] was not all that good but evolution did a pretty decent job:

Table of developed models and fit to data

$\endgroup$
3
  • $\begingroup$ hi, thanks, can you elaborate on that? Is it a package? I used FindFormula and it woorked quite good, but this one is much better. $\endgroup$
    – li xu
    Commented Oct 13, 2023 at 6:48
  • $\begingroup$ DataModeler is a commercial product which implements symbolic regression as well as the surrounding infrastructure you need for multivariate feature selection and model development. You can get a trial license from www.evolved-analytics.com. $\endgroup$ Commented Oct 13, 2023 at 15:38
  • $\begingroup$ Thanks for the explanation $\endgroup$
    – li xu
    Commented Oct 13, 2023 at 16:40
2
$\begingroup$

Many of the other answers are very good but I do think a simple interpolation function could be the simplest. Particularly as your data does not seem to include and noise. Below I make an interpolation function then invent a function to show how easy it is to use in other functions.

    y1 = {48.999, 57.180, 63.8421, 68.81, 72.228, 74.428, 75.782, 76.60, 
       77.138, 77.531, 77.886, 78.264, 78.697, 79.201, 79.784, 80.444, 
       81.180, 81.986, 82.857, 83.786, 84.7678, 85.796, 86.866, 87.974`, 
       89.113, 90.281, 91.474, 92.687`, 93.920, 95.167, 96.428, 97.700, 
       98.981, 100.268, 101.562, 102.859, 104.158, 105.460, 106.761, 
       108.062, 109.361, 110.658, 111.951};
    
    
    y2 = Table[y2, {y2, 50, 470, 10}];
    
    
    data = Transpose[{y2, y1}];
    {x1, x2} = {y2[[1]], y2[[-1]]};
    
    ClearAll[f];
    f[x_] := Evaluate[ Interpolation[data, Method -> "Spline"][x]]
Plot[f[x], {x, x1, x2}]

enter image description here

Now lets put the new function into an invented function and plot that

  Plot[f[x]^2/(90 - f[x] + 0.5 x), {x, 50, 470}, PlotRange -> All]

enter image description here

You can take the derivative of a function containing the interpolation function.

g[x_] := f[x]^2/(90 - f[x] + 0.5 x)

dg = D[g[x], x];

Plot[dg, {x, x1, x2}]

enter image description here

The only tricky issue is to integrate. You need a starting value but then you can use NDSolve to give you a new integrated interpolation function.

int = y /. First@NDSolve[{y'[x] == g[x], y[0] == 0}, y, {x, x1, x2}];

Plot[int[x], {x, x1, x2}]

enter image description here

Hope that helps. I think an interpolation function is simplest if you do not have noise in your data and you have no need to smooth.

$\endgroup$
3
  • $\begingroup$ thanks, I should work on it, but I need something like y=F(x) can you explain this part, I did not get it: {x1, x2} = {y2[[1]], y2[[-1]]}; $\endgroup$
    – li xu
    Commented Oct 13, 2023 at 9:29
  • $\begingroup$ The x1 and x2 are the first and last points of the x values. You called your abscissi y1 and I was just trying to make things easier by having a symbol rather than typing the numbers into plot etc. [[1]] is the first point and [[-1]] the last point of a list. $\endgroup$
    – Hugh
    Commented Oct 13, 2023 at 11:36
  • $\begingroup$ thanks for the explanation, I got it. $\endgroup$
    – li xu
    Commented Oct 13, 2023 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.