MATLAB: Using polifit in matlab

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

Best Answer

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.
Related Question