Using polifit in matlab

6 visualizaciones (últimos 30 días)
VMyr
VMyr el 2 de Jun. de 2017
Editada: Jan el 2 de Jun. de 2017
Hi,
I'm processing some data collected of charges and discharges curves of a battery. To do so, I'm fitting the data to a polynomial using polifit. what I'm doing is the following:
t=time(line,colomn);
V=volt(line,colomn);
sz=size(t,1);
l=150;
n=3;
tab=[];
%charge
for k1=(1+l/2):sz-l/2
x=t((k1-l/2):(k1+l/2),1);
y=V((k1-l/2):(k1+l/2),1);
poly=polyfit(x,y,n);
yf=polyval(pply,t(k1,1));
tab=[tab;t(k1,1) yf];
%But it takes a lot of time doing it. It exist any other way to do the same thing in less time?
%I think that part of the problem come from doing vertcat of each value.
thank you

Respuesta aceptada

Jan
Jan el 2 de Jun. de 2017
Editada: Jan el 2 de Jun. de 2017
Using the center point of a polynomial fitted to the surrounding points is a Savitzky-Golay filter. Either use Matlab's sgolayfilt or the C-Mex function https://www.mathworks.com/matlabcentral/fileexchange/5661-fsgolayfilt. Then the loop is not required:
tab = fSGolayFilt(V, 3, 151); % or sgolayfilt, about 50% slower
This works only, if t is equidistant. If not think about a linear interpolation at first. Or replace the polyfit function by a faster version:
function p = fPolyFit(x, y, n)
% Construct Vandermonde matrix:
x = x(:);
V = ones(length(x), n + 1);
for j = n:-1:1
V(:, j) = V(:, j + 1) .* x;
end
% Solve least squares problem:
[Q, R] = qr(V, 0);
p = transpose(R \ (transpose(Q) * y(:))); % Same as: (V \ y)'
Note that omitting the validity checks of the inputs is not a good idea in general. But here it helps.
You are right: The iterative growing of the array is a severe problem. A "pre-allocation" helps - serach in the forum for this term to learn the details.
len = sz - l;
tab = zeros(1, len);
iTab = 0;
for k1 = (1+l/2):sz-l/2
...
iTab = iTab + 1;
tab(iTab) = yf;
end
Join the time afterwards.

Más respuestas (1)

Image Analyst
Image Analyst el 2 de Jun. de 2017
How much data do you have? Billions of elements? Otherwise it should be really fast. Since the (badly named) l is 150, it looks like the fits are done over only a minuscule 150 points, so that should be blazingly fast to do just a single fit.
It looks like you're trying to fit lots of polynomials in a window sliding along your data. If so, that's basically a Savitzky-Golay filter and can be done efficiently using the function sgolayfilt() in the Signal Processing Toolbox.

Categorías

Más información sobre Spline Postprocessing en Help Center y File Exchange.

Etiquetas

Aún no se han introducido etiquetas.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by