有限域:计算矩阵的逆

时间:2017-08-17 04:37:37

标签: python matrix inverse galois-field finite-field

我正在使用Python中的有限字段。我有一个包含多项式的矩阵,每个多项式都表示为一个整数。例如,多项式x^3 + x + 1表示为11,因为:

x^3 + x + 1 ==> (1,0,1,1) ==> (8,0,2,1) ==> 8 + 0 + 2 + 1 ==> 11

给定一个矩阵,例如:

6, 2, 1
7, 0, 4
1, 7, 3

如何在Python中计算矩阵的逆矩阵?我已经实现了以下函数(对于多项式,而不是多项式的矩阵):add()sub()mul()div()inv()

2 个答案:

答案 0 :(得分:1)

我写了一个 python 包,它在 Galois 字段上实现了 numpy 数组。除了普通的数组算术,它还支持线性代数。 https://github.com/mhostetter/galois

这里有一个例子来完成你的要求。

In [1]: import numpy as np                                                              

In [2]: import galois                                                                   

In [3]: GF = galois.GF(2**3)                                                            

In [4]: print(GF.properties)                                                            
GF(2^3):
  characteristic: 2
  degree: 3
  order: 8
  irreducible_poly: Poly(x^3 + x + 1, GF(2))
  is_primitive_poly: True
  primitive_element: GF(2, order=2^3)

In [5]: A = GF([[6,2,1],[7,0,4],[1,7,3]]); A                                            
Out[5]: 
GF([[6, 2, 1],
    [7, 0, 4],
    [1, 7, 3]], order=2^3)

In [6]: np.linalg.inv(A)                                                                
Out[6]: 
GF([[5, 5, 4],
    [3, 0, 1],
    [4, 3, 7]], order=2^3)

In [7]: np.linalg.inv(A) @ A                                                            
Out[7]: 
GF([[1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]], order=2^3)

答案 1 :(得分:0)

  1. 假设您的有限字段是$ GF(8)$,您的所有计算函数(例如add()mul())必须在同一字段(GF(8))上计算。

  2. 在有限域上计算矩阵逆的方式与在其他场上计算矩阵逆的方式完全相同,而Gauss-Jordan消除算法就可以实现。

  3. 以下是代码(From:https://github.com/foool/nclib/blob/master/gmatrixu8.cc)的一部分,用于计算GF(256)上的矩阵逆。希望对你有所帮助。

    void GMatrixU8::Inverse(){
        GMatrixU8 mat_inv;
        int w = this->ww;
        int dim;
        int i, nzero_row, j;
        int temp, jtimes;
    
        dim = this->rr;
        mat_inv.Make_identity(this->rr, this->cc, this->ww);
    
        for(i = 0; i < dim; i++){
            nzero_row = i;
            if(0 == Get(i,i)){
                do{
                    ++nzero_row;
                    if(nzero_row >= dim){ ERROR("Non-full rank matrix!"); }
                    temp = Get(nzero_row, i);
                }while((0 == temp)&&(nzero_row < dim));
                Swap_rows(i, nzero_row);
                mat_inv.Swap_rows(i, nzero_row);
            }
            for(j = 0; j < dim; j++){
                if(0 == Get(j,i))
                    continue;
                if(j != i){
                    jtimes = galois_single_divide(Get(j,i), Get(i,i), w);
                    Row_plus_irow(j, i, jtimes);
                    mat_inv.Row_plus_irow(j, i, jtimes);
                }else{
                    jtimes = galois_inverse(Get(i, i), w);
                    Row_to_irow(i , jtimes);
                    mat_inv.Row_to_irow(i , jtimes);
                }
            }
        }
        this->ele = mat_inv.ele;
    }