convert data to a function using polyfit
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
JEDIDI Ran
el 5 de Jun. de 2020
Editada: John D'Errico
el 5 de Jun. de 2020
i have used polyfit function to fit my data and to have as an output a function and i have got that plot the red one is the polyfit function , the blue is the one i have it data , as you see they are close to each other but
P(t)= =2.995134969444502*(10^3)*(t^10)+(2.454194242827056*(10^3))*(t^9)-(3.074449680687996*(10^4))*(t^8)-(1.831814183200164*(10^4))*(t^7)+(1.225116448716314*(10^5))*(t^6)+(1.225116448716314*(10^5))*(t^5)-(2.265044070414277*(10^5))*(t^4)+(6.259310423328208*(10^2))*(t^3)+(1.720638633336634*(10^5))*(t^2)+(8.587517861009773*(10^4))*t+(2.102731998692876*(10^5));
so P(t=0)= (2.102731998692876*(10^5)) different from zero
what should i do to make it close ?
2 comentarios
KSSV
el 5 de Jun. de 2020
You should attach data here...not an image snippet. By the way, there is not data value at t= 0.
Respuesta aceptada
John D'Errico
el 5 de Jun. de 2020
Editada: John D'Errico
el 5 de Jun. de 2020
This is almost what would normally be called a broken stick regression, except the joints between the linear segments are curves and pretty smooth.
Is a polynomial ever a good choice to try to fit a curve that has essentially linear segments? Not really. Polynomials just don't like that kind of behavior, where they are SOMETIMES linear, but reasonably curved in other regions.
Can you fit a polynomial of the desired form, such that it will be forced through 0 at time 0? Well, yes. You could use my polyfitn tool. You can even trick polyfit to do so, but that would cause other problems, that you won't know how to deal with.
Simplest is to just use backslash. This code will run in R2016b or later:
P = (time.^(10:-1:1))\u;
P(end+1) = 0; % stuff a zero constant term so polyval will work
plot(time,u,'b.')
hold on
ti = linspace(0,max(time),1000);
plot(ti,polyval(P,ti),'r-')
What I have done here is to recognize that to fit a polynomial that is FORCED to pass through the point (0,0) just requires no constant term in the model. That is, the constant term must be EXACTLY zero.
As you can see, at zero, we get the desired behavior. We get exactly zero.
polyval(P,0)
ans =
0
The curve actually dips considerably below zero, but you have no data there at all. In fact, your curve fit as produced had virtually the same behavior, but your plot was not sufficiently carefully done to show that. I'll show a blowup of the plot you would have produced near zero for your fit:
As you can see, it dives down quite a way below zero. If you are worried about missing EXACTLY zero, then why are you not worried about that behavior? The small error at zero in your model was insignificant compared to the extent it dove down below zero. However, you missed that due to the way you plotted the curve, because you never evaluated the curve between the 1st and second data points!
Could I have done better? Yes, most assuredly so, but not by using a polynomial. The absolutely simplest solution is to just use a spline interpolation. Your data is not at all noisy, so an interpolating function will be a good choice. I can get that from the functions spline and ppval, or I could just have used interp1.
plot(time,u,'.b',ti,interp1(time,u,ti,'pchip'),'r-')
I used pchip to produce a curve that will NOT dip even by the slightest amount below zero there. So I could have done it like this too:
spl = pchip(time,u);
plot(time,u,'.b',ti,ppval(spl,ti),'r-')
The only thing you cannot do is write down the actual function on paper, as you have done. But there is no need to do so. The model is entirely contained in the variable spl there.
2 comentarios
John D'Errico
el 5 de Jun. de 2020
Editada: John D'Errico
el 5 de Jun. de 2020
- That you don't understand it just means you don't understand the linear algebra that polyfit uses to generate a fit. That is irrelevant here, because while I could teach you to use bsxfun, you should not be using a polynomial fit at all here.
- If the fact the polynomial goes below zero is important, this essentially forces you to NOT use a polynomial, since a polynomial fit will always dip below zero in that region. Again, this is why you don't want to use a polynomial.
- That you don't know how to pass a spline into a function does not mean you should not use the tool. It just means you need to learn to use functions, and learn how to pass things around in MATLAB.
- No, you cannot extract a function "from" interp1. But I already showed you how to extract that function from pchip, for as much as you need to extract.
So the real question you need to ask is how can you pass a spline into a function? And that part is easy.
You will externally create the model using pchip. That requires ONE simple line of code.
spl = pchip(time,u);
Now you pass that spline into a function trivially enough. If the function is a nested function, you don't even need to pass it in, since the nested function can see the variables in the calling function workspace. But this will work however:
function myfun(spl)
t = linspace(0,1,10);
for i = 1:numel(t)
ppval(spl,t(i))
end
end
ans =
0
ans =
8229.47650069855
ans =
84130.8822176659
ans =
168482.726405534
ans =
194822.685396463
ans =
201555.202012822
ans =
246706.027936529
ans =
303788.903706188
ans =
364730.612310776
ans =
412693.648644221
As you can see, I created the spline, then passed it into the function, and evaluated the spline at a list of points in a loop.
You don't say what kind of function you are using it in. But anything works. For example, suppose I wanted to compute the integral of this curve?
integral(@(t) ppval(spl,t),0,time(end))
ans =
241891.376196292
So I created a function handle that uses spl. Then I passed that function handle into integral, which computed the integral of that function over the domain of your data. If your problem involves using perhaps an ODE solver, again, that is no more difficult than what I already did.
Or, for example, suppsoe I wanted to use fzero, finding the point where that curve passes through u==250?
t250 = fzero(@(t) ppval(spl,t) - 250,.5)
t250 =
0.0816728813147105
ppval(spl,t250)
ans =
250
You can always pass that spline around into any function and then use it.
Again, not only don't you need to use a polynomial here, you actively don't want to use that polynomial. What you do need to do is to use a spline. And that part is really easy, far more so than using that polynomial was, because you then typed in all of those numbers.
Más respuestas (0)
Ver también
Categorías
Más información sobre Get Started with Curve Fitting Toolbox en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!