Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
multi-dimensional indexing

Subject: multi-dimensional indexing

From: Roel H

Date: 3 Feb, 2012 16:09:29

Message: 1 of 8

Is it possible to use a matrix as subscripts for a multi-dimensional array?
What I want is the following: I have a n-D array, say 'A', and a n-by-1 vector, say 'ind', containing the subscripts for each dimension. I want to be able to use A(ind) and get as output A(ind(1),ind(2),...,ind(n)). Is there an elegant way to do this? (preferably without knowing n in advance)

The best I've come with so far, is the following:
temp = num2cell(ind); %convert the vector to a cell
A(temp{:}) %this command somehow gives the contents of each cell as subscripts.
(this seems to be undocumented matlab behavior, but it is pretty neat though)

I would like to get rid of the intermediate step, since it involves creating extra variables I don't need.

Thanks in advance!

Kind regards,
Roel Helsen


(by the way, the same trick can be used to group multiple outputs of functions. i.e.
temp = cell(n,1); [temp{:}] = ndgrid(1:10); %this creates an n-dimensional grid with 10 elements in each dimension)

Subject: multi-dimensional indexing

From: Steven_Lord

Date: 3 Feb, 2012 18:12:45

Message: 2 of 8



"Roel H" <r.helsen@student.tudelft.nl> wrote in message
news:jgh0rp$po9$1@newscl01ah.mathworks.com...
> Is it possible to use a matrix as subscripts for a multi-dimensional
> array?
> What I want is the following: I have a n-D array, say 'A', and a n-by-1
> vector, say 'ind', containing the subscripts for each dimension. I want to
> be able to use A(ind) and get as output A(ind(1),ind(2),...,ind(n)). Is
> there an elegant way to do this? (preferably without knowing n in advance)
>
> The best I've come with so far, is the following:
> temp = num2cell(ind); %convert the vector to a cell
> A(temp{:}) %this command somehow gives the contents of each cell as
> subscripts.
> (this seems to be undocumented matlab behavior, but it is pretty neat
> though)

That's a comma-separated list.

http://www.mathworks.com/help/techdoc/matlab_prog/br2js35-1.html

This example is the "Function Call Arguments" example on that page, if you
think of subscripted indexing as a function call.

> I would like to get rid of the intermediate step, since it involves
> creating extra variables I don't need.

MATLAB treats indexing like:

y = A(onlyIndexArray);

as linear indexing (assuming onlyIndexArray is not a logical array; that
would be logical indexing) and retrieves the elements whose linear indices
are stored in onlyIndexArray. It does not treat the index array as a
subscript index because it has the same length as the number of dimensions
in A, as you hoped.

The approach I would use in this case is the comma-separated list approach,
though you may want to look at the implementation of the SUB2IND function
and write your own function, based on SUB2IND, that accepts a vector of
indices rather than individual vectors for the index in each dimension.

> Thanks in advance!
>
> Kind regards,
> Roel Helsen
>
>
> (by the way, the same trick can be used to group multiple outputs of
> functions. i.e.
> temp = cell(n,1); [temp{:}] = ndgrid(1:10); %this creates an
> n-dimensional grid with 10 elements in each dimension)

That's correct. That's the "Function Return Values" example on the page I
linked above.

--
Steve Lord
slord@mathworks.com
To contact Technical Support use the Contact Us link on
http://www.mathworks.com

Subject: multi-dimensional indexing

From: Matt J

Date: 4 Feb, 2012 11:03:15

Message: 3 of 8

"Roel H" wrote in message <jgh0rp$po9$1@newscl01ah.mathworks.com>...
>
> The best I've come with so far, is the following:
> temp = num2cell(ind); %convert the vector to a cell
> A(temp{:}) %this command somehow gives the contents of each cell as subscripts.
> (this seems to be undocumented matlab behavior, but it is pretty neat though)
>
> I would like to get rid of the intermediate step, since it involves creating extra variables I don't need.
=====================

