【问题标题】:Create and invert large Galois field matrix创建和反转大型伽罗瓦场矩阵
【发布时间】:2014-06-16 16:37:47
【问题描述】:

我有一个大小为 128x128 的矩阵。每个条目都是一个二进制字段元素(在我的用例中,只有 0 和 1)。我尝试在 matlab 中反转这个矩阵。我在 matlab 中找到了一些在 http://www.mathworks.com/help/comm/galois-field-computations.html 处进行有限域矩阵求逆的函数。

但是,这些内置函数仅支持最大 16x16 的矩阵大小。还有其他方法可以克服这个限制吗?我对 Python 或 C/C++ 等其他工具持开放态度。

如果您想尝试您的方法,这里是测试矩阵及其逆矩阵。

矩阵 A [0,0,0,1,0,0,1,0;1,1,1,0,1,0,1,1;1,1,1,0,1,1,0,1;0 ,1,0,0,0,0,1,0;0,1,1,1,1,1,1,0;1,0,1,1,0,0,1,0;0,0 ,1,0,0,0,1,0;0,0,0,0,0,1,0,0]

矩阵 A^-1 [1,1,1,0,0,1,1,1;0,1,1,1,0,0,0,1;0,1,1,0,0,0,1,1;1 ,1,1,0,0,0,0,1;1,0,0,1,1,0,1,1;0,0,0,0,0,0,0,1;0,1 ,1,0,0,0,0,1;0,1,0,0,1,1,1,1]

【问题讨论】:

    标签: python c++ c matlab finite-field


    【解决方案1】:

    看看SAGEwww.sagemath.org

    【讨论】:

    【解决方案2】:

    可以通过对 [A | I] 执行 Gaussian elimination(在 Galois 字段中执行所有算术)来完成对 Galois 域的矩阵求逆,从而得到 [I | A^-1]

    这是一些执行高斯消除(行缩减)的伪代码。

    def row_reduce(A):
        A_rre = A.copy()
        p = 0  # The pivot
    
        for j in range(A.shape[1]):
            # Find a pivot in column `j` at or below row `p`
            idxs = np.nonzero(A_rre[p:,j])[0]
            if idxs.size == 0:
                continue
            i = p + idxs[0]  # Row with a pivot
    
            # Swap row `p` and `i`. The pivot is now located at row `p`.
            A_rre[[p,i],:] = A_rre[[i,p],:]
    
            # Force pivot value to be 1
            A_rre[p,:] /= A_rre[p,j]
    
            # Force zeros above and below the pivot
            idxs = np.nonzero(A_rre[:,j])[0].tolist()
            idxs.remove(p)
            A_rre[idxs,:] -= np.multiply.outer(A_rre[idxs,j], A_rre[p,:])
    
            p += 1
            if p == A_rre.shape[0]:
                break
    
        return A_rre
    

    我有这个用例,但找不到完成此任务的 Python 库。所以我创建了一个 Python 包galois,它在 Galois 字段上扩展了 NumPy 数组。它支持使用普通np.linalg 函数的线性代数。

    这是一个使用您的测试矩阵的示例。

    In [1]: import numpy as np                                                                              
    
    In [2]: import galois                                                                                   
    
    In [3]: GF = galois.GF(2)                                                                               
    
    In [4]: A = GF([[0,0,0,1,0,0,1,0],[1,1,1,0,1,0,1,1],[1,1,1,0,1,1,0,1],[0,1,0,0,0,0,1,0],[0,1,1,1,1,1,1,0
       ...: ],[1,0,1,1,0,0,1,0],[0,0,1,0,0,0,1,0],[0,0,0,0,0,1,0,0]]); A                                    
    Out[4]: 
    GF([[0, 0, 0, 1, 0, 0, 1, 0],
        [1, 1, 1, 0, 1, 0, 1, 1],
        [1, 1, 1, 0, 1, 1, 0, 1],
        [0, 1, 0, 0, 0, 0, 1, 0],
        [0, 1, 1, 1, 1, 1, 1, 0],
        [1, 0, 1, 1, 0, 0, 1, 0],
        [0, 0, 1, 0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0, 1, 0, 0]], order=2)
    
    In [5]: A_inv = np.linalg.inv(A); A_inv                                                                 
    Out[5]: 
    GF([[1, 1, 1, 0, 0, 1, 1, 1],
        [0, 1, 1, 1, 0, 0, 0, 1],
        [0, 1, 1, 0, 0, 0, 1, 1],
        [1, 1, 1, 0, 0, 0, 0, 1],
        [1, 0, 0, 1, 1, 0, 1, 1],
        [0, 0, 0, 0, 0, 0, 0, 1],
        [0, 1, 1, 0, 0, 0, 0, 1],
        [0, 1, 0, 0, 1, 1, 1, 1]], order=2)
    
    In [6]: A @ A_inv                                                                                       
    Out[6]: 
    GF([[1, 0, 0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0, 0, 0],
        [0, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 1, 0, 0, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0],
        [0, 0, 0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0, 0, 0, 1]], order=2)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-07-22
      • 1970-01-01
      • 1970-01-01
      • 2016-10-14
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多