大数的模块矩阵求逆
我正在寻找一种方法来进行模矩阵的求逆。我在这里找到了代码:这里:
def generalizedEuclidianAlgorithm(a, b):
if b > a:
#print a, b
return generalizedEuclidianAlgorithm(b,a);
elif b == 0:
return (1, 0);
else:
#print a,b
(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 0
(x,y) = generalizedEuclidianAlgorithm(p, a % p);
return y % p
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)
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
# print A, Ainv
# print i, j, factor
return Ainv
当我用小的质数q和小的矩阵元素进行测试时,结果是正确的。但是,当我用大的质数q和包含大元素(比如1024位)的矩阵进行测试时,出现了错误:
A = np.matrix([[ matrix[j, i] for i in range(0,n)] for j in range(0, n)], dtype = long)
File "C:\Python27\lib\site-packages\numpy\matrixlib\defmatrix.py", line 257, in __new__
arr = N.array(data, dtype=dtype, copy=copy)
这是不是因为np.matrix的数据类型?如果是的话,为什么“long”数据类型不能支持这种情况呢?
你能告诉我怎么解决这个错误吗?提前谢谢你!
1 个回答
2
我刚发现使用np.array会引发很多问题。一个解决办法就是把矩阵当作二维列表来处理。下面是我的代码:
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 0
(x,y) = generalizedEuclidianAlgorithm(p, a % p);
return y % p
def identitymatrix(n):
return [[long(x == y) for x in range(0, n)] for y in range(0, n)
def multiply_vector_scalar (vector, scalar, q):
kq = []
for i in range (0, len(vector)):
kq.append (vector[i] * scalar %q)
return kq
def minus_vector_scalar1(vector1, scalar, vector2, q):
kq = []
for i in range (0, len(vector1)):
kq.append ((vector1[i] - scalar * vector2[i]) %q)
return kq
def inversematrix1(matrix, q):
n = len(matrix)
A =[]
for j in range (0, n):
temp = []
for i in range (0, n):
temp.append (matrix[j][i])
A.append(temp)
Ainv = identitymatrix(n)
for i in range(0, n):
factor = inversemodp(A[i][i], q)
A[i] = multiply_vector_scalar(A[i],factor,q)
Ainv[i] = multiply_vector_scalar(Ainv[i],factor,q)
for j in range(0, n):
if (i != j):
factor = A[j][i]
A[j] = minus_vector_scalar1(A[j],factor,A[i],q)
Ainv[j] = minus_vector_scalar1(Ainv[j],factor,Ainv[i],q)
return Ainv