Just for fun, here's a way of doing it using ndSparse objects,

 A(ndSparse.build(ind(:).',true))

But it's only value is that it offers a 1-line syntax. There is no CPU efficiency in it.
The ndSparse class is available here,

http://www.mathworks.com/matlabcentral/fileexchange/29832-n-dimensional-sparse-arrays

Subject: multi-dimensional indexing

From: Bruno Luong

Date: 4 Feb, 2012 11:23:32

Message: 4 of 8

"Steven_Lord" <slord@mathworks.com> wrote in message

> The approach I would use in this case is the comma-separated list approach,
> though you may want to look at the implementation of the SUB2IND function
> and write your own function, based on SUB2IND, that accepts a vector of
> indices rather than individual vectors for the index in each dimension.
>

That won't really solve the problem of avoid using comma-list, since SUB2IND again requires comma separated-list as input argument.

One way is doing something like this:

A = rand(3,4,5)
ind = [2 1 3]

s = size(A);
A ( 1+(ind-1)*cumprod([1 s(1:end-1)])' )

 % Bruno

Subject: multi-dimensional indexing

From: Sadik

Date: 5 Feb, 2012 01:13:15

Message: 5 of 8

Single line solution with no additional variables.
Elegant? Maybe...

eval(sprintf(['A(' repmat('ind(%d),',1,length(ind)-1) 'ind(%d))'],1:length(ind)))

Subject: multi-dimensional indexing

From: Matt J

Date: 5 Feb, 2012 14:09:10

Message: 6 of 8

"Roel H" wrote in message <jgh0rp$po9$1@newscl01ah.mathworks.com>...
>
> I would like to get rid of the intermediate step, since it involves creating extra variables I don't need.
=============

Incidentally, why do you need 'ind' as an n-by-1 vector in the first place? If you were to generate it as a cell array from the get-go, you would never have to perform the num2cell conversion.

For that matter, do you really need to be generating subscripts into A()?
Most MATLAB functions that analyze the contents of arrays return either a logical or linear index I, which can be used to index into A in single argument form: A(I).

To obtain subscript vectors like 'ind', you normally have to obtain logical/linear indices first and then transform them. So, if you have a subscript vector ind on your hands, chances are you've done a lot of unneeded/inefficient processing to get it.

Subject: multi-dimensional indexing

From: Roel H

Date: 7 Feb, 2012 11:06:10

Message: 7 of 8

"Matt J" wrote in message <jgm2i6$ej2$1@newscl01ah.mathworks.com>...
> "Roel H" wrote in message <jgh0rp$po9$1@newscl01ah.mathworks.com>...
> >
> > I would like to get rid of the intermediate step, since it involves creating extra variables I don't need.
> =============
>
> Incidentally, why do you need 'ind' as an n-by-1 vector in the first place? If you were to generate it as a cell array from the get-go, you would never have to perform the num2cell conversion.
>
> For that matter, do you really need to be generating subscripts into A()?
> Most MATLAB functions that analyze the contents of arrays return either a logical or linear index I, which can be used to index into A in single argument form: A(I).
>
> To obtain subscript vectors like 'ind', you normally have to obtain logical/linear indices first and then transform them. So, if you have a subscript vector ind on your hands, chances are you've done a lot of unneeded/inefficient processing to get it.


Hi Matt,

I'm working with a multidimensional grid, in which I traverse through cells. To keep track of the current cell I use the subscripts in each dimension. After the computations in the current cell, the algorithm needs to advance to neighboring cells. With subscripts, this is pretty straightforward, just do+/- 1 in the wanted dimension. In linear indices it is more complicated to get the index of a neighboring cell (which probably would involve transforming back and forth between subscripts and linear indices).
Also the subscript code is more readable than linear indexing code.

Subject: multi-dimensional indexing

From: Matt J

Date: 7 Feb, 2012 17:36:11

Message: 8 of 8

"Roel H" wrote in message <jgr0j2$f8o$1@newscl01ah.mathworks.com>...
>
> I'm working with a multidimensional grid, in which I traverse through cells. To keep track of the current cell I use the subscripts in each dimension. After the computations in the current cell, the algorithm needs to advance to neighboring cells. With subscripts, this is pretty straightforward, just do+/- 1 in the wanted dimension. In linear indices it is more complicated to get the index of a neighboring cell (which probably would involve transforming back and forth between subscripts and linear indices).
> Also the subscript code is more readable than linear indexing code.
================

I can agree with the concerns about code readability. However, if you start with subscripts, the need to transform to linear indices will be inevitable, especially if you are looking for a dimension-independent indexing scheme. If speed is an issue for you, (and it sounds like you might be dealing with an already painfully slow for-loop through the grid elements) you ought to seriously consider reframing things in linear indexing terms.


It isn't that hard to do jump between grid neighbors using linear indexing. In an MxN grid, you move up/down by adding +/-1 and you move right/left by adding +/-N
The desired increments are easy enough to pre-compute.

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us