基于Matlab的二维数组索引

基于Matlab的二维数组索引,matlab,matrix,indexing,2d,Matlab,Matrix,Indexing,2d,我有一个2D矩阵,比如M=0(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; 或 但这两者都没有产生预期的结果 我是否可以使用一些语法糖分来实现这一点,或者我应该恢复循环?这几乎不微妙,也不比循环好,我不认为,但是: [

我有一个2D矩阵,比如M=0(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;

但这两者都没有产生预期的结果


我是否可以使用一些语法糖分来实现这一点,或者我应该恢复循环?

这几乎不微妙,也不比循环好,我不认为,但是:

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

享受吧。

这并不微妙,也不比循环好,我不认为,但是:

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

试试这个:

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

v = [1;2;3;4;5;6;5;4;3;2];
n = 10;
M = repmat((1:n)', 1, numel(v)) > repmat(v', n, 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来说会消耗内存。我会坚持循环。

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

既然你在寻找语法上的糖分,这里有一种深奥的方法

假设
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

既然你在寻找语法上的甜点,这里有一种深奥的方法

假设
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

我添加了两个选项,包括一个使用线性索引和累积和非常快(比这些更快)的选项。如果您想直接针对这些进行速度测试,我很想知道它的运行情况。另外,在非循环测试中,请注意,
M
将是一个逻辑矩阵,除非您将其转换为双精度,否则会使它们变慢。尝试了您的方法(使用cumsum),对于N=10000,需要0.852秒,使您的方法成为所有方法中最快的,大约是loop one速度的两倍我添加了两个选项,包括一个使用线性索引和cumsum的非常快(比这些快)的选项。如果您想直接针对这些进行速度测试,我很想知道它的运行情况。另外,在非循环测试中,请注意,
M
将是一个逻辑矩阵,除非您将其转换为双精度,否则会使它们变慢。尝试了您的方法(使用cumsum),对于N=10000,需要0.852秒,使您的方法成为所有方法中最快的,速度大约是loop One的两倍,在风格和独创性方面有许多优点。感谢大家的回答,这是一次有益的学习经历。我将学会并行思考…许多关于风格和创造力的观点。感谢大家的回答,这是一次有益的学习经历。我将学会并行思考。。。