How to index one array by assigned vector in certain dimension

5 vues (au cours des 30 derniers jours)
Warren Chuo
Warren Chuo le 14 Juin 2021
Commenté : Warren Chuo le 21 Juin 2021
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!!

Réponse acceptée

DGM
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,[])
ans = 2×4
211 312 113 214 221 322 123 224
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
DGM le 15 Juin 2021
If you don't have repelem, you can probably just use kron()
x = 1:4
x = 1×4
1 2 3 4
repelem(x,2)
ans = 1×8
1 1 2 2 3 3 4 4
kron(x,[1 1])
ans = 1×8
1 1 2 2 3 3 4 4
Warren Chuo
Warren Chuo le 21 Juin 2021
Thank you for suggesting 'kron'.
I'll try this tensor formula later.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Matrices and Arrays dans Help Center et File Exchange

Produits


Version

R2010b

Community Treasure Hunt

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

Start Hunting!

Translated by