2017-02-18 13 views
1

У меня есть большой двумерный ndarray, A, и я хочу вычислить SVD, извлекающее наибольшее собственное значение и связанную пару собственных векторов. Глядя на документы NumPy, кажется, что NumPy может вычислять только полное SVD (numpy.linalg.svd), в то время как SciPy имеет метод, который делает именно то, что мне нужно (scipy.sparse.linalg.svds), но с разреженными матрицами, и я не хочу выполнять преобразование A, поскольку для этого потребуется дополнительное вычислительное время.наибольшее единственное значение NumPy `ndarray`

До сих пор я использовал SciPy svds непосредственно на A, однако документация не позволяет передать ndarray s этим методам.

Есть ли способ выполнить эту задачу с помощью метода, который принимает объекты ndarray?

ответ

3

Если svds работает с вашим плотным массивом A, продолжайте использовать его. Вам не нужно преобразовывать его во что угодно. svds выполняет всю необходимую адаптацию.

Это документация говорит

A: {разреженная матрица, LinearOperator} массива для вычисления СВД на, формы (M, N)

Но что такое LinearOperator? Это оболочка вокруг того, что может выполнять матричный продукт. Для плотного массива A.dot подходит.

Посмотрите на код для svds. Первое, что делает, это A = np.asarray(A), если A еще не линейный оператор или разреженная матрица. Затем он захватывает A.dot и (hemetianA).dot и создает новый LinearOperator.

В этой функции нет ничего особенного в разреженной матрице. Все, что имеет значение, - это совместимый матричный продукт.

Посмотрите на эти времена:

In [358]: A=np.eye(10) 
In [359]: Alg=splg.aslinearoperator(A) 
In [360]: Am=sparse.csr_matrix(A) 
In [361]: timeit splg.svds(A) 
1000 loops, best of 3: 541 µs per loop 
In [362]: timeit splg.svds(Alg) 
1000 loops, best of 3: 964 µs per loop 
In [363]: timeit splg.svds(Am) 
1000 loops, best of 3: 939 µs per loop 

Прямое использование A является самым быстрым. Конверсии не помогают, даже если они находятся вне цикла синхронизации.