Using polifit in matlab

6 views (last 30 days)
VMyr
VMyr on 2 Jun 2017
Edited: Jan on 2 Jun 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

Accepted Answer

Jan
Jan on 2 Jun 2017
Edited: Jan on 2 Jun 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.

More Answers (1)

Image Analyst
Image Analyst on 2 Jun 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.

Categories

Find more on Spline Postprocessing in Help Center and File Exchange

Tags

No tags entered yet.

Community Treasure Hunt

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

Start Hunting!