Speed up stepwise averaging
2 views (last 30 days)
Show older comments
I have an array index with different indices and I want to average a different array according to these indices! Currently I run this code (array index would change in every iteration):
index = ceil(0.01:0.1:500);
data = rand(size(index));
for q = 1:1000 % just for timing
adata = zeros(size(data));
for n = min(index):max(index)
k = index == n;
adata(k) = sum(data(k))/sum(k);
end
end
Any way to speed this up even further?
Thanks Felix
1 Comment
Image Analyst
on 30 Mar 2015
Are you sure index is right? And what is the q loop for? Timing? I don't see tic and toc or anything. Would that be in the final code, or do you have that just to test/time different strategies? It sort of looks like you might be able to use blockproc() (in the Image Processing Toolbox) to find averages by "jumping" the window, but it depends on exactly what you're doing, and I can't figure that out. Maybe conv() would be okay if you want to move along one element at a time. And, in your example, n = min(index):max(index) is just simply n=1:500 but I don't if that will always be true because you say index will change every time but you don't say how it might be different from one time to the next.
Accepted Answer
Mohammad Abouali
on 30 Mar 2015
if the indeces in the index variable are like your example next to each other you can take advantage of that. Here is the timing I get:
For the modified version: Elapsed time is 2.229993 seconds.
for the original code you posted. Elapsed time is 15.343979 seconds.
And here is the code:
index = ceil(0.01:0.1:500);
data = rand(size(index));
% modified version
tic
for q=1:1000
breakPoints= find(diff([0 index 0]));
adata1 = zeros(size(data));
for i=1:numel(breakPoints)-1
idx=breakPoints(i):breakPoints(i+1)-1;
adata1(idx)=sum(data(idx))./numel(idx);
end
end
toc
% original version
tic
for q = 1:1000 % just for timing
adata2 = zeros(size(data));
for n = min(index):max(index)
k = index == n;
adata2(k) = sum(data(k))/sum(k);
end
end
toc
% checking if they produced the same results
all(adata1==adata2)
1 Comment
Jan
on 30 Mar 2015
You can try to use a dynamic indexing instead of creating an index vector:
breakPoints = find(diff([0 index 0])); % Once only
adata1 = zeros(size(data)); % Once only
for q=1:1000
for i = 1:numel(breakPoints)-1
a = breakPoints(i);
b = breakPoints(i+1)-1;
adata1(a:b)=sum(data(a:b)) ./ (b - a + 1);
end
end
More Answers (0)
See Also
Categories
Find more on Data Import and Analysis in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!