我有一个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;
但这些都不会产生预期的结果。
我可以使用一些语法糖来实现这个目标,还是应该恢复循环?
答案 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);