3

Suppose I have 4D matrix:

>> A=1:(3*4*5*6);
>> A=reshape(A,3,4,5,6);

And now I want to cut given number of rows and columns (or any given chunks at known dimensions).

If I would know it's 4D I would write:

>> A1=A(1:2,1:3,:,:);

But how to write universally for any given number of dimensions?

The following gives something different:

>> A2=A(1:2,1:3,:);

And the following gives an error:

>> A2=A;
>> A2(3:3,4:4)=[];
Dims
  • 47,675
  • 117
  • 331
  • 600
  • 3
    A minor modification of [this Q&A](http://stackoverflow.com/q/22537326/2586922) will work – Luis Mendo Nov 09 '15 at 11:35
  • To make sure I understand this correctly - the problem is that you don't know in advance how many `,:` you'll need in the indexing expression...? Also I'm assuming you meant "any given number of dimensions >=2"...? – Dev-iL Nov 09 '15 at 11:39
  • @Dev-iL yes this is it – Dims Nov 09 '15 at 15:30

3 Answers3

4

It is possible to generate a code with general number of dimension of A using the second form of indexing you used and reshape function. Here there is an example:

Asize = [3,4,2,6,4]; %Initialization of A, not seen by the rest of the code
A = rand(Asize);

%% This part of the code can operate for any matrix A
I = 1:2;
J = 3:4;
A1 = A(I,J,:);
NewSize = size(A);
NewSize(1) = length(I);
NewSize(2) = length(J);
A2 = reshape(A1,NewSize);

A2 will be your cropped matrix. It works for any Asize you choose.

alexmogavero
  • 537
  • 2
  • 12
4

I recommend the solution Luis Mendo suggested for the general case, but there is also a very simple solution when you know a upper limit for your dimensions. Let's assume you have at most 6 dimensions. Use 6 dimensional indexing for all matrices:

A1=A(1:2,1:3,:,:,:,:);

Matlab will implicit assume singleton dimensions for all remaining dimension, returning the intended result also for matrices with less dimensions.

Daniel
  • 36,610
  • 3
  • 36
  • 69
0

It sounds like you just want to use ndims.

num_dimensions = ndims(A)

if (num_dimensions == 3)
    A1 = A(1:2, 1:3, :);
elseif (num_dimensions == 4)
    A1 = A(1:2, 1:3, :, :);
end

If the range of possible matrix dimensions is small this kind of if-else block keeps it simple. It seems like you want some way to create an indexing tuple (e.g. (1:2,:,:,:) ) on the fly, which I don't know if there is a way to do. You must match the correct number of dimensions with your indexing...if you index in fewer dimensions than the matrix has, matlab returns a value with the unindexed dimensions collapsed into a single array (similar to what you get with

A1 = A(:);
gariepy
  • 3,576
  • 6
  • 21
  • 34