Variable Indexing for N-dimension data
14 views (last 30 days)
Show older comments
I am using Matlab R2013b. I've been struggling with Matlab indexing being a bottleneck in my functions. The issue keeps coming up. How can I tinker with Matlab's 'subsindex' function?
Overview of my problem: ------------------------------- I have a function that takes in a matrix of N-dimension. The function does not know the dimensions of the matrix beforehand. After some loops and things, the function must access data in the matrix. There's another function I have that creates a variable based on the number of inputs, essentially creating the same problem. I currently use 'sub2ind' to access or place values properly, but the 'sub2ind' function is slow. So slow it is a serious issue.
What I would Ideally like to do: ------------------------------------------ Let's say we have matrix A of N dimension. I have an index variable, indV. I want to be able to write A({indV}) without Matlab screaming an error at me about 'subsindex' not being defined for class 'cell'.
For example, if size(A) = (5, 4, 6) and indV=[1, 2, 3] then --> A({indV}) would be interpreted the same as A(1, 2, 3) resulting in one value. As you know matlab would produce three values if I wrote A(indV) which is seen as A(1:3). It would be a dream come true if I have the same A matrix and indV=[1 2] now and matlab would interpret A({indV},:) as A(1,2,:) resulting in 6 values instead of an error. What if indV1=3 and indV2=4 so A({indV1}, :, {indV2}) would be interpreted as A(3,:,4) producing 4 values, wouldn't that be nice. Even nicer would be with indV={2:4, 1} A({indV},:) would be seen as A(2:4, 1, :). You get the point.
I am hoping there is a way to modify/add to the 'subsindex' function to accomplish this resulting in a faster method than the 'sub2ind' function. Or maybe there is already functionality in Matlab that I am not aware of?
Any ideas/suggestions?
0 Comments
Accepted Answer
Matt J
on 19 Oct 2017
Edited: Matt J
on 19 Oct 2017
Or maybe there is already functionality in Matlab that I am not aware of?
I think so. If you have indV={1,2,3}, then A(indV{:}) is equivalent to A(1,2,3). See Comma Separated Lists.
3 Comments
James Tursa
on 19 Oct 2017
Of course, using this directly works. For some reason I was fixated on the idea that calling subsref directly was needed when ':' was present, hence my overly complicated answer below!
More Answers (1)
James Tursa
on 19 Oct 2017
Edited: James Tursa
on 19 Oct 2017
indV = your cell array of indexing, which could include ':' entries
S.type = '()';
S.subs = indV;
result = subsref(A,S);
If you want to allow for indexing like {2,3} to behave like {2,3,':'} where ':' is automatically used for all unspecified trailing dimensions, then you could do this instead:
S.subs = [indV repmat({':'},1,numel(size(A))-numel(indV))];
E.g.,
>> A = reshape(1:24,2,3,4)
A(:,:,1) =
1 3 5
2 4 6
A(:,:,2) =
7 9 11
8 10 12
A(:,:,3) =
13 15 17
14 16 18
A(:,:,4) =
19 21 23
20 22 24
>> indV = {':',2:3,':'}
indV =
':' [1x2 double] ':'
>> S.type = '()'
S =
type: '()'
>> S.subs = indV
S =
type: '()'
subs: {':' [2 3] ':'}
>> result = subsref(A,S)
result(:,:,1) =
3 5
4 6
result(:,:,2) =
9 11
10 12
result(:,:,3) =
15 17
16 18
result(:,:,4) =
21 23
22 24
1 Comment
Amr
on 10 Aug 2022
This is awsome. I have been using MATLAB for more than 10 years, and I did not know about this subsref() function. Thanks for sharing.
See Also
Categories
Find more on Creating and Concatenating Matrices in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!