4

u入力:長さの論理行ベクトルn、たとえば[1,0,1,1,0]; Mサイズが m 行 n 列の論理行列、たとえば[1,0,0,1,1;0 0 0 1 1].

OUTPUT: サイズが m 行 n 列の論理行列。最初の行は行列の最初の行をM「セレクタ」として適用することによって取得されます。つまり[1,0,0,1,0];、2 番目の行は同様に[0 0 0 1 0].

行ベクトルの長さは 20000 で、行列は 30 行 20000 列です。これは1000回繰り返され、1秒未満のコストが必要です。

repmatbsxfun、および要素ごとの乗算を試しましたが、うまくいきません。これらの要素はすべて論理値であるため、これらの要素を一度に「選択」する簡単な方法があると思います。

4

3 に答える 3

1

私があなたに与えることができる最速は、現時点で(私のマシンで)4秒です。あなたがこれを試したかどうかは 100% わかりませんが、とりあえず行ってみましょう。

randbool.mテストデータを生成するために、これらのコンテンツを含む m ファイルがあります。

function x = randbool(m,n)
x = logical(rand(m,n) < 0.5);

テスト用のデータを生成します。

>> u = randbool(1,20000);
>> M = randbool(30,20000);

M の行をループする 3 つの方法 ( を使用bsxfunrepmatを使用、ループを使用) と、必要な要素を取り出す 2 つの方法 (結合&、または を使用した点ごとの乗算.*) を考えることができます。最も速いのは、 と の組み合わせですbsxfun

Bsxfun / コンジャンクション

>> tic, for i=1:1000, bsxfun(@and,u,M); end, toc
Elapsed time is 4.068684 seconds.

Bsxfun / 乗算

>> tic, for i=1:1000, bsxfun(@times,u,M); end, toc
Elapsed time is 4.856784 seconds.

レプマット/コンジャンクション

>> tic, for i=1:1000, utmp=repmat(u,30,1); M&utmp; end, toc
Elapsed time is 7.305158 seconds.

レプマット/乗算

>> tic, for i=1:1000, utmp=repmat(u,30,1); M.*utmp; end, toc
Elapsed time is 8.117164 seconds.

ループ/結合

>> tic, for i=1:1000, for j = 1:30, out(j,:)=u&M(j,:); end; end, toc
Elapsed time is 7.110872 seconds.

ループ/乗算

>> tic, for i=1:1000, for j = 1:30, out(j,:)=u.*M(j,:); end; end, toc
Elapsed time is 8.322888 seconds.
于 2012-11-30T11:53:21.940 に答える
0

他の解決策は物事を過度に複雑にしています。

あなたがする必要があるのは、選択されていない列のエントリをゼロにすることです...

M(:,~u)=0;

それでおしまい。わずか10文字。@and で bsxfun を使用する Chris Taylor のソリューションは少し遅く、他の方法はもっと悪いです。

octave:8> u = logical(rand(1,20000)<0.5);
octave:9> M = logical(rand(30,20000)<0.5);
octave:10> tic, for i=1:1000, N=M; N(:,~u)=0; end, toc
Elapsed time is 0.66 seconds.
octave:11> tic, for i=1:1000, N=M; N=bsxfun(@and,u,N); end, toc
Elapsed time is 0.82 seconds.
octave:12> tic, for i=1:1000, N=bsxfun(@and,u,M); end, toc
Elapsed time is 0.8 seconds.

このメソッドはベクトルに直接作用するため、「N=M」を使用して結果を標準化したことに注意してください。ただし、割り当ては時間に大きな影響を与えません。

于 2013-03-16T15:45:29.580 に答える
0

これは、ビットごとの and 操作のように見えます。おそらく、次のようなものが機能します。

utemp=repmat(u,1,size(m,2));
output=M&utemp;

そのような大規模な行列の場合、メモリの問題が発生する可能性があることを追加する必要があります。基本的に、合計 600K の要素マトリックスの 3 つのコピーが必要です。

于 2012-11-30T11:34:08.103 に答える