Numpy наибольшее сингулярное значение больше наибольшего собственного значения - PullRequest
0 голосов
/ 07 мая 2020

Пусть

import numpy as np

M = np.array([[ 1., -0.5301332 , 0.80512845],
              [ 0., 0., 0.],
              [ 0., 0., 0.]])

M - это ранг один, его единственное ненулевое собственное значение - 1 (его след). Однако np.linalg.norm(M, ord=2) возвращает 1,39, что строго больше 1. Почему?

Собственные значения M, возвращаемые np.linalg.eigvals, равны 1, 0, 0, но сингулярные значения M равны 1,39, 0, 0 , что для меня сюрприз. Что я пропустил?

Ответы [ 3 ]

0 голосов
/ 07 мая 2020

В этом конкретном случае 2-норма M совпадает с нормой Фробениуса, которая дается формулой (np.sum(np.abs(M**2)))**(1/2), поэтому мы можем видеть, что:

import numpy as np

M = np.array([[ 1., -0.5301332 , 0.80512845],
              [ 0., 0., 0.],
              [ 0., 0., 0.]])

np.sqrt(np.sum(np.abs(M**2)))
1.388982732341062

np.sqrt(np.sum(np.abs(M**2))) == np.linalg.norm(M,ord=2) == np.linalg.norm(M, ord='fro')
True

В частности, можно докажите, что 2-норма - это квадрат root наибольшего собственного значения M.T@M, т.е.

np.sqrt(np.linalg.eigvals(M.T@M)[0])
1.388982732341062

И это его связь с собственными значениями матрицы. Теперь вспомним, что сингулярные значения - это квадрат root собственных значений M. T@M, и мы раскрываем тайну.


Используя характеристику нормы Фробениуса (квадрат root сумма следа M. T@M):

np.sqrt(np.sum(np.diag(M.T@M)))
1.388982732341062

Сопоставление результатов:

np.sqrt(np.linalg.eigvals(M.T@M)[0]) == np.sqrt(np.sum(np.diag(M.T@M))) == np.linalg.svd(M)[1][0]
True
0 голосов
/ 07 мая 2020

Это совершенно нормально. В общем случае сингулярные значения не равны собственным значениям. Это верно только для положительных эрмитовых матриц.

Для матриц в квадрате у вас есть следующие отношения:

M = np.matrix([[ 1., -0.5301332 , 0.80512845],
              [ 0., 0., 0.],
              [ 0., 0., 0.]])
u, v= np.linalg.eig(M.H @ M) # M.H @ M is Hermitian
print(np.sqrt(u)) # [1.38898273 0.         0.        ]
u,s,v = lin.svd(M)
print(s) # [1.38898273 0.         0.        ]
0 голосов
/ 07 мая 2020

вторая норма матрицы квадрат root суммы всех элементов в квадрате

norm(M, ord=2) = (1.**2  + 0.5301332**2 + 0.80512845**2)**0.5 = 1.39

, чтобы получить соотношение между собственными значениями и сингулярными значениями, вам нужно вычислить собственные значения M ^ HM и квадрат root it

eigV = np.linalg.eigvals(M.T.dot(M))
array([1.92927303, 0.        , 0.        ])
eigV**0.5
array([1.38898273, 0.        , 0.        ])
...