【问题标题】:Python: reduced row echelon form (mod p) of a very large matrixPython:一个非常大的矩阵的简化行梯形形式(mod p)
【发布时间】:2015-09-28 02:18:04
【问题描述】:

我想找到一个大矩阵的简化行梯形(在字段 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

【问题讨论】:

    标签: python gaussian gmpy


    【解决方案1】:

    通过使用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)
    

    如果您的内存使用量超过 500MB,则您的 gmpy2 版本可能存在内存泄漏。或者我对您的要求的解释有误,并且矩阵要大得多。

    免责声明:我维护gmpy2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      相关资源
      最近更新 更多