0

我有一个二维矩阵,比如 M=zeros(10,10);

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

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

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

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

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

M(:,V:10)=1;

或者

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

但这些都没有产生预期的结果。

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

4

4 回答 4

2

它几乎不微妙,并不比我不认为的循环更好,但是:

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

享受。

于 2012-06-13T20:55:47.200 回答
2

由于您正在寻找语法糖,因此这是一种深奥的方法。:)

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

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
于 2012-06-14T01:49:47.287 回答
1

我尝试了循环方法和“网格”方法。我想知道计算大型矩阵的时间(因为 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 会消耗内存。我会亲自坚持循环。

于 2012-06-14T01:19:08.250 回答
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);
于 2012-06-13T21:53:57.353 回答