Matlab索引到二维数组使用

时间:2012-06-13 20:45:10

标签: matlab matrix indexing 2d

我有一个2D矩阵,比如说M =零(10,10);

我有另一个列矩阵,V = [1; 2; 3; 4; 5; 6; 5; 4; 3; 2];

我希望能够为所有j设置M(i,j)= 1> = V(i)

我知道我可以在循环中执行此操作

for i=1:10
   M(i,V(i):10) = 1;
end

但似乎可以使用某种形式的Matlab索引来避免使用循环。例如:

M(:,V:10)=1;

M(:,V(:):10)=1;

但这些都不会产生预期的结果。

我可以使用一些语法糖来实现这个目标,还是应该恢复循环?

4 个答案:

答案 0 :(得分:2)

它几乎不是微妙的,也不是一个我不认为的循环,但是:

[J,I] = meshgrid(1:10,1:10); 
V = [1;2;3;4;5;6;5;4;3;2];
M = J>V(I);

享受。

答案 1 :(得分:2)

既然你正在寻找语法糖,这里有一种深奥的方法。 :)

假设V的长度是所需矩阵M中两个维度的大小,首先创建一个相同大小的单位矩阵,然后适当地索引并取cumsum:< / p>

V = [1;2;3;4;5;6;5;4;3;2]; #% 10x1 vector
E = eye(length(V), length(V)); #%10x10 identity matrix
M = cumsum(E(V,:),2)

M =

     1     1     1     1     1     1     1     1     1     1
     0     1     1     1     1     1     1     1     1     1
     0     0     1     1     1     1     1     1     1     1
     0     0     0     1     1     1     1     1     1     1
     0     0     0     0     1     1     1     1     1     1
     0     0     0     0     0     1     1     1     1     1
     0     0     0     0     1     1     1     1     1     1
     0     0     0     1     1     1     1     1     1     1
     0     0     1     1     1     1     1     1     1     1
     0     1     1     1     1     1     1     1     1     1

好的,现在:不那么有趣,但(在我的机器上)比迄今为止测试过的任何其他选项都快:

n=10000;
V = randi(n-1, 1, n); #% as in @KevinRatelle's answer (but not transposed)

tic;
Vlinear = reshape(V + (0:n-1)*n, 1, []); #% find linear indices of first "ones"
M = zeros(n);
M(Vlinear)=1;
M=cumsum(M);
toc

答案 2 :(得分:1)

我尝试了循环方法和'meshgrid'方法。我想知道计算大型矩阵的时间(因为matlab中的循环问题通常是时间)。

首先,我优化了代码,如下所示:

V = V*ones(1,n);
N = ones(1,n)'*(1:n);
M = N>=V;

实际上,N是一个网格网格,但这样做似乎更快......

我试过了:

n = 10000;
V = randi(n-1,1,n)';

tic;
M = zeros(n);
for i=1:n
    M(i,V(i):n) = 1;
end
toc

tic;
[J,I] = meshgrid(1:n,1:n);
M = J>=V(I);
toc

tic;
V = V*ones(1,n);
N = ones(1,n)'*(1:n);
M = N>=V;
toc

结果是:

Elapsed time is 1.726872 seconds.
Elapsed time is 5.206657 seconds.
Elapsed time is 1.548600 seconds.

但是使用矩阵而不是循环的方法对于大n来说是内存消耗。我会个人坚持循环。

答案 3 :(得分:0)

试试这个:

v = [1;2;3;4;5;6;5;4;3;2];
n = 10;
M = repmat((1:n)', 1, numel(v)) > repmat(v', n, 1);