0

私は2D行列を持っています、例えば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

loopメソッドと'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が大きい場合にメモリを消費します。私は個人的にループに固執します。

于 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 に答える