How to programmatically select which array dimension to address

22 visualizaciones (últimos 30 días)
DGM
DGM el 15 de Mzo. de 2021
Comentada: DGM el 16 de Mzo. de 2021
I've run across this issue a few times, and I'm wondering if there's an elegant way to handle it.
Say I have a function that reorders the vectors/pages/etc of an N-D array along a specified dimension, but we don't really know how many dimensions this arbitrary array might have. How can I address the elements of the array? I can think of two solutions, neither of which seem particularly ideal.
On one hand, I could presume a maximum number of dimensions and just handle it with explicit cases. It wouldn't take that many cases to cover most practical scenarios. Let's say I presume a maximum of 5-D:
function outpict=reorderarray(myarray,whichdim)
sz=size(myarray);
reorderedVector=randi(sz(whichdim),[1 sz(whichdim)]);
switch whichdim
case 1
outpict=myarray(reorderedVector,:,:,:,:);
case 2
outpict=myarray(:,reorderedVector,:,:,:);
case 3
outpict=myarray(:,:,reorderedVector,:,:);
case 4
outpict=myarray(:,:,:,reorderedVector,:);
case 5
outpict=myarray(:,:,:,:,reorderedVector);
% we could go on ...
end
end
Alternatively, I could build the expression as a character array and use eval(). This seems like something I should avoid.
Is there a better way to do something like this?
  2 comentarios
DGM
DGM el 16 de Mzo. de 2021
Oof. I admit, I had struggled to find a good search query and could've done a better job. Thank you.

Iniciar sesión para comentar.

Respuesta aceptada

Walter Roberson
Walter Roberson el 16 de Mzo. de 2021
img = imread('flamingos.jpg');
imshow(reorderarray(img, 2));
imshow(reorderarray(img, 3));
imshow(reorderarray(img, 7));
function outpict = reorderarray(myarray,whichdim)
sz = size(myarray);
sz(end+1:whichdim) = 1; %in case asked for a dimension past the typical
idx = repmat({':'}, 1, length(sz));
idx{whichdim} = randperm(sz(whichdim));
outpict = myarray(idx{:});
end
  1 comentario
DGM
DGM el 16 de Mzo. de 2021
Auugh! It works!
I had run across a similar example in a very old book, but in the printing, the curly braces were parentheses. I just figured it was some old syntax that no longer worked. I didn't even think that of course it would be a cell array. I should've been paying attention.
Many thanks to you, Stephen, and John.

Iniciar sesión para comentar.

Más respuestas (1)

John Chilleri
John Chilleri el 15 de Mzo. de 2021
Editada: John Chilleri el 15 de Mzo. de 2021
Hello,
I wouldn't suggest this to be an elegant solution, but it has worked so far for a number of test cases.
% A is myarray
% wdim is whichdim
% ordering is reorderedVector
function C = reorderarray(A,wdim,ordering)
sz = size(A); % Acquire size
pA = 1:length(sz); % Create permutation vector
pA(1) = wdim; % Swap desired dimension with first dimension
pA(wdim) = 1;
sz2 = sz; % Track permuted size
sz2(1) = sz(wdim);
sz2(wdim) = sz(1);
B1 = permute(A,pA); % Permute matrix so desired dimension is first
B2 = B1(ordering,:); % Reorder rows and restructure as 2D array
B3 = reshape(B2,sz2); % Reshape back into original permuted shape
C = permute(B3,pA); % Undo the permutation
end
I'll note that the process makes sense intuitively, but I wouldn't guarantee its correctness. The reshape restoring order seems to work because MATLAB has consistent methods of indexing across functions.
Thanks!
  1 comentario
DGM
DGM el 16 de Mzo. de 2021
That works, but in my tests, it performs poorly in terms of execution time -- especially as array size increases. For a sample 100x10x10x10x10 array, it requires more than twice the time compared to the methods I described, and doubling the array size quintuples the time, whereas it only doubles it for the aforementioned methods.
I was actually surprised that the eval() method is actually slightly the fastest of the three. I've had it drilled into my head to avoid using eval(), but I'm not sure if this isn't a good use for it.

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by