How to programmatically select which array dimension to address
23 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commenti
Stephen23
il 16 Mar 2021
Modificato: Stephen23
il 16 Mar 2021
"How can I address the elements of the array?"
Define the indices in a cell array, then use a comma-separated list:
"It wouldn't take that many cases to cover most practical scenarios."
Or you could use a simple comma-separated list to obtain the general solution for any number of dimensions:
Risposta accettata
Walter Roberson
il 16 Mar 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
Più risposte (1)
John Chilleri
il 15 Mar 2021
Modificato: John Chilleri
il 15 Mar 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!
Vedere anche
Categorie
Scopri di più su Matrix Indexing in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!