Speed up stepwise averaging

3 visualizaciones (últimos 30 días)
Felix Ruhnow
Felix Ruhnow el 30 de Mzo. de 2015
Comentada: Jan el 30 de Mzo. de 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 comentario
Image Analyst
Image Analyst el 30 de Mzo. de 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.

Iniciar sesión para comentar.

Respuesta aceptada

Mohammad Abouali
Mohammad Abouali el 30 de Mzo. de 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 comentario
Jan
Jan el 30 de Mzo. de 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

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Data Import and Analysis en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by