Speed up stepwise averaging
8 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Felix Ruhnow
am 30 Mär. 2015
Kommentiert: Jan
am 30 Mär. 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 Kommentar
Image Analyst
am 30 Mär. 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.
Akzeptierte Antwort
Mohammad Abouali
am 30 Mär. 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 Kommentar
Jan
am 30 Mär. 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
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu Characters and Strings finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!