Variable Indexing for N-dimension data

16 visualizzazioni (ultimi 30 giorni)
Solagens
Solagens il 19 Ott 2017
Commentato: Amr il 10 Ago 2022
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?

Risposta accettata

Matt J
Matt J il 19 Ott 2017
Modificato: Matt J il 19 Ott 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 Commenti
Jan
Jan il 19 Ott 2017
It works even with:
indV = {3, ':', 4}
James Tursa
James Tursa il 19 Ott 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!

Accedi per commentare.

Più risposte (1)

James Tursa
James Tursa il 19 Ott 2017
Modificato: James Tursa il 19 Ott 2017
The procedure for ':' functionality using the subsref ( ) function
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 Commento
Amr
Amr il 10 Ago 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.

Accedi per commentare.

Categorie

Scopri di più su Creating and Concatenating Matrices in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by