How better to build a matrix whose elements are precisely their indexes or index functions in Matlab?

What is the best way to construct a matrix whose elements are precisely their indices in Matlab?


EDIT: There is an answer to this question is applicable to how to build a matrix whose elements are functions of their indices. So I added it to the title question.


The format can be either a matrix with vectors as elements, or two molds, each of which stores one index.

In the end I would like to create a matrix whose elements are functions of their indices. Therefore, it is an effective method for this (but possibly different). Any comments on the effectiveness of welcome.

Matrix size tends to be large (the size of the squares of hundreds at least) for my application. As a result, techniques that use their own Matlab functions are likely to be much better than for cycles / while.

For example, for the size of the matrix [2 2] I would like to make any

IND = [1 1] [1 2] [2 1] [2 2] 

or

 X = 1 1 2 2 Y = 1 2 1 2 

In the end I hope to do something like

 matrixIneed = arrayfun(@(s)..., IND) 

where s - 2 or the vector size

 matrixIneed = arrayfun(@(i,j)..., X,Y) 

Last preferable.


EDIT: Note on the accepted answer.

I took Andrew answer, because it is intuitive for me, and the code seems to be fast (at least for me).

If you've ever answered this question on Google, you're probably worried about how I do it. (Otherwise, if not the best practice, anyone can think of a double loop to complete the task.)

If so, you are advised to view the Andrew comment about the function reshape() , and Rody response performance meshgrid() and loops .

Nevertheless, the decision to pass to meshgrid() is a useful model for studying the function of meshgrid() . This is useful in many other Matlab functions.

Jigg repmat() can help you.

+6
source share
5 answers

Look at the function ind2sub , sub2ind and reshape . They are useful for converting indexes and indexes on multidimensional arrays.

In your case, it looks like you want it. (I think you need a "Federation" instead of "index". The Matlab uses "index" to refer to "linear" element of the index array when viewed as a one-dimensional vector, and the "Federation" means the position along each dimension of a multidimensional array.)

 sz = [3 3]; % Size of your matrix n = prod(sz); % Total number of elements in matrix [X, Y] = ind2sub(sz, 1:n); % Subscripts, returned as vectors X = reshape(X, sz); % Reshape the subscript vectors to match your matrix Y = reshape(Y, sz); sz, sz = [3 3]; % Size of your matrix n = prod(sz); % Total number of elements in matrix [X, Y] = ind2sub(sz, 1:n); % Subscripts, returned as vectors X = reshape(X, sz); % Reshape the subscript vectors to match your matrix Y = reshape(Y, sz); ; sz = [3 3]; % Size of your matrix n = prod(sz); % Total number of elements in matrix [X, Y] = ind2sub(sz, 1:n); % Subscripts, returned as vectors X = reshape(X, sz); % Reshape the subscript vectors to match your matrix Y = reshape(Y, sz); matrix sz = [3 3]; % Size of your matrix n = prod(sz); % Total number of elements in matrix [X, Y] = ind2sub(sz, 1:n); % Subscripts, returned as vectors X = reshape(X, sz); % Reshape the subscript vectors to match your matrix Y = reshape(Y, sz); 

Approach meshgrid who gave @thewaywewalk, will give the same result, but I think that the approach ind2sub in this case a little read because it is formulated in terms of indexing the array, which is your area of concern. And it will generalize to work with cuts or arbitrary subset of arrays that meshgrid are not well matched and ind2sub for efficient operations going in the other direction. (In any case it is necessary to study meshgrid , it appears in other places.)

+3
source

Use meshgrid or ndgrid :

 % example matrix Matrix = magic(5) [nm] = 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 in your 2D-case is that Y and X are reversed - use it to meet your needs.)

From the documentation :

[X,Y] = meshgrid(xgv,ygv) xgv, ygv) replicates mesh vectors xgv and ygv to create a full mesh. This grid output presented coordinate arrays X and Y . The output coordinate arrays X and Y contain copy vectors grid xgv and ygv respectively. Dimensions output arrays are determined by the length of the grid vectors. For reticulated vectors xgv and ygv lengths M and N , respectively, X and Y will have N rows and columns of M .

