How to index one array by assigned vector in certain dimension
5 views (last 30 days)
Show older comments
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 Comments
Accepted Answer
DGM
on 15 Jun 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 Comments
DGM
on 15 Jun 2021
If you don't have repelem, you can probably just use kron()
x = 1:4
repelem(x,2)
kron(x,[1 1])
More Answers (0)
See Also
Categories
Find more on Matrices and Arrays in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!