2

大きな m *n スパース行列 Y があります。各行の平均がゼロになるように、Y の各行を正規化したいと思います。

私は最初にこれを試しました。しかし、各行の平均もゼロエントリから差し引かれますが、これは私が望むものではありません。

Ynorm = bsxfun(@minus, Y, Ymean); 

それから私はこれを試しました。

[m, n] = size(Y);
nonZeroNum = nnz(Y); 
Ynorm = spalloc(m,n,nonZeroNum); 
for i = 1:m
    Ynorm(i, :) = spfun(@(x)(x - Ymean(i)), Y(i, :));
end

ただし、このベクトル化されていないソリューションは遅すぎます。

bsxfun と spfun を組み合わせることも考えましたが、実現しませんでした。

ベクトル化されたソリューションを持っている人はいますか?

4

1 に答える 1

3

簡単、簡単。

ランダムなスパース行列。

A = sprand(100,100,.05);

行の意味を取得します。行にゼロ以外の要素がない場合、0/0 = NaNと予想されますが、その行が次のステップで変更されることはありません。

rowmeans = sum(A,2)./sum(A~=0,2);

非ゼロを抽出します。

[i,j.a] = find(A);

そして、配列を復元します。つまり、減算されます。

[n,m] = size(A);
B = sparse(i,j,a - rowmeans(i),n,m);

今、それをテストします。ここでは浮動小数点演算が適用されることを忘れないでください。したがって、行の平均は正確にゼロではなく、epsのオーダーのみになります。

min(mean(B,2))
ans =
   (1,1)     -1.5543e-17

max(mean(B,2))
ans =
   (1,1)      1.1657e-17

ほぼ正しいようで、完全にベクトル化されています。結果が本当にまばらであり、ゼロ要素が破損していないことを納得させるために、ここにスパイの結果があります。

spy(B)

spyplot.jpg

于 2012-09-13T01:24:43.900 に答える