Linear indexing over a subset of dimensions

15 views (last 30 days)
Linear indexing over the last two dimensions of a three dimensional array seems to work:
A = zeros([3 5 5]);
aIdx = [1 7 13 19 25];
aVal = [1 2 3 ; 4 5 6 ; 7 8 9 ; 10 11 12 ; 13 14 15].';
A(:,aIdx) = aVal;
This puts the triplets of aVal into the diagonal locations of the [5 5] part of A. That is
>> A(:,2,2)
ans =
4
5
6
I want to do the same thing but with first two dimension of an array. That is something like:
B = zeros([5 5 3]);
bIdx = [1 7 13 19 25];
bVal = [1 2 3 ; 4 5 6 ; 7 8 9 ; 10 11 12 ; 13 14 15];
B(bIdx,:) = bVal;
But this does not work. A couple of ways that do work are:
B([ bIdx bIdx + 25 bIdx + 50]) = bVal;
and
bLogIdx = false([5 5]);
bLogIdx(bIdx) = true;
B(repmat(bLogIdx, [1 1 3])) = bVal;
Both of these give
>> squeeze(B(2,2,:))
ans =
4
5
6
Is there a more clever way to accomplish this? More generally, is there a way to linear index over a subset of dimensions. That is use linear indexing in the y1,y2 dimensions of A(x1,x2,y1,y2,x3,x4)?
  1 Comment
Stephen23
Stephen23 on 9 Nov 2022
Edited: Stephen23 on 10 Nov 2022
"Is there a more clever way to accomplish this?"
RESHAPE or PERMUTE
"More generally, is there a way to linear index over a subset of dimensions."
By definition trailing dimensions collapse into the last subscript index. As Loren Shure wrote: "Indexing with fewer indices than dimensions If the final dimension i<N, the right-hand dimensions collapse into the final dimension."
If you think about it, linear indexing is really just a side-effect of this. An earlier discussion on this:

Sign in to comment.

Accepted Answer

Matt J
Matt J on 9 Nov 2022
Edited: Matt J on 9 Nov 2022
If you are indexing into the initial dimensions of an array, reshape will be cheaper than permute:
B = zeros([25 3]);
bIdx = [1 7 13 19 25];
bVal = [1 2 3 ; 4 5 6 ; 7 8 9 ; 10 11 12 ; 13 14 15];
B(bIdx,:) = bVal;
B=reshape(B,5,5,[])
B =
B(:,:,1) = 1 0 0 0 0 0 4 0 0 0 0 0 7 0 0 0 0 0 10 0 0 0 0 0 13 B(:,:,2) = 2 0 0 0 0 0 5 0 0 0 0 0 8 0 0 0 0 0 11 0 0 0 0 0 14 B(:,:,3) = 3 0 0 0 0 0 6 0 0 0 0 0 9 0 0 0 0 0 12 0 0 0 0 0 15
  1 Comment
James Bowen
James Bowen on 10 Nov 2022
In my application, B has the shape [5 5 3], but I suppose I can do two reshapes, one to convert it to [25 3] and one to convert it back.
Thanks!

Sign in to comment.

More Answers (1)

Chris
Chris on 9 Nov 2022
B = permute(A,[2,3,1]);

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!