简体   繁体   English

Matlab使用2D数组索引

[英]Matlab indexing into 2D array using

I have a 2D matrix, say M=zeros(10,10); 我有一个2D矩阵,比如说M = zeros(10,10);

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

I would like to be able to set M(i,j) = 1 for all j >= V(i) 我希望能够为所有j> = V(i)设置M(i,j)= 1

I know I can do this in a loop 我知道我可以循环执行此操作

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

but it seems that it would be possible to use some form of Matlab indexing to avoid using a loop. 但是似乎可以使用某种形式的Matlab索引来避免使用循环。 For example something like : 例如:

M(:,V:10)=1;

or 要么

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

but neither of these produces the expected result. 但是这些都不产生预期的结果。

Is there some syntactic sugar I can use to achieve this or should I revert to looping? 是否可以使用一些语法糖来实现此目的,还是应该恢复为循环播放?

Its hardly subtle and not really better than a loop I don't think but: 它几乎没有什么微妙之处,而且还没有比我认为的循环更好的地方:

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

Enjoy. 请享用。

Since you're looking for syntactic sugar, here's a sort of esoteric way of doing it. 由于您正在寻找语法糖,因此这是一种深奥的方法。 :) :)

Assuming the length of V is the size of both dimensions in the desired matrix M , first create an identity matrix of the same size, then index appropriately and take cumsum : 假设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

Ok, now: less fun, but (on my machine) faster than any of the other options that have been tested so far: 好吧,现在:娱乐性降低了,但是(在我的机器上)比到目前为止已经测试过的任何其他选项都快:

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

I tried the loop method, and the 'meshgrid' method. 我尝试了循环方法和“网格”方法。 I was wondering about the time to compute for large matrices (since the issue with loops in matlab is usually the time). 我想知道大型矩阵的计算时间(因为matlab中的循环问题通常是时间)。

First, I optimised the code to look like this : 首先,我优化了代码,使其看起来像这样:

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

Actually, N is a meshgrid, but it seems way faster to do it this way... 实际上,N是一个网格物体,但是用这种方法似乎更快。

I tried this : 我尝试了这个:

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

And results were : 结果是:

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

But methods using matrices instead of loops are memory consuming for large n. 但是,使用矩阵而不是循环的方法会消耗大量n的内存。 I would personnaly stick to the loop. 我会个性地坚持下去。

try this: 尝试这个:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM