What is the best way to construct a matrix whose elements are exactly their indices in Matlab?
EDIT: The existing answers to this question is applicable to how to construct a matrix whose elements are functions of their indices. So I added that to the question title.
The format can be either a matrix with vectors as elements, or as two matrices each storing one index.
At the end, I would like to create a matrix whose elements are functions of their indices. So an efficient method for that (but possibly different) is very much appreciated. Any comment on efficiency is welcomed.
The size of matrices tends to be large (dimension of hundreds squared at the minimum) for my applications. As a result, methods that take advantage of native Matlab functions are probably much better than for/while loops.
For example, for a matrix of size [2 2], I would like to make either
IND =
[1 1] [1 2]
[2 1] [2 2]
or
X =
1 1
2 2
Y =
1 2
1 2
At the end, I am hoping to do something like
matrixIneed = arrayfun(@(s)..., IND)
where s is a vector of size 2, or
matrixIneed = arrayfun(@(i,j)..., X,Y)
The latter is preferred.
EDIT: A note about accepted answer.
I have accepted Andrew's answer because it is intuitive to me and the code seems quick (at least to me).
If you ever Google an answer to this question, you are likely concerned about performance like I do. (Otherwise if not for best practice, anyone can think of a double loop to accomplish the task.)
If so, you are encouraged to examine Andrew's comment on the reshape()
function and Rody's answer about the performance of meshgrid()
and loops
.
Nevertheless, thewaywewalk's solution with meshgrid()
is a helpful example to learn the meshgrid()
function. And it is useful in many other Matlab functions.
Jigg's repmat()
solution may help you too.
use meshgrid
or ndgrid
:
% example matrix
Matrix = magic(5)
[n m] = size(Matrix)
% or define the dimensions directly
n = 5;
m = 5;
[X,Y] = meshgrid(1:n,1:m) %\\ [Y,X] = ndgrid(1:n,1:m)
(the difference for your 2D case is that, Y
and X
are swapped. - use it according to your needs.)
From the documentation:
[X,Y] = meshgrid(xgv,ygv)
replicates the grid vectorsxgv
andygv
to produce a full grid. This grid is represented by the output coordinate arraysX
andY
. The output coordinate arraysX
andY
contain copies of the grid vectorsxgv
andygv
respectively. The sizes of the output arrays are determined by the length of the grid vectors. For grid vectorsxgv
andygv
of lengthM
andN
respectively,X
andY
will haveN
rows andM
columns.
Well there is not much more to explain, meshgrid
is used to create a regular grid from two vectors, usually "x
" and "y
" values in order to obtain suitable input data for a 3D/color-coded plot of z
-data. If you assume your x
and y
to be the vectors [1 2 3 ... n]
it does exactly what you need.
returns:
X =
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Y =
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
Get used to ndgrid
. Avoid meshgrid
, except in support of plotting and graphics operations.
The output of ndgrid
, expressed in terms of rows, columns, etc., has more natural semenatics for MATLAB matrix operations than x,y coordinates, as returned by meshgrid
.
>> nrows = 3;
>> ncols = 4;
>> [II,JJ] = ndgrid(1:nrows,1:ncols)
II =
1 1 1 1
2 2 2 2
3 3 3 3
JJ =
1 2 3 4
1 2 3 4
1 2 3 4
MATLAB's dimension ordering is rows as first dimension, columns as second, then higher dimensions. ndgrid
follows this convention with the ordering of its inputs and outputs. For reference, the equivalent meshgrid
command is [JJ,II] = meshgrid(1:ncols,1:nrows);
.
An excellent illustration of why you should stick to the rows,columns frame of mind is converting to linear indexes: sub2ind
. The function sub2ind
expects subscripts ordered in the same way as the outputs of ndgrid
:
>> inds = sub2ind([nrows ncols],II,JJ)
inds =
1 4 7 10
2 5 8 11
3 6 9 12
Formulating this command requires little thought if you are always thinking in terms of rows,columns (subscripts) rather than x,y.
Again, use ndgrid
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With