如何最好地构造一个矩阵,其元素正是它们在Matlab中索引的索引或函数?

时间:2014-03-17 15:45:10

标签: matlab matrix

在Matlab中构造一个元素正好是它们的索引的矩阵的最佳方法是什么?


编辑:此问题的现有答案适用于如何构建其元素为其索引的函数的矩阵。所以我把它添加到问题标题中。


格式可以是带矢量作为元素的矩阵,也可以是两个矩阵,每个矩阵存储一个索引。

最后,我想创建一个矩阵,其元素是其索引的函数。因此非常感谢一种有效的方法(但可能不同)。对效率的任何评论都受到欢迎。

对于我的应用程序,矩阵的大小往往很大(最小数百平方)。因此,利用原生Matlab函数的方法可能比for / while循环要好得多。

例如,对于大小为[2 2]的矩阵,我想制作

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

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

最后,我希望做一些像

这样的事情
matrixIneed = arrayfun(@(s)..., IND)

其中s是大小为2的向量,或

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

后者是首选。


编辑:关于已接受答案的说明。

我接受了安德鲁的答案,因为这对我来说很直观,代码似乎很快(至少对我来说)。

如果你曾经谷歌这个问题的答案,你可能会像我一样关注性能。 (否则,如果不是最佳实践,任何人都可以考虑使用双循环来完成任务。)

如果是这样,我们鼓励您检查Andrew对reshape()函数和Rody关于meshgrid()loops的效果的答案的评论。

尽管如此,使用meshgrid()的thewaywewalk解决方案是学习meshgrid()功能的有用示例。它在许多其他Matlab函数中都很有用。

Jigg的repmat()解决方案也可以为您提供帮助。

5 个答案:

答案 0 :(得分:7)

使用meshgridndgrid

% 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) 

(2D情况的区别在于,YX已交换。 - 根据您的需要使用它。)

来自documentation

  

[X,Y] = meshgrid(xgv,ygv)将网格向量xgvygv复制到   产生一个完整的网格。该网格由输出坐标表示   数组XY。输出坐标数组XY包含   分别为网格向量xgvygv的副本。的大小   输出数组由网格矢量的长度决定。对于   网格向量xgvygv分别为MNXY将   有N行和M列。

嗯,没有更多的解释,meshgrid用于从两个向量创建一个常规网格,通常是“x”和“y”值,以获得合适的输入z - 数据的3D /颜色编码图的数据。如果您认为xy是向量[1 2 3 ... n],那么它就完全符合您的要求。

返回:

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

答案 1 :(得分:4)

习惯ndgrid。避免使用meshgrid,但支持绘图和图形操作。

ndgrid的输出,以行,列等表示,对于MATLAB矩阵运算具有比由meshgrid返回的x,y坐标更自然的精确度。

>> 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的维度排序是行作为第一维,列作为第二维,然后是更高维。 ndgrid遵循此约定,其输入和输出的顺序。作为参考,等效的meshgrid命令是[JJ,II] = meshgrid(1:ncols,1:nrows);

为什么你应该坚持行,列的心态转换为线性索引:sub2ind的一个很好的例子。函数sub2ind期望订阅的顺序与ndgrid

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

如果你总是考虑行,列(下标)而不是x,y,那么制定这个命令几乎不需要考虑。

再次使用ndgrid

答案 2 :(得分:3)

查看ind2subsub2indreshape函数。它们对于转换多维数组上的下标和索引非常有用。

在你的情况下,看起来你想要这个。 (我认为你想要“下标”而不是“索引”。当将数组视为一维向量时,Matlab使用“index”表示元素的“线性”索引,而“下标”表示每个元素的位置多维数组的维度。)

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);

@thewaywewalk提供的meshgrid方法将产生相同的输出,但我认为ind2sub方法在这种情况下更具可读性,因为它的数据索引方面的措辞,这是你的问题域。它将概括为处理切片或数组的任意子集,meshgrid不会,并且与ind2sub很好地对应,以便以另一种方式进行有效的操作。 (无论如何,它值得学习meshgrid;它会在其他位置弹出。)

答案 3 :(得分:1)

既然你已经表明你想在索引上运行一个函数,那么它是最简单的,也可能是最快的只做一个双循环:

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

取决于myFunction,这可能比arrayfun更快,当meshgridn时,内存密集度明显低于m比较大;另见this related question

如果您正在运行MATLAB R2009或更高版本,并且您的函数是内置函数或只能使用内置函数构建,则这些循环与meshgrid的执行时间将具有可比性,但{ {1}}将消耗更多的内存(O(N²)内存,而不是O(1)用于循环)。与往常一样,分析是关键,但双循环可能是最好的全面解决方案。

有时候,这也会有所帮助:

meshgrid

答案 4 :(得分:0)

使用repmat的另一个选项(因为这些矩阵的内容是多余的):

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