2

I am working with finite fields in Python. I have a matrix containing polynomials, each polynomial is represented as an integer. For example, the polynomial x^3 + x + 1 is represented as 11, because:

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

Given a matrix, for example:

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

How can I compute the inverse of a matrix in Python ? I have already implemented the following functions (for polynomials, not matrices of polynomials): add(), sub(), mul(), div(), inv()

dimitris93
  • 4,155
  • 11
  • 50
  • 86
  • 1
    Take a a look https://jeremykun.com/2014/03/13/programming-with-finite-fields/ – MishaVacic Aug 17 '17 at 04:43
  • @MishaVacic Are you sure that this discusses matrices? – dimitris93 Aug 17 '17 at 04:45
  • May be this https://www.quora.com/How-can-I-use-Python-to-compute-matrix-on-finite-field – MishaVacic Aug 17 '17 at 06:23
  • How do you represent the matrix? Have you considered to implement your own function, e.g., through Gaussian elimination? – Jonas Aug 17 '17 at 13:21
  • I assume these are polynomials with 1 bit coefficients (the finite field for coefficients is GF(2)) .The matrix inversion could use any typical algorithm for inverting matrices. However it's not clear to me how divide or inverse are implemented, since polynomial division will often result in a non-zero remainder, which would present an issue when trying to calculate an inverse matrix. – rcgldr Aug 29 '17 at 20:01

2 Answers2

2

I wrote a python package that implements numpy arrays over Galois fields. In addition to normal array arithmetic, it also supports linear algebra. https://github.com/mhostetter/galois

Here's an example to do what you're asking about.

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)
Matt Hostetter
  • 360
  • 1
  • 10
1
  1. Suppose your finite field is $GF(8)$, all your computing functions (such as add(), mul()) must calculate over the same field(GF(8)).

  2. The way you calculate a matrix inverse over a finite field is exactly the same as you calculate it over other fields, and the Gauss-Jordan elimination can just make it.

The following is a part of code (From:https://github.com/foool/nclib/blob/master/gmatrixu8.cc) to calculate matrix inverse over GF(256). Hope it help you.

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;
}
foool
  • 1,462
  • 1
  • 15
  • 29