Какой самый быстрый способ найти собственные значения / векторы в Python? - PullRequest
38 голосов
/ 13 июля 2011

В настоящее время я использую numpy, который делает эту работу. Но так как я имею дело с матрицами с несколькими тысячами строк / столбцов, а позже эта цифра увеличится до десятков тысяч, мне стало интересно, существует ли существующий пакет, способный выполнять такие вычисления быстрее?

Ответы [ 2 ]

52 голосов
/ 14 июля 2011
  • ** если ваша матрица разрежена, то создайте ее экземпляр с помощью конструктора из scipy.sparse , затем используйте аналогичные методы собственного вектора / собственного значения в spicy.sparse.linalg . С точки зрения производительности это имеет два преимущества:

    • ваша матрица, построенная из конструктора spicy.sparse, будет меньше пропорционально ее разреженности.

    • методы собственного значения / собственного вектора для разреженных матриц ( eigs , eigsh ) принимают необязательный аргумент, k , который это число пар собственных значений / собственных значений, которые вы хотите вернуть. Почти всегда число, необходимое для учета> 99% отклонения, намного меньше, чем количество столбцов, которое вы можете проверить ex post ; другими словами, вы можете указать методу, чтобы он не вычислял и не возвращал все пары собственных векторов / собственных значений - за исключением (обычно) небольшого подмножества, необходимого для учета отклонений, маловероятно, что вам понадобится остальные.

  • использовать библиотеку линейной алгебры в SciPy , scipy.linalg , вместо этого одноименной библиотеки NumPy . Эти две библиотеки имеют то же имя и использовать те же имена методов. Тем не менее, есть разница в производительности. Эта разница вызвана тем, что numpy.linalg является меньше верная оболочка на аналогичных подпрограммах LAPACK, которые пожертвовать некоторой производительностью ради переносимости и удобства (т. е. для достижения цели проектирования NumPy , что вся библиотека NumPy должен быть собран без компилятора Фортрана). linalg in SciPy on с другой стороны, гораздо более полная обертка на LAPACK и которая использует f2py .

  • выберите функцию, подходящую для вашего варианта использования ; другими словами, не использовать функцию делает больше, чем нужно. В scipy.linalg есть несколько функций для вычисления собственных значений; различия не велики, хотя при тщательном выборе функции чтобы вычислить собственные значения, вы должны увидеть повышение производительности. За пример:

    • scipy.linalg.eig возвращает оба собственные значения и собственные векторы
    • scipy.linalg.eigvals , возвращает только собственные значения. Так что если вам нужны только собственные значения матрицы, тогда не используйте linalg.eig , вместо этого используйте linalg.eigvals .
    • если у вас есть квадратные симметричные матрицы с реальными значениями (равными его транспонированию), тогда используйте scipy.linalg.eigsh
  • оптимизировать вашу сборку Scipy Подготовка вашей среды сборки SciPy в основном это делается в скрипте SciPy setup.py . Возможно, Наиболее значимым параметром с точки зрения производительности является выявление любого оптимизированного Библиотеки LAPACK, такие как ATLAS или инфраструктура Accelerate / vecLib (OS X только?) чтобы SciPy мог их обнаружить и построить против них. В зависимости от вашей установки на данный момент, оптимизация вашего SciPy сборка, а затем повторная установка может дать вам существенную производительность увеличение. Дополнительные примечания от основной команды SciPy: здесь .

Будут ли эти функции работать для больших матриц?

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

Я использовал большинство методов в библиотеке linalg для разложения матриц, в которых число столбцов обычно составляет от 5 до 50, и в которых число строк обычно превышает 500 000. Похоже, что ни методы SVD , ни методы eigenvalue не имеют проблем с обработкой матриц такого размера.

Используя библиотеку SciPy linalg , вы можете вычислить собственные векторы и собственные значения одним вызовом, используя любой из нескольких методов из этой библиотеки, eig , eigvalsh и восемь .

>>> import numpy as NP
>>> from scipy import linalg as LA

>>> A = NP.random.randint(0, 10, 25).reshape(5, 5)
>>> A
    array([[9, 5, 4, 3, 7],
           [3, 3, 2, 9, 7],
           [6, 5, 3, 4, 0],
           [7, 3, 5, 5, 5],
           [2, 5, 4, 7, 8]])

>>> e_vals, e_vecs = LA.eig(A)
9 голосов
/ 13 июля 2011

Если ваши матрицы разрежены, вы можете попробовать использовать функцию разреженного собственного значения scipy, которая должна быть быстрее:

http://docs.scipy.org/doc/scipy/reference/sparse.linalg.html

Вы также можете проверить специализированные пакеты, такие как SLEPc, который имеет привязки Python и может выполнять вычисления параллельно с использованием mpi:

http://code.google.com/p/slepc4py/

...