How to index one array by assigned vector in certain dimension
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Hi,
I'd like to form a new 2D array by indexing another 3D array, where the indexing is via one assigned vector.
Details like below:
Given arr_i,vec_i, want to find func_index as
arr_o = func_index(arr_i,vec_i);
%%%
arr_i1 = [111,112,113,114; ...
121,122,123,124];
arr_i2 = [211,212,213,214; ...
221,222,223,224];
arr_i3 = [311,312,313,314; ...
321,322,323,324];
arr_i = cat(3,arr_i1,arr_i2,arr_i3);
vec_i = [2,3,1,2];
arr_o = func_index(arr_i,vec_i);
%%%
With above operation, I expect arr_o will be
[211,312,113,214; ...
221,322,123,224];
The in/out relationship of func_index is:
arr_o(1:2,1) = arr_i(1:2,1,2), since vec_i(1) == 2;
arr_o(1:2,2) = arr_i(1:2,2,3), since vec_i(2) == 3;
arr_o(1:2,3) = arr_i(1:2,3,1), since vec_i(3) == 1;
arr_o(1:2,4) = arr_i(1:2,4,2), since vec_i(4) == 2;
Keypoint here is assigned vector actually index 3D array in certain one dimension (in this case is dim_3), and result in new 2D array.
Please propose matrix operation (avoiding loop, since the real array is quite big).
Thanks!!
0 commentaires
Réponse acceptée
DGM
le 15 Juin 2021
There are probably multiple ways of doing this. It could probably be done with a bunch of reshaping and such, but I did it this way. I'm not sure which would be faster or less confusing.
arr_i1 = [111,112,113,114; ...
121,122,123,124];
arr_i2 = [211,212,213,214; ...
221,222,223,224];
arr_i3 = [311,312,313,314; ...
321,322,323,324];
arr_i = cat(3,arr_i1,arr_i2,arr_i3);
% [211,312,113,214;
% 221,322,123,224];
% calculate all 8 subscripts for each axis
xvec = repelem(1:4,2);
yvec = repmat(1:2,[1 4]);
zvec = repelem([2 3 1 2],2);
% convert to linear indices
idx = sub2ind(size(arr_i),yvec,xvec,zvec);
reshape(arr_i(idx),2,[])
Otherwise, trying to do something directly like
arr_i(:,1:4,[2 3 1 2])
Would give the intersection of the subscript ranges. Such a result would be a much larger set than intended, and the desired result would be its block diagonal.
3 commentaires
DGM
le 15 Juin 2021
If you don't have repelem, you can probably just use kron()
x = 1:4
repelem(x,2)
kron(x,[1 1])
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Matrices and Arrays dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!