Я хотел бы вычислить математический разряд матрицы с помощью scipy. Самая очевидная функция numpy.rank
вычисляет размер массива (т.е. скаляры имеют размер 0, векторы 1, матрицы 2, и т.д....). Я знаю что numpy.linalg.lstsq
модуль имеет эту возможность, но я задавался вопросом, встроена ли такая фундаментальная операция в матричный класс где-нибудь.
Вот явный пример:
from numpy import matrix, rank
A = matrix([[1,3,7],[2,8,3],[7,8,1]])
print rank(A)
Это дает 2
размер, где я ищу ответ 3
.
Функции линейной алгебры обычно сгруппированы в numpy. linalg
. (Они также доступны на scipy.linalg
, который имеет больше функциональных возможностей.) Это допускает полиморфизм: функции могут принимать любой из типов, которые обрабатывает SciPy.
Итак, да, функция numpy.linalg.lstsq
делает то, о чем вы просите. Почему этого недостаточно?
Я не знаю, в частности, о Numpy, но вряд ли это будет встроенная операция над матрицей; он включает в себя довольно интенсивные численные вычисления (и связанные с ними опасения по поводу ошибки округления с плавающей запятой и т. д.) и выбор пороговых значений, которые могут или не могут быть подходящими в данном контексте, и выбор алгоритма важен для его точного и быстрого вычисления.
Вещи, встроенные в базовые классы, как правило, могут быть выполнены уникальным и простым способом, например, умножение матриц в самом сложном случае.
Этот ответ устарел.
Ответ отрицательный - в настоящее время нет функции, предназначенной для вычисления ранга матрицы массива / матрицы в scipy. Добавление одного уже обсуждалось ранее, но если это произойдет, я не думаю, что это уже произошло.
Чтобы предоставить примерный фрагмент кода для людей, которым нужно сделать это на практике. Не стесняйтесь совершенствоваться.
u, s, v = np.linalg.svd(A)
rank = np.sum(s > 1e-10)
Если numpy
не предлагает возможности ранжирования, почему бы вам не написать свой собственный?
Эффективный способ вычисления ранга - через разложение по сингулярным значениям - ранг матрицы равен количеству ненулевых сингулярных значений.
def rank(A, eps=1e-12):
u, s, vh = numpy.linalg.svd(A)
return len([x for x in s if abs(x) > eps])
Обратите внимание, что eps
зависит от вашего приложения - большинство согласятся, что 1e-12 соответствует нулю, но вы можете наблюдать численную нестабильность даже для eps = 1e-9.
Используя ваш пример, ответ - три. Если вы измените вторую строку на [2, 6, 14]
(линейно зависит от первой строки), ответ будет два («нулевое» собственное значение - 4.9960E-16)