2017-11-22 2 views
2

のベクトルの要素によって、スパース行列のすべての行は、私は疎行列スケールMATLAB

obj.resOp = sparse(row,col,val); 

とすぐ

sums = sparse(sum(obj.resOp,2)); 

行列の各列の和を含むベクターを有します私は何をしたいです

obj.resOp = obj.resOp ./ sums; 
各行のrowsumが1になるように行列のすべての行をスケールするでしょう

は、しかし、この最後の行では、MATLABは内部obj.resOpからフル行列を構築しているようですので、私はこのエラーを取得する:十分に大きな行列のため

Error using ./ Requested 38849x231827 (17.5GB) array exceeds maximum array size preference. Creation of arrays greater than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference panel for more information.

理論的には、フルマトリクスに拡張する必要はないと私は考えています。 obj.resOpの希薄さを維持しながら、達成したいMATLABの定式化はありますか?

+0

使用しているMATLABのバージョンを知ることはおそらく適切でしょうか? – Wolfie

+0

私はMATLAB 2017aを使用しています。 – fpnick

+0

obj.resOp = inv(diag(sums))* obj.resOp;私に同じ結果を与えるべきであるが、殺される。それは私のベクトルのバグかもしれません。 – fpnick

答えて

2

これは、described in this answerと同様の方法で実行できます。いくつかの疎行列

% Random sparse matrix: 10 rows, 4 cols, density 20% 
S = sprand(10,4, 0.2); 

sumがまばらな入力からスパース行列を返すことに注意して、行の合計を取得しますので、あなたの追加の変換(docs)を必要とせず、

スタート。

rowsums = sum(S,2); 

今要素単位分割からスパース行列を作成

out = sparse(rowidx, colidx, vals./rowsums(rowidx), size(S,1), size(S,2)); 
+0

このソリューションは確かに私のものより速く、メモリが足りなくなりにくいです。 – fpnick

+0

うれしいことに私は助けてくれました、方法は私には新しかったので、それがうまく働くことを知ってもらえました – Wolfie

0

にすべての非ゼロインデックスとその値

[rowidx, colidx, vals] = find(S) 

等価計算

obj.resOp = inv(diag(sums)) * obj.resOp; 
を探します

はスムーズに動作します。

+2

絶対に必要でない限り、すべての費用で 'inv'を使わないでください。エラーを起こしやすいことが知られています。対角行列の逆行列を求めるので、その結果は係数が逆行列であるもう1つの対角行列になります。したがって、 'inv(diag(sums)) - > diag(1.sums)'となります。 [John D. Cookによるこの記事は、啓発されていることが証明されるべきです](https://www.johndcook.com/blog/2010/01/19/dont-invert-that-matrix/)。 – rayryeng

+0

チップをありがとう。実装されました。 – fpnick