Рассчитать матричный ранг, используя scipy

Я хотел бы рассчитать математический ранг матрицы, используя 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.


person Hooked    schedule 18.03.2010    source источник
comment
Я проверил ранг с помощью Mathematica - это действительно 3. Функция, которую вы вызываете в Python, либо неверна, либо вы ее используете неправильно.   -  person duffymo    schedule 19.03.2010
comment
Использование правильное - это то, что сбило меня с толку в первую очередь. В посте я объясняю, что делает rank: он вычисляет размерность массива. Массив ранга 3 будет списком списков списков.   -  person Hooked    schedule 19.03.2010
comment
Обратите внимание, что термин «ранг» несколько неоднозначен. Для тензора ранг говорит вам о количестве индексов (например, скаляр — это тензор ранга 0, ранг вектора — 1 и ранг матрицы — 2). Для линейной алгебры также есть определение, которое вы цитируете выше. Из строки документации ясно, что Numpy использует первое.   -  person Rupert Nash    schedule 29.03.2010


Ответы (7)


Numpy предоставляет numpy.linalg.matrix_rank():

>>> import numpy
>>> numpy.__version__
'1.5.1'
>>> A = numpy.matrix([[1,3,7],[2,8,3],[7,8,1]])
>>> numpy.linalg.matrix_rank(A)
3
person Simon    schedule 01.08.2011
comment
Как найти ранг для целочисленных матриц по модулю n? В Mathematica есть эта функция MatrixRank[..., Modulus -> n], но как реализовать эту функцию в Python? - person Everett You; 18.06.2015

Предоставить примерный фрагмент кода для людей, которым нужно сделать это на практике. Не стесняйтесь совершенствоваться.

u, s, v = np.linalg.svd(A)
rank = np.sum(s > 1e-10)
person Stefan van der Walt    schedule 28.07.2010

Если 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).

person Escualo    schedule 28.07.2010

Этот ответ устарел.

Ответ — нет — в настоящее время в scipy нет функции, предназначенной для вычисления матричного ранга массива/матрицы. Добавление одного обсуждалось ранее, но если это произойдет, я не верю, что это еще не произошло.

person Mike Graham    schedule 19.03.2010
comment
Кстати, mail.scipy.org/pipermail/numpy-discussion/ 2008-February/ — первая запись короткого обсуждения этой темы в группе новостей. - person Mike Graham; 19.03.2010
comment
В настоящее время существует numpy.linalg.matrix_rank(). Смотрите мой ответ. - person Simon; 02.12.2011

Я не знаю, в частности, о Numpy, но вряд ли это будет встроенная операция над матрицей; он включает в себя довольно интенсивные численные вычисления (и связанные с этим опасения по поводу ошибки округления с плавающей запятой и т. д.) и выбор пороговых значений, которые могут подходить или не подходить в данном контексте, и выбор алгоритма важен для точного и быстрого его вычисления.

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

person Brooks Moses    schedule 18.03.2010
comment
Это хороший момент, численно нестабильная матрица может привести к изменению ранга из-за ошибок округления. Однако это известная проблема, и мне было интересно, имеют ли библиотеки scipy/numpy прямую функцию. Если ответ нет - это тоже нормально, я всегда могу пойти с СВД. - person Hooked; 19.03.2010
comment
Это не просто численно нестабильные. Как насчет {{1.0, 3.0}, {1.0/3.0, 1.0}}? Подразделение не может дать точного ответа, поэтому следует ли считать это рангом 1 или рангом 2? - person Brooks Moses; 19.03.2010

Функции линейной алгебры обычно группируются в numpy.linalg. (Они также доступны из scipy.linalg, который обладает большей функциональностью.) Это допускает полиморфизм: функции могут принимать любые типы, которые обрабатывает SciPy.

Так что да, функция numpy.linalg.lstsq делает то, что вы просите. Почему этого недостаточно?

person bignose    schedule 18.03.2010
comment
Он делает то, что я прошу, но делает гораздо больше без необходимости и с большим количеством багажа. То же самое можно было бы сделать с декомпозицией LU, а затем с сортировкой строк. Цель вопроса - если это было неясно, существовала ли функция, единственной целью которой было вычисление ранга. Т.е. взять в matrx, выплюнуть int. - person Hooked; 19.03.2010

scipy теперь содержит эффективный интерполяционный метод для оценки ранга матрицы/LinearOperator с использованием случайных методов, которые часто могут быть достаточно точными:

>>> from numpy import matrix
>>> A = matrix([[1,3,7],[2,8,3],[7,8,1]], dtype=float)  # doesn't accept int

>>> import scipy.linalg.interpolative as sli
>>> sli.estimate_rank(A, eps=1e-10)
3
person jawknee    schedule 19.02.2018