0

サイズ100x100のこの行列Aがあります。これで、100 個の要素を持つ別のベクトル Z=(1,24,5,80...) ができました。これは 100 要素の列ベクトルです。ここで、行列 A の各行について、その A(i,j) 要素を 1 にします。ここで、i は 1:100 からの行であり、j は Z で指定される列です。

したがって、1 であるべき要素は 1,1 2,24 3,5 4,80 などになります。

ループを使用してそれを実行できることを知っています。しかし、私が1つのライナーを意味する直接的な簡単な方法はありますか?

4

2 に答える 2

3

合計で10000のうち100の非ゼロ要素(つまり、1%の非ゼロのみ)を持つ行列は、スパースとして保存するのが最適です。matlabの機能を使用します。

A = sparse(1:100,Z,1,100,100);

これは、すてきでクリーンな1線形であり、完全な行列よりも効率的に格納される行列になります。それでも行列の乗算に使用でき、その点でもより効率的です。例えば...

Z = randperm(100);
A = sparse(1:100,Z,1,100,100);

whos A

  Name        Size             Bytes  Class     Attributes
  A         100x100             2408  double    sparse    

これにより、メモリがほぼ40対1に削減されます。また、これらの処理が進むにつれてマトリックスは実際にはかなり小さくなりますが、スパースとして使用する方が高速です。

B = rand(100);
timeit(@() B*A)
ans =
   4.5717e-05

Af = full(A);
timeit(@() B*Af)
ans =
   7.4452e-05

Aが1000x1000だったとしたら、節約はさらに重要だったでしょう。

目標が完全な行列である場合は、fullを使用して完全な行列に変換できます。または、accumarrayはオプションです。また、既存の配列に値を挿入する場合は、sub2indを使用します。

于 2012-11-07T22:21:05.200 に答える
0

これを行う1つの方法は、を使用して値Zを絶対インデックスに変換してから、ベクトルインデックスを使用することです。Asub2ind

idx = sub2ind(size(A), 1:numel(Z), Z);
A(idx) = 1;

または単にワンライナーで:

A(sub2ind(size(A), 1:numel(Z), Z)) = 1;
于 2012-11-07T22:07:04.223 に答える