Как получить обратную матрицу в python? Я реализовал это сам, но это чистый python, и я подозреваю, что для этого есть более быстрые модули.
Python, обратная матрице
Ответы (7)
Вам следует взглянуть на numpy, если вы выполняете манипуляции с матрицами. Это модуль, в основном написанный на C, что будет намного быстрее, чем программирование на чистом питоне. Вот пример того, как инвертировать матрицу и выполнять другие манипуляции с матрицей.
from numpy import matrix
from numpy import linalg
A = matrix( [[1,2,3],[11,12,13],[21,22,23]]) # Creates a matrix.
x = matrix( [[1],[2],[3]] ) # Creates a matrix (like a column vector).
y = matrix( [[1,2,3]] ) # Creates a matrix (like a row vector).
print A.T # Transpose of A.
print A*x # Matrix multiplication of A and x.
print A.I # Inverse of A.
print linalg.solve(A, x) # Solve the linear equation system.
Вы также можете взглянуть на модуль array, который намного эффективнее. реализация списков, когда приходится иметь дело только с одним типом данных.
numpy.linalg
вы можете получить почти все, что хотите. , без использования громоздкого numpy.matrix
.
- person Praveen; 13.06.2017
Убедитесь, что вам действительно нужно инвертировать матрицу. Это часто не нужно и может быть численно нестабильным. Когда большинство людей спрашивают, как инвертировать матрицу, они действительно хотят знать, как решить Ax = b, где A — матрица, а x и b — векторы. Более эффективно и точнее использовать код, который решает уравнение Ax = b для x напрямую, чем вычислять обратное значение A, а затем умножать обратное значение на B. Даже если вам нужно решить Ax = b для многих значений b, это не очень хорошая идея. чтобы инвертировать A. Если вам нужно решить систему для нескольких значений b, сохраните факторизацию Холецкого для A, но не инвертируйте ее.
См. Не инвертировать эту матрицу.
Жаль, что выбранная матрица, повторенная здесь снова, либо сингулярна, либо плохо обусловлена:
A = matrix( [[1,2,3],[11,12,13],[21,22,23]])
По определению, обратная А при умножении на саму матрицу А должна давать единичную матрицу. А, выбранный в хваленом объяснении, этого не делает. На самом деле, просто глядя на инверсию, можно понять, что инверсия работала неправильно. Посмотрите на величину отдельных слагаемых - они очень, очень велики по сравнению с слагаемыми исходной матрицы A...
Примечательно, что людям при выборе примера матрицы так часто удается выбрать единственную матрицу!
У меня была проблема с решением, поэтому я изучил его подробнее. На платформе ubuntu-kubuntu пакет debian numpy не имеет подпакетов matrix и linalg, поэтому в дополнение к импорту numpy необходимо также импортировать scipy.
Если диагональные члены A умножить на достаточно большой коэффициент, скажем, на 2, матрица, скорее всего, перестанет быть сингулярной или почти сингулярной. Так
A = matrix( [[2,2,3],[11,24,13],[21,22,46]])
не становится ни сингулярным, ни почти сингулярным, и пример дает значимые результаты... При работе с числами с плавающей запятой нужно следить за последствиями неизбежных ошибок округления.
Спасибо за ваш вклад,
Старый Ал.
Вы можете вычислить определитель рекурсивной матрицы, а затем сформировать присоединенную матрицу
Я думаю, что это работает только для квадратных матриц
Другой способ их вычисления включает ортогонализацию по Граму-Шмидту, а затем транспонирование матрицы, транспонирование ортогонализированной матрицы является ее инверсией!
Для тех, кто, как и я, искал чистое решение Python без участия pandas
или numpy
, ознакомьтесь со следующим проектом GitHub: https://github.com/ThomIves/MatrixInverse.
Он щедро дает очень хорошее объяснение того, как процесс выглядит за кулисами. Автор хорошо описал пошаговый подход и представил несколько практических примеров, которым легко следовать.
Это всего лишь небольшой фрагмент кода, чтобы очень кратко проиллюстрировать подход (AM
— исходная матрица, IM
— единичная матрица того же размера):
def invert_matrix(AM, IM):
for fd in range(len(AM)):
fdScaler = 1.0 / AM[fd][fd]
for j in range(len(AM)):
AM[fd][j] *= fdScaler
IM[fd][j] *= fdScaler
for i in list(range(len(AM)))[0:fd] + list(range(len(AM)))[fd+1:]:
crScaler = AM[i][fd]
for j in range(len(AM)):
AM[i][j] = AM[i][j] - crScaler * AM[fd][j]
IM[i][j] = IM[i][j] - crScaler * IM[fd][j]
return IM
Но, пожалуйста, следите за всем, вы узнаете гораздо больше, чем просто скопировав этот код! Между прочим, есть блокнот Jupyter.
Надеюсь, это кому-то поможет, лично я нашел это чрезвычайно полезным для моей конкретной задачи (Поглощение цепи Маркова) где я не смог использовать какие-либо нестандартные пакеты.
Numpy подойдет для большинства людей, но вы также можете создавать матрицы в Sympy
Попробуйте запустить эти команды на странице http://live.sympy.org/.
M = Matrix([[1, 3], [-2, 3]])
M
M**-1
Ради интереса попробуйте M**(1/2)
numpy.linalg
давал неточные результаты для матриц, содержащих большие целые числа, тогда как результаты sympy
были точными. +1
- person primo; 17.06.2015
(M**-1)*M
, и она дала единичную матрицу (не совсем, но очень близкую)
- person Deniz Kaplan; 20.05.2016
Если вы ненавидите numpy, вытащите RPy и свою локальную копию R и используйте его вместо этого.
(Я бы также повторил, чтобы вам действительно нужно было инвертировать матрицу. Например, в R linalg.solve и функцияsolve() фактически не выполняют полную инверсию, поскольку в этом нет необходимости.)