Selecting a range of rows at a time

14 views (last 30 days)
Diana
Diana on 14 Apr 2017
Commented: Stephen23 on 14 Apr 2017
I have a matrix A = 1201x50. I would like to select a range of 30 rows at a time to analyse it (1-30, 31-60, 61-90...).
To explain better: I would like to find the bandpower of every 30 rows in all 50 columns (end up with a 40 x 50).
The easiest but very time consuming to write would be to select every single row range:
fs = 300
freqrange = [7 11]
Aa = bandpower(A((1:30),:),fs,freqrange);
Ab = bandpower(A((31:60),:),fs,freqrange);
Ac = bandpower(A((61:90),:),fs,freqrange);
Ad = bandpower(A((91:120),:),fs,freqrange);
(....)
FPOWER_Reward_7_11 = [Aa;Ab;Ac;Ad...]
But since I'll have to run a lot of frequency ranges, I would like a faster way of running this, without having to write each range of 30 (it will be 40 lines per frequency range). Is there a way to make this row selection easier and faster?
Thank you!

Accepted Answer

Stephen23
Stephen23 on 14 Apr 2017
Edited: Stephen23 on 14 Apr 2017
Method one: use a loop and basic indexing: this is the easiest and most efficient solution:
out = NaN(40,50);
for k = 1:40;
idx = (k-1)*30+(1:30);
out(k,:) = bandpower(A(idx,:),fs,freqrange);
end
Method Two: use mat2cell and cellfun:
C = mat2cell(A,30*ones(1,40),50);
out = cell2mat(cellfun(@(m)bandpower(m,fs,freqrange),C,'uni',0));
Method Three: use accumarray:
idx = 1:size(A,1);
grp = ceil(idx(:)/30);
accumarray(grp,idx(:),[],@(r)bandpower(A(r,:),fs,freqrange));
Warning: whatever you do, do NOT try to create or access lots of variable names (e.g. Aa, Ab, etc) in a loop. Read this to know why:
  2 Comments
Diana
Diana on 14 Apr 2017
Thank you. I used the loop - modified a bit, but the original also worked really well.
Stephen23
Stephen23 on 14 Apr 2017
@Diana: I hope that it helped. Make sure that you always preallocate the output array (as my example showed):

Sign in to comment.

More Answers (2)

Jos (10584)
Jos (10584) on 14 Apr 2017
You can loop over the rows, using for-loops or arrayfun:
step = 30 ;
fh = @(x) bandpower(A(x:min(x+step-1,size(A,2)),:), fs, freqrange);
Y = arrayfun(fh, 1:30step:size(A,2), 'un', 0)
FPOWER_Reward_7_11 = cat(1, Y{:})

Rik
Rik on 14 Apr 2017
You can replace your code with the code below, although it will not be any faster than the code you describe.
fs = 300
freqrange = [7 11]
FPOWER_Reward_7_11 = zeros(40,50);
for n=1:40
FPOWER_Reward_7_11(n,:) = bandpower(A((1:30)+30*(n-1),:),fs,freqrange);
end

Categories

Find more on Loops and Conditional Statements 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!