用python求逆矩阵含未知数_用Python执行模块化矩阵求逆的最简单方法?

I'd like to take the modular inverse of a matrix like [[1,2],[3,4]] mod 7 in Python. I've looked at numpy (which does matrix inversion but not modular matrix inversion) and I saw a few number theory packages online, but nothing that seems to do this relatively common procedure (at least, it seems relatively common to me).

By the way, the inverse of the above matrix is [[5,1],[5,3]] (mod 7). I'd like Python to do it for me though.

解决方案

A hackish trick which works when rounding errors aren't an issue:

find the regular inverse (may have non-integer entries), and the determinant (an integer), both implemented in numpy

multiply the inverse by the determinant, and round to integers (hacky)

now multiply everything by the determinant's multiplicative inverse (modulo your modulus, code below)

do entrywise mod by your modulus

A less hackish way is to actually implement gaussian elimination. Here's my code using Gaussian elimination, which I wrote for my own purposes (rounding errors were an issue for me). q is the modulus, which is not necessarily prime.

def generalizedEuclidianAlgorithm(a, b):

if b > a:

return generalizedEuclidianAlgorithm(b,a);

elif b == 0:

return (1, 0);

else:

(x, y) = generalizedEuclidianAlgorithm(b, a % b);

return (y, x - (a / b) * y)

def inversemodp(a, p):

a = a % p

if (a == 0):

print "a is 0 mod p"

return None

if a > 1 and p % a == 0:

return None

(x,y) = generalizedEuclidianAlgorithm(p, a % p);

inv = y % p

assert (inv * a) % p == 1

return inv

def identitymatrix(n):

return [[long(x == y) for x in range(0, n)] for y in range(0, n)]

def inversematrix(matrix, q):

n = len(matrix)

A = np.matrix([[ matrix[j, i] for i in range(0,n)] for j in range(0, n)], dtype = long)

Ainv = np.matrix(identitymatrix(n), dtype = long)

for i in range(0, n):

factor = inversemodp(A[i,i], q)

if factor is None:

raise ValueError("TODO: deal with this case")

A[i] = A[i] * factor % q

Ainv[i] = Ainv[i] * factor % q

for j in range(0, n):

if (i != j):

factor = A[j, i]

A[j] = (A[j] - factor * A[i]) % q

Ainv[j] = (Ainv[j] - factor * Ainv[i]) % q

return Ainv

EDIT: as commenters point out, there are some cases this algorithm fails. It's slightly nontrivial to fix, and I don't have time nowadays. Back then it worked for random matrices in my case (the moduli were products of large primes). Basically, the first non-zero entry might not be relatively prime to the modulus. The prime case is easy since you can search for a different row and swap. In the non-prime case, I think it could be that all leading entries aren't relatively prime so you have to combine them

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值