Indexing of unknown dimensional matrix
matlab, matrix-indexing, multidimensional-array
Solution
For the general case where `J` can be any length (which I assume always matches the number of dimensions in `M`), there are a couple options you have:
You can place each entry of `J` in a cell of a cell array using the `num2cell` function, then create a comma-separated list from this cell array using the colon operator:
cellJ = num2cell(J);
output = M(cellJ{:});
You can sidestep the `sub2ind` function and compute the linear index yourself with a little bit of math:
sizeM = size(M);
index = cumprod([1 sizeM(1:end-1)]) * (J(:) - [0; ones(numel(J)-1, 1)]);
output = M(index);
Problem
I have a non-fixed dimensional matrix M, from which I want to access a single element. The element's indices are contained in a vector J. So for example: ``` M = rand(6,4,8,2); J = [5 2 7 1]; output = M(5,2,7,1) ``` This time M has 4 dimensions, but this is not known in advance. This is dependent on the setup of the algorithm I'm writing. It could likewise be that ``` M = rand(6,4); J = [3 1]; output = M(3,1) ``` so I can't simply use ``` output=M(J(1),J(2)) ``` I was thinking of using sub2ind, but this also needs its variables comma separated.. @gnovice this works, but I intend to use this kind of element extraction from the matrix `M` quite a lot. So if I have to create a temporary variable `cellJ` every time I access `M`, wouldn't this tremendously slow down the computation?? I could also write a separate function ``` function x= getM(M,J) x=M(J(1),J(2)); % M doesn't change in this function, so no mem copy needed = passed by reference end ``` and adapt this for different configurations of the algorithm. This is of course a speed vs flexibility consideration which I hadn't included in my question.. BUT: this is only available for getting the element, for setting there is no other way than actually using the indices (and preferably the linear index). I still think sub2ind is an option. The final result I had intended was something like: ``` function idx = getLinearIdx(J, size_M) idx = ... end ``` RESULTS: ``` function lin_idx = Lidx_ml( J, M )%#eml %LIDX_ML converts an array of indices J for a multidimensional array M to %linear indices, directly useable on M % % INPUT % J NxP matrix containing P sets of N indices % M A example matrix, with same size as on which the indices in J % will be applicable. % % OUTPUT % lin_idx Px1 array of linear indices % % method 1 %lin_idx = zeros(size(J,2),1); %for ii = 1:size(J,2) % cellJ = num2cell(J(:,ii)); % lin_idx(ii) = sub2ind(size(M),cellJ{:}); %end % method 2 sizeM = size(M); J(2:end,:) = J(2:end,:)-1; lin_idx = cumprod([1 sizeM(1:end-1)])*J; end ``` method 2 is 20 (small number of index sets (`=P`) to convert) to 80 (large number of index sets (`=P`)) times faster than method 1. easy choice