Speed up stepwise averaging

2 vues (au cours des 30 derniers jours)
Felix Ruhnow
Felix Ruhnow le 30 Mar 2015
Commenté : Jan le 30 Mar 2015
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 commentaire
Image Analyst
Image Analyst le 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.

Connectez-vous pour commenter.

Réponse acceptée

Mohammad Abouali
Mohammad Abouali le 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 commentaire
Jan
Jan le 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

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Data Import and Analysis dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by