Access last matlab size by ndimensions matrix

I have a record as a matrix that can have several dimensions: n Γ— m or n Γ— m Γ— p or n Γ— m Γ— p Γ— q or ...

I want to make access to the last dimension, for example:

 data = input(:,:,1) 

The problem is that the number : may change.

+6
source share
6 answers

You should use the fact that indexes into an array can be strings containing ':' :

 >> data = rand(2, 2, 2, 5); >> otherdims = repmat({':'},1,ndims(data)-1); >> data(otherdims{:}, 1) ans(:,:,1) = 7.819319665880019e-001 2.940663337586285e-001 1.006063223624215e-001 2.373730197055792e-001 ans(:,:,2) = 5.308722570279284e-001 4.053154198805913e-001 9.149873133941222e-002 1.048462471157565e-001 

See the subsref documentation for more subsref .

+9
source

This is a little hack, but here is how you can do it:

 data = rand(2,2,3); eval(['data(' repmat(':,',1,ndims(data)-1) '1)']) 

This will give (depending on the number of rands):

 ans = 0.19255 0.56236 0.62524 0.90487 
+5
source

You can use shiftdim to move the last dimension to the first and index it and change it back.

 x = rand(2,3,4,5,6); sz = size(x); A = shiftdim(x, numel(sz)-1); B = reshape(A(1,:), sz(1:end-1)); 

and

 >> isequal(B, x(:,:,:,:,1)) ans = 1 

or you can use subsref to index it:

 B = subsref(x, substruct('()', [num2cell(repmat(':', 1, ndims(x)-1)) 1])) 
+2
source

Good question!

Another possibility is to use linear indexing in blocks, and then change:

 x = rand(2,3,4,5); % example data n = 2; % we want x(:,:,...,:,n) siz = size(x); b = numel(x)/siz(end); % block size result = reshape(x(b*(n-1)+1:b*n),siz(1:end-1)); 

This is apparently the fastest approach on my computer (but try it yourself, it may depend on the version and system of Matlab)

+2
source

I think this does:

 a = rand(2,2,2,3) s = size(a) r = reshape(a, [], s(end)) reshape(r(:,1), s(1:end-1)) %// reshape(r(:,2), s(1:end-1)) gives you a(:,:,:,...,2) etc... 

I compared with Dennis the (correct) answer, and it gives the same result, but does not need eval , which should always be avoided if possible.

+1
source

Just in case, GNU Octave readers reach here.

@Rody Oldenhuis's answer can be written as a single line in Octave:

 > data = reshape(1:8, 2, 2, 2); > data({':'}(ones(1,ndims(data)-1)){:}, 1) ans = 1 3 2 4 

Here:

 {':'}(ones(1,ndims(data)-1)){:} 

means:

 tmp = {':'}; tmp = tmp(ones(1,ndims(data)-1)); tmp{:} 

From couse, repmat({':'},1,ndims(data)-1){:} also works.

0
source

Source: https://habr.com/ru/post/957993/


All Articles