2016-12-08 11 views
1

私は単一値分解を計算したい比較的大きな行列を持っています。 (: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に関連している可能性があります。

代替手段はありますか?

+0

「コルト」を代わりに使用できますか?私はそれがあなたが望むものではないことを知っていますが、それらは疎な行列サポートとSVDを実装しています。 http://dst.lbl.gov/ACSSoftware/colt/api/cern/colt/matrix/linalg/SingularValueDecomposition.html – endbegin

答えて

0

私はの実装を使用してsvd計算で自分のメモリの問題を回避することができます。 Clatrixはスパース行列をサポートしていませんが、svd計算に必要なメモリは少ないようです。