Fast and simple trend

14 views (last 30 days)
Azura Hashim
Azura Hashim on 17 Dec 2017
Commented: Azura Hashim on 18 Dec 2017
Hi,
I need a fast and simple way to calculate the trend of a variable at each point in time for data over the preceding 1 hour. All I need is whether the trend is increasing or decreasing and to what degree. At the moment I am using fitlm to return the slope for each row but have found this to be too slow. Below is a simple example but my application has a much bigger dataset and I need at least an order of magnitude speedup. Appreciate some help please, especially if there are ways to vectorize the calculation. Thank you.
time=[0.2,0.8,0.9,1.1,1.2,1.7,1.8,2.1,2.2];
x=[0.2,0.4,0.5,0.7,1.1,0.7,0.6,1.7,2.1];
slopes=repmat(NaN,length(x),1);
for row=1:length(x)
startrow=find(time >= time(row)-1,1);
%calculate slope if there are more 2 or more data points
if row > startrow
temptime=time(startrow:row);
tempx=x(startrow:row);
mdl = fitlm(temptime,tempx);
slopes(row)=mdl.Coefficients.Estimate(2);
end
end

Accepted Answer

the cyclist
the cyclist on 17 Dec 2017
Edited: the cyclist on 17 Dec 2017
You can do the fit directly with matrix operations. It should be roughly a gazillion times faster.
coeffs = [ones(size(temptime')) temptime']\tempx';
slopes(row) = coeffs(2);
There are presumably other efficiencies if you restructure your data ahead such that you do not need to do the transposes, or create the "ones" matrix inside the loop.
  1 Comment
Azura Hashim
Azura Hashim on 18 Dec 2017
Thank you, this worked well!

Sign in to comment.

More Answers (1)

Jan
Jan on 17 Dec 2017
What about the faster polyfit:
time = [0.2,0.8,0.9,1.1,1.2,1.7,1.8,2.1,2.2];
x = [0.2,0.4,0.5,0.7,1.1,0.7,0.6,1.7,2.1];
slopes = NaN(length(x), 1);
for row = 1:length(x)
startrow = find(time >= time(row)-1,1);
if row > startrow
P = polyfit(time(startrow:row), x(startrow:row), 1);
slopes(row) = P(1);
end
end
If this is still too slow, use a leaner version of polyfit:
function p = LeanPolyFit1(x, y)
V = [x(:), ones(numel(x), 1)];
% Solve least squares problem:
[Q, R] = qr(V, 0);
p = transpose(R \ (transpose(Q) * y(:)));
end

Community Treasure Hunt

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

Start Hunting!