2016-12-08 9 views
1

У меня относительно большая матрица, из которой я хотел бы вычислить одноразрядную декомпозицию. Использование прямой функции linear/svd функции core.matrix (с использованием реализации :vectorz), к сожалению, приводит к исключению из-за-памяти - у моей машины сравнительно мало памяти для dev-машины (8 ГБ, пространство кучи Java установлено на max при 5Гб).Однораздельное разложение разреженной матрицы

матрица имеет размерность [422, 23069] и относительно редкими (~ 1,74% значений не равны нулю), так что моя следующая попытка была преобразования матрицы к sparse-matrix:

(def sparse-fs (matrix/sparse-matrix fs)) 

Это удивительно терпит неудачу с ArrayOutOfBoundsException в коде Java. Я мог бы обойти эту проблему, создав разреженную матрицу первого и затем установить ненулевые значения:

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 

Однако, называя 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) в мою относительно небольшую память.

Update: Проблема протокола приходит от меня до сих пор пытается использовать clojure.core.matrix/sparse-matrix, который предназначение я, видимо, не понимаю. Вместо этого я могу использовать new-sparse-array, который создает экземпляр, реализующий AMatrix, для которых реализован протокол разложения:

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 

К сожалению, когда я называю linear/svd на этой матрице, я вернулся в моем отказе от ошибки памяти:

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. Clatrix не поддерживает разреженные матрицы, но, похоже, использует меньше памяти для вычисления svd.