Well, not so much to explain, meshgrid used to create a regular grid of two vectors, typically the values of " X " and " Y ", to get the appropriate input data for 3D / color chart z -data. If you think that your X and Y are 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 
+7
source

Get used to ndgrid . Avoid meshgrid , with the exception of support for graphics and graphics operations.

Conclusion ndgrid , expressed in terms of rows, columns, etc., has a natural semenatiki for matrix operations MATLAB than coordinates x, y, returned 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 ( >> 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 

Procedure ordering MATLAB - this line as a first measurement column - as a second, then higher. ndgrid should this agreement with the ordering of its inputs and outputs. For reference, an equivalent command meshgrid [JJ,II] = meshgrid(1:ncols,1:nrows); .

An excellent illustration of why you should stick to the rows, columns reference system is converted into linear codes: sub2ind . Function sub2ind expected the index are arranged in the same way as outputs ndgrid :

 >> inds = sub2ind([nrows ncols],II,JJ) inds = 1 4 7 10 2 5 8 11 3 6 9 12 ], II, JJ) >> inds = sub2ind([nrows ncols],II,JJ) inds = 1 4 7 10 2 5 8 11 3 6 9 12 

The wording of this command requires little thought, if you always think in terms of rows, columns (index) rather than x, y.

Again use ndgrid .

+4
source

Since you have indicated that you want to run the function of the indices, it is definitely the simplest and probably the fastest to just make a double loop:

 matrixIneed = zeros(n,m); for ii = 1:n for jj = 1:m matrixIneed(ii,jj) = myFunction(ii,jj); end end ; matrixIneed = zeros(n,m); for ii = 1:n for jj = 1:m matrixIneed(ii,jj) = myFunction(ii,jj); end end (ii, jj); matrixIneed = zeros(n,m); for ii = 1:n for jj = 1:m matrixIneed(ii,jj) = myFunction(ii,jj); end end 

Depending on the bit myFunction is likely to be faster than arrayfun , and, of course, much smaller than the memory meshgrid , if n and m are relatively large; See. also this related question .

If you are using MATLAB R2009 or later, and your function is built-in or can be built only with the use of built-in modules, the execution of these cycles against meshgrid be comparable, but meshgrid will consume more memory (O (N²) memory instead O (1) for a cycle). As always, profiling is a key, but double loop, is probably the best one-stop solution.

Sometimes it also helps:

 matrixIneed = zeros(n*m,1); for ij = 1:n*m %// use this when possible matrixIneed(ij) = myFunction(ij); %// otherwise, use this matrixIneed(ij) = myFunction(mod(ij-1,n)+1, floor((ij-1)/n)+1); end reshape(matrixIneed,n,m); ); matrixIneed = zeros(n*m,1); for ij = 1:n*m %// use this when possible matrixIneed(ij) = myFunction(ij); %// otherwise, use this matrixIneed(ij) = myFunction(mod(ij-1,n)+1, floor((ij-1)/n)+1); end reshape(matrixIneed,n,m); (ij- matrixIneed = zeros(n*m,1); for ij = 1:n*m %// use this when possible matrixIneed(ij) = myFunction(ij); %// otherwise, use this matrixIneed(ij) = myFunction(mod(ij-1,n)+1, floor((ij-1)/n)+1); end reshape(matrixIneed,n,m); ij- matrixIneed = zeros(n*m,1); for ij = 1:n*m %// use this when possible matrixIneed(ij) = myFunction(ij); %// otherwise, use this matrixIneed(ij) = myFunction(mod(ij-1,n)+1, floor((ij-1)/n)+1); end reshape(matrixIneed,n,m); 
+1
source

Another embodiment using repmat (since the content of these matrices is redundant):

 X=repmat((1:size(YourMatrix, 2))', 1, size(YourMatrix, 1)); Y=repmat(1:size(YourMatrix, 1), size(YourMatrix, 2), 1); 
0
source

All Articles