# Reduce dimensionality using indices

8 views (last 30 days)
fromLondon on 28 May 2014
Answered: fromLondon on 28 May 2014
Hi all.
I have what I tink should be a fairly simple question but I just can't work it out. In one of my scripts I have a three-dimensional array A like this:
A(:,:,1) =
2 4 8
5 6 3
10 3 6
A(:,:,2) =
7 6 3
9 2 9
10 2 3
A(:,:,3) =
9 4 7
3 2 5
10 3 4
I also have a 2D matrix d which looks sth like this:
d =
1 2 3
1 1 3
2 1 1
Now, what I want to reduce A to two dimensions using the third dimension elements indicated by d. The result should be:
AA =
2 6 7
5 6 5
10 3 6
Surely there's a clever way to do this without loops? I fiddled around with a combination of meshgrid and d but that got ugly really quickly...
EDIT : I should have made clear that this is just an example and I don't necessarily know the dimensions of A. It will always be true that
size(A,1) == size(d,1)
size(A,2) == size(d,2)
but A may be 5x5x13.
Thanks so much for your help.

Jos (10584) on 28 May 2014
Convert sub indices into linear indices:
% some data
A = ceil(10*rand(3,4,3)) % A has an arbitrary size
d = ceil(size(A,3)*rand(size(A,1),size(A,2))) % d is the subindex in the 3rd dimension
% engine
Nrc = size(d) ;
[r,c] = ndgrid(1:Nrc(1), 1:Nrc(2)) ; %r,c, specify the subindices in the 1st and 2nd dimension
ix = sub2ind(size(A),r, c, d) % convert to linear indices
B = A(ix) % retrieve from A
% check
x = 2 ; y = 3 ;
A(x,y,d(x,y)) == B(x,y)

George Papazafeiropoulos on 28 May 2014
This is an alternative solution which does not contain external functions, thanks to Jos!
% initial data
A=ceil(10*rand(3,4,3))
d=ceil(size(A,3)*rand(size(A,1),size(A,2)))
% engine
dim1=size(A,1);
dim2=size(A,2);
linind=(1:dim1*dim2)';
linind=reshape(linind,dim1,dim2);
modind=linind+(d-1)*dim1*dim2;
AA=A(modind);
% check
x=2;
y=1;
A(x,y,d(x,y)) == AA(x,y)
Thanks Jos!

George Papazafeiropoulos on 28 May 2014
After specifying A...
d=[1 2 3;
1 1 3;
2 1 1];
B=zeros(3,3,3);
B(:,:,1)=(d==1);
B(:,:,2)=2*(d==2);
B(:,:,3)=3*(d==3);
AA=sum(A.*B,3)
fromLondon on 28 May 2014
Hi.
Thanks for the quick reply. I like the solution but I should have made clear that I don't necessarily know the size of A. I will change the question accordingly. My bad.

fromLondon on 28 May 2014
Perfect. Thank you both! :-)