Вы подняли два вопроса:
- Собственные значения, возвращаемые
scipy.linalg.eig
, не являются реальными.
- Некоторые из собственных значений отрицательны.
Обе эти проблемы являются результатом ошибок, вызванных ошибками усечения и округления, которые всегда происходят с итерационными алгоритмами, использующими арифметику с плавающей точкой. Обратите внимание, что результаты Matlab также дали отрицательные собственные значения.
Теперь, для более интересного аспекта проблемы: почему результат Matlab реален, тогда как результат SciPy имеет некоторые сложные компоненты?
Matlab's eig
определяет, является ли входная матрица реальной симметричной или эрмитовой, и использует факторизацию Холецкого, когда она есть. См. Описание аргумента chol
в документации eig
. Это не делается автоматически в SciPy.
Если вы хотите использовать алгоритм, который использует структуру реальной симметричной или эрмитовой матрицы, используйте scipy.linalg.eigh
. Для примера в вопросе:
>>> eigh(C, eigvals_only=True)
array([ -3.73825923e-17, -1.60154836e-17, 8.11704449e-19,
3.65055777e-17, 7.90175615e-01])
Этот результат такой же, как у Matlab, если вы округлите до того же числа цифр точности, которое напечатал Matlab.