2

I want to split a matrix columnwise into 3 segments and do a calculation on it (mean()). Is there a way to get this without a for-loop, as I did in this provided sample?

M = [2 4 9; 50 50 200; 30 0 0];
M = [M 10*M]
N = length(M);
seg = 3 % split in lets say 3 parts
segLen = round(N/seg)
segBeg = (((1:seg)-1) * segLen)+1  % start indices
segEnd = segBeg + segLen -1        % end indices

for i = 1: length(segBeg)
    mean(M(:,segBeg(i):segEnd(i)),2)
end

Thank you!

Massoud
  • 175
  • 1
  • 7

3 Answers3

3

Think outside the box: use the 3rd dimension:

r=reshape(M,size(M,1),segLen,[])
squeeze(mean(r,2))

The first line produces a 3d array with the first matrix at r(:,:,1), the second at r(:,:,2), ... (use M(:,1:seg*segLen) instread of M if the number of columns is not divisible by segLen). mean(r,2) produces a nrows-by-1-by-seg array, squeeze makes a nrows-by-seg matrix out of it again.

arne.b
  • 4,212
  • 2
  • 25
  • 44
  • thank you very much! This is nice an elegant. Didn´t know about those commands. I´ll use the `M(:,1:seg*segLen)` indexing, because the columns are not divisible everytime. – Massoud Feb 25 '13 at 10:07
1

You can use arrayfun together with cell2mat

result = cell2mat(arrayfun(@(x,y) mean(M(:,x:y),2), segBeg, segEnd,...
   'UniformOutput', false))

This results in

result =

   1.0e+03 *

    0.0030    0.0145    0.0650
    0.0500    0.3500    1.2500
    0.0150    0.1500         0

where each column represents the mean across one submatrix.

Another solution using blockproc (like suggested by @DennisJaheruddin in the comments) could look like this

myFun = @(x) mean(x.data,2);

result2 = blockproc(M, [N, segLen], myFun)

This also results in

result2 =

   1.0e+03 *

    0.0030    0.0145    0.0650
    0.0500    0.3500    1.2500
    0.0150    0.1500         0

Note that blockproc can take advantage of parallel processing if the flag 'UseParallel' is set to true, i.e., result2 = blockproc(M, [N, segLen], myFun, 'UseParallel', true)

H.Muster
  • 9,297
  • 1
  • 35
  • 46
  • Thanks @H.Muster, this usage of anonymous functions is also very nice! Didn´t use this in the past. But now I will. Is there any advantages/disadvantages compared to the `reshape`-method? – Massoud Feb 25 '13 at 10:12
  • Actually, I do not know. The `reshape` solution seems simple and effective. – H.Muster Feb 25 '13 at 10:20
0

You can do for your example case

mean1 = mean(M(:,1:segLen))
mean2 = mean(M(:,segLen+1:N-segLen-1))
mean3 = mean(M(:,N-segLen:end)) 
Jan
  • 4,932
  • 1
  • 26
  • 30