私は単一値分解を計算したい比較的大きな行列を持っています。 (:vectorz
の実装を使用して)core.matrixの関数linear/svd
を使用すると、残念なことにメモリ不足の例外が発生します。私のマシンはdevマシンのメモリがほとんどありません(8GB、Javaヒープスペースはmax 5GB)。疎行列の単一値分解
私の次の試みがsparse-matrix
に行列を変換してマトリックスが、(〜値の1.74パーセントが非ゼロである)の寸法[422, 23069]
を有し、比較的まばらである:
(def sparse-fs (matrix/sparse-matrix fs))
これは驚くべきことで失敗JavaコードのArrayOutOfBoundsException
私が最初にスパース行列を作成し、ゼロ以外の値を設定することでこの問題を回避できます。
user> (def sparse-fs (matrix/sparse-matrix [422 23069]))
#'user/sfs
user> (count
(map-indexed
(fn [row line]
(map-indexed
(fn [col val]
(when (not (= val 0.0))
(matrix/mset! sparse-fs row col val)))))
fs))
422
しかし、SVDのためのプロトコルが明らかに実装されていないとしても、失敗したこの疎行列にlinear/svd
を呼び出す:
user> (def svd-fs (linear/svd sparse-fs))
CompilerException java.lang.IllegalArgumentException: No implementation of method: :svd of protocol:
#'clojure.core.matrix.protocols/PSVDDecomposition found for class: mikera.vectorz.Vector2,
私は現在、ここから進める方法についてのアイデアはありません。私のマトリックス(およびsvd計算)を私の比較的小さなメモリに収める方法についてのご意見をお待ちしております。
更新: プロトコルの問題は、私はまだ私は明らかに理解していない使用を意図clojure.core.matrix/sparse-matrix
を、使用しようとしてから来ています。私はこの行列にlinear/svd
を呼び出すとき、私はメモリエラーの私のうちに戻ってきた、残念ながら
user> (def foo-sparse (matrix/sparse-matrix [422 23069]))
#'user/foo-sparse
user> (type foo-sparse)
mikera.vectorz.Vector2
user> (matrix/dimensionality foo-sparse)
1
user> (def foo-sparse (matrix/new-sparse-array [422 23069]))
#'user/foo-sparse
user> (matrix/dimensionality foo-sparse)
2
user> (type foo-sparse)
mikera.matrixx.impl.SparseRowMatrix
:代わりに、私は、分解プロトコルが実装されているAMatrix
を実装インスタンスを生成new-sparse-array
を使用することができます
1. Caused by java.lang.OutOfMemoryError
Java heap space
DoubleArrays.java: 724 mikera.vectorz.util.DoubleArrays/createStorage
Matrix.java: 45 mikera.matrixx.Matrix/<init>
Matrix.java: 56 mikera.matrixx.Matrix/create
Matrix.java: 653 mikera.matrixx.Matrix/createIdentity
BidiagonalRow.java: 174 mikera.matrixx.decompose.impl.bidiagonal.BidiagonalRow/handleU
BidiagonalRow.java: 155 mikera.matrixx.decompose.impl.bidiagonal.BidiagonalRow/getU
BidiagonalRow.java: 115 mikera.matrixx.decompose.impl.bidiagonal.BidiagonalRow/_decompose
BidiagonalRow.java: 78 mikera.matrixx.decompose.impl.bidiagonal.BidiagonalRow/decompose
Bidiagonal.java: 21 mikera.matrixx.decompose.Bidiagonal/decompose
SvdImplicitQr.java: 177 mikera.matrixx.decompose.impl.svd.SvdImplicitQr/bidiagonalization
SvdImplicitQr.java: 154 mikera.matrixx.decompose.impl.svd.SvdImplicitQr/_decompose
SvdImplicitQr.java: 89 mikera.matrixx.decompose.impl.svd.SvdImplicitQr/decompose
SVD.java: 31 mikera.matrixx.decompose.SVD/decompose
matrix_api.clj: 334 mikera.vectorz.matrix-api/eval26238/fn
protocols.cljc: 1150 clojure.core.matrix.protocols$eval21076$fn__21077$G__21067__21084/invoke
linear.cljc: 105 clojure.core.matrix.linear$svd/invoke
これはvectorz-clj issue 18 that operations on sparse matrices don't produce sparse resultsに関連している可能性があります。
代替手段はありますか?
「コルト」を代わりに使用できますか?私はそれがあなたが望むものではないことを知っていますが、それらは疎な行列サポートとSVDを実装しています。 http://dst.lbl.gov/ACSSoftware/colt/api/cern/colt/matrix/linalg/SingularValueDecomposition.html – endbegin