[英]Python: reduced row echelon form (mod p) of a very large matrix
我想找到一個大矩陣的簡化的行梯形形式(在字段F_q中)。 我嘗試了以下代碼。 盡管我使用gmpy2庫加快了速度,但該程序仍然內存不足。 因為我的輸入矩陣非常大(100 x 2 ^ 15),而p也非常大(| p | = 256位)。 有人可以建議如何降低這種算法的復雜性。
謝謝
def invmodp(a, p):
return gmpy2.invert(a,p)
def division_mod(a, b, p): #a/b mod p
invert = invmodp(b, p)
return (a * invert) %p
def row_echelon_form(M, p):
lead = 0
rowCount = len(M)
columnCount = len(M[0])
for r in range(rowCount):
if lead >= columnCount:
return
i = r
while M[i][lead] == 0:
i += 1
if i == rowCount:
i = r
lead += 1
if columnCount == lead:
return
M[i],M[r] = M[r],M[i]
lv = M[r][lead]
M[r] = [ division_mod(mrx, lv, p) for mrx in M[r]]
for i in range(rowCount):
if i != r:
lv = M[i][lead]
M[i] = [ (iv - lv*rv)%p for rv,iv in zip(M[r],M[i])]
lead += 1
return M
通過使用gmpy2.divm
替換您的division_mod
我可以節省幾秒鍾的運行時間。 我沒有其他任何重大改進。 下面的程序創建一個隨機的100 x 2 ^ 15矩陣,並在大約3分鍾內計算行梯形形式,並消耗425MB的內存。
import gmpy2
bits = 256
r = 100
c = 2**15
p = gmpy2.next_prime(2**bits - 1234)
seed = gmpy2.random_state(42)
M = []
for i in range(r):
M.append([gmpy2.mpz_urandomb(seed, bits) for j in range(c)])
def row_echelon_form(M, p):
lead = 0
rowCount = len(M)
columnCount = len(M[0])
for r in range(rowCount):
if lead >= columnCount:
return
i = r
while M[i][lead] == 0:
i += 1
if i == rowCount:
i = r
lead += 1
if columnCount == lead:
return
M[i],M[r] = M[r],M[i]
lv = M[r][lead]
M[r] = [ gmpy2.divm(mrx, lv, p) for mrx in M[r]]
for i in range(rowCount):
if i != r:
lv = M[i][lead]
M[i] = [ (iv - lv*rv) % p for rv,iv in zip(M[r],M[i])]
lead += 1
return M
N = row_echelon_form(M, p)
如果您的內存使用量gmpy2
超過500MB,則您的gmpy2
版本中可能存在內存泄漏。 或我沒有正確解釋您的要求,矩陣很大。
免責聲明:我維護gmpy2
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.