2

次の要件で、MATLAB で行列を作成する必要があります。ベクトルv、たとえばが与えられた[1,2,2,1,3,5,1]場合、行列を形成する必要があります。

[1 0 0 1 0 0 1;
 0 1 1 0 0 0 0;
 0 0 0 0 1 0 0;
 0 0 0 0 0 0 0;
 0 0 0 0 0 1 0]

つまり、行列のith 列には、行 にゼロ以外の要素 (単一の1) が1 つだけ含まれていますv[i]。ループを回避し、これを効率的に行うにはどうすればよいですか?

4

5 に答える 5

4

ここではループが問題ないと指摘する人もいます。スパースの方がはるかに優れていることを指摘します。あなたの行列はまばらです。そのため、スパースの機能を使用して問題を解決し、行列が大きい場合に備えて大量のストレージを節約してください。

N = 3000;
v = ceil(rand(1,3000)*3000);

tic
A = zeros(N,N);
for i = 1:N
  A(v(i),i) = 1;
end
toc
Elapsed time is 0.069082 seconds.

tic
B = sparse(v,1:N,1,N,N);
toc
Elapsed time is 0.001308 seconds.

したがって、マトリックスがまったく大きい場合、時間に大きな違いがあります。

スペースはどうですか?

whos A B
  Name         Size                 Bytes  Class     Attributes

  A         3000x3000            72000000  double              
  B         3000x3000               72008  double    sparse    

それ以外の場合、行列は同じです。

sum(sum(abs(A - B)))
ans =
     0

スパース マトリックスはスペースをほとんど必要とせず、他のマトリックスと同じように使用できます。

MATLAB の機能を使用します。

于 2012-09-30T19:07:12.730 に答える
1

まず、標準的な免責事項として、MATLAB では一般にループを避けるべきであるという一般的な考え方にもかかわらず、ループは実際には MATLAB の最近のリリースで大幅に効率化されており、その大部分は JIT アクセラレータのおかげです。したがって、コードをベンチマークして、ループが実際にボトルネックになっているかどうかを判断してください。

そうは言っても、ループなしでこの問題にアプローチする方法について最初に考えたのは、恒等行列にインデックスを付けることでした (以下に示すように)。

identityMatrix = eye(max(v(:)));
result = identityMatrix(:,v);

これは見栄えの良い、見栄えの良いソリューションだと思います。ただし、ループを使用するよりもはるかに効率的であるとは限りません。比較のポイントとして、ループを使用して次のソリューションを実装しました。

numRows = max(v(:));
numCols = length(v);
result = zeros(numRows,numCols);

for i=1:numCols
    result(v(i),i) = 1;
end

v私のテスト実行に基づいて、トップ (ループなし) ソリューションは、それほど長くない場合に一般的に高速であるように見えます。ただし、多くの要素が含まれている場合 (たとえば、100 を超える場合)、実際には、ループソリューションが代替ソリューションを上回ってvいる平均時間を確認していました。

于 2012-09-30T05:58:52.763 に答える
0
m = max(v);
n = length(v);
M = zeros(m, n);
M([0:(n-1)]*m + v) = 1;
于 2012-09-30T05:26:10.213 に答える
0
>> v =  [1,2,2,1,3,5,1];
>> a = zeros(max(v), length(v));
>> a((0 : size(a, 1) : numel(a) - 1) + v) = 1

a =

     1     0     0     1     0     0     1
     0     1     1     0     0     0     0
     0     0     0     0     1     0     0
     0     0     0     0     0     0     0
     0     0     0     0     0     1     0
于 2012-09-30T18:10:14.723 に答える
0

これは、ニューラル ネットワーク割り当てでターゲット ベクトルを作成する際に必要な手順と非常によく似ています (第 5 週 - Andrew NG ML コースの手書き数字認識)。y の i 番目の出力など、単一のトレーニング出力に対して 10 X 1 サイズのベクトルを作成する必要がありました。y の i 番目のトレーニング出力が 2 の場合、ベクトル化された i 番目の出力は [0 1 0 0 0 0 0 0 0 0] でした。したがって、5000 のトレーニング例では、5000 のベクトルが必要でした。

コードは次のとおりです。


>> v =  [1,2,2,1,3,5,1];
>> v_vec = (1:5)==v';
>> v_vec
v_vec =

  1  0  0  0  0
  0  1  0  0  0
  0  1  0  0  0
  1  0  0  0  0
  0  0  1  0  0
  0  0  0  0  1
  1  0  0  0  0

>> v_vec'
ans =

  1  0  0  1  0  0  1
  0  1  1  0  0  0  0
  0  0  0  0  1  0  0
  0  0  0  0  0  0  0
  0  0  0  0  0  1  0

v_vec' は目的の出力です。便利なリンク: https://www.ee.columbia.edu/~marios/matlab/Matlab%20Tricks.pdf

于 2020-06-02T07:18:06.130 に答える