Array Creation

This page discusses the multiple ways to create arrays over finite fields. For this discussion, we are working in the finite field \(\mathrm{GF}(3^5)\).

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

In [2]: print(GF)
Galois Field:
  name: GF(3^5)
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 1
  is_primitive_poly: True
  primitive_element: x
In [3]: GF = galois.GF(3**5, display="poly")

In [4]: print(GF)
Galois Field:
  name: GF(3^5)
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 1
  is_primitive_poly: True
  primitive_element: x
In [5]: GF = galois.GF(3**5, display="power")

In [6]: print(GF)
Galois Field:
  name: GF(3^5)
  characteristic: 3
  degree: 5
  order: 243
  irreducible_poly: x^5 + 2x + 1
  is_primitive_poly: True
  primitive_element: x

Create a new array

A Galois field array can be created from various array-like objects.

Valid array-like objects are: single values, iterables of values, iterables of iterables, or NumPy arrays. The values can be either integers or polynomial strings.

Integers

The most standard input is an iterable of integers. For extension fields, an integer input is the integer representation of the polynomial field element.

In [7]: GF([17, 4])
Out[7]: GF([17,  4], order=3^5)
In [8]: GF([17, 4])
Out[8]: GF([α^2 + 2α + 2,        α + 1], order=3^5)
In [9]: GF([17, 4])
Out[9]: GF([α^222,  α^69], order=3^5)

Iterables of iterables are also supported.

In [10]: GF([[17, 4], [148, 205]])
Out[10]: 
GF([[ 17,   4],
    [148, 205]], order=3^5)
In [11]: GF([[17, 4], [148, 205]])
Out[11]: 
GF([[             α^2 + 2α + 2,                     α + 1],
    [ α^4 + 2α^3 + α^2 + α + 1, 2α^4 + α^3 + α^2 + 2α + 1]], order=3^5)
In [12]: GF([[17, 4], [148, 205]])
Out[12]: 
GF([[α^222,  α^69],
    [ α^54,  α^24]], order=3^5)

Polynomial strings

In addition to the integer representation, field elements may be expressed in their polynomial representation using strings.

In [13]: GF(["x^2 + 2x + 2", "x + 1"])
Out[13]: GF([17,  4], order=3^5)
In [14]: GF(["x^2 + 2x + 2", "x + 1"])
Out[14]: GF([α^2 + 2α + 2,        α + 1], order=3^5)
In [15]: GF(["x^2 + 2x + 2", "x + 1"])
Out[15]: GF([α^222,  α^69], order=3^5)

Many string conventions are accepted, including: with/without *, with/without spaces, ^ or **, any indeterminate variable, increasing/decreasing degrees, etc. Or any combination of the above.

# Add explicit * for multiplication
In [16]: GF(["x^2 + 2*x + 2", "x + 1"])
Out[16]: GF([17,  4], order=3^5)

# No spaces
In [17]: GF(["x^2+2x+2", "x+1"])
Out[17]: GF([17,  4], order=3^5)

# ** instead of ^
In [18]: GF(["x**2 + 2x + 2", "x + 1"])
Out[18]: GF([17,  4], order=3^5)

# Different indeterminate
In [19]: GF(["α^2 + 2α + 2", "α + 1"])
Out[19]: GF([17,  4], order=3^5)

# Ascending degrees
In [20]: GF(["2 + 2x + x^2", "1 + x"])
Out[20]: GF([17,  4], order=3^5)
# Add explicit * for multiplication
In [21]: GF(["x^2 + 2*x + 2", "x + 1"])
Out[21]: GF([α^2 + 2α + 2,        α + 1], order=3^5)

# No spaces
In [22]: GF(["x^2+2x+2", "x+1"])
Out[22]: GF([α^2 + 2α + 2,        α + 1], order=3^5)

# ** instead of ^
In [23]: GF(["x**2 + 2x + 2", "x + 1"])
Out[23]: GF([α^2 + 2α + 2,        α + 1], order=3^5)

# Different indeterminate
In [24]: GF(["α^2 + 2α + 2", "α + 1"])
Out[24]: GF([α^2 + 2α + 2,        α + 1], order=3^5)

# Ascending degrees
In [25]: GF(["2 + 2x + x^2", "1 + x"])
Out[25]: GF([α^2 + 2α + 2,        α + 1], order=3^5)
# Add explicit * for multiplication
In [26]: GF(["x^2 + 2*x + 2", "x + 1"])
Out[26]: GF([α^222,  α^69], order=3^5)

# No spaces
In [27]: GF(["x^2+2x+2", "x+1"])
Out[27]: GF([α^222,  α^69], order=3^5)

# ** instead of ^
In [28]: GF(["x**2 + 2x + 2", "x + 1"])
Out[28]: GF([α^222,  α^69], order=3^5)

# Different indeterminate
In [29]: GF(["α^2 + 2α + 2", "α + 1"])
Out[29]: GF([α^222,  α^69], order=3^5)

# Ascending degrees
In [30]: GF(["2 + 2x + x^2", "1 + x"])
Out[30]: GF([α^222,  α^69], order=3^5)

Integers and polynomial strings may be mixed and matched.

In [31]: GF(["x^2 + 2x + 2", 4])
Out[31]: GF([17,  4], order=3^5)
In [32]: GF(["x^2 + 2x + 2", 4])
Out[32]: GF([α^2 + 2α + 2,        α + 1], order=3^5)
In [33]: GF(["x^2 + 2x + 2", 4])
Out[33]: GF([α^222,  α^69], order=3^5)

Polynomial coefficients

Rather than strings, the polynomial coefficients may be passed into GF’s constructor as length-\(m\) vectors using the galois.FieldArray.Vector() classmethod.

In [34]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[34]: GF([17,  4], order=3^5)
In [35]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[35]: GF([α^2 + 2α + 2,        α + 1], order=3^5)
In [36]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[36]: GF([α^222,  α^69], order=3^5)

The galois.FieldArray.vector() method is the opposite operation. It converts extension field elements from \(\mathrm{GF}(p^m)\) into length-\(m\) vectors over \(\mathrm{GF}(p)\).

In [37]: GF([17, 4]).vector()
Out[37]: 
GF([[0, 0, 1, 2, 2],
    [0, 0, 0, 1, 1]], order=3)
In [38]: GF([17, 4]).vector()
Out[38]: 
GF([[0, 0, 1, 2, 2],
    [0, 0, 0, 1, 1]], order=3)
In [39]: GF([17, 4]).vector()
Out[39]: 
GF([[0, 0, 1, 2, 2],
    [0, 0, 0, 1, 1]], order=3)

NumPy array

An integer NumPy array may also be passed into GF. The default keyword argument copy=True of the galois.FieldArray constructor will create a copy of the array.

In [40]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[40]: array([213, 167,   4, 214, 209])

In [41]: x = GF(x_np); x
Out[41]: GF([213, 167,   4, 214, 209], order=3^5)

# Modifying x does not modify x_np
In [42]: x[0] = 0; x_np
Out[42]: array([213, 167,   4, 214, 209])
In [43]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[43]: array([213, 167,   4, 214, 209])

In [44]: x = GF(x_np); x
Out[44]: 
GF([    2α^4 + α^3 + 2α^2 + 2α,               2α^4 + α + 2,
                         α + 1, 2α^4 + α^3 + 2α^2 + 2α + 1,
         2α^4 + α^3 + 2α^2 + 2], order=3^5)

# Modifying x does not modify x_np
In [45]: x[0] = 0; x_np
Out[45]: array([213, 167,   4, 214, 209])
In [46]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[46]: array([213, 167,   4, 214, 209])

In [47]: x = GF(x_np); x
Out[47]: GF([α^183,   α^9,  α^69, α^153,  α^58], order=3^5)

# Modifying x does not modify x_np
In [48]: x[0] = 0; x_np
Out[48]: array([213, 167,   4, 214, 209])

View an existing array

Instead of creating a Galois field array explicitly, you can convert an existing NumPy array into a Galois field array temporarily and work with it in-place.

Simply call .view(GF) to view the NumPy array as a Galois field array. When finished working in the finite field, call .view(np.ndarray) to view it back to a NumPy array.

In [49]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[49]: array([213, 167,   4, 214, 209])

In [50]: x = x_np.view(GF); x
Out[50]: GF([213, 167,   4, 214, 209], order=3^5)

# Modifying x does modify x_np!
In [51]: x[0] = 0; x_np
Out[51]: array([  0, 167,   4, 214, 209])
In [52]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[52]: array([213, 167,   4, 214, 209])

In [53]: x = x_np.view(GF); x
Out[53]: 
GF([    2α^4 + α^3 + 2α^2 + 2α,               2α^4 + α + 2,
                         α + 1, 2α^4 + α^3 + 2α^2 + 2α + 1,
         2α^4 + α^3 + 2α^2 + 2], order=3^5)

# Modifying x does modify x_np!
In [54]: x[0] = 0; x_np
Out[54]: array([  0, 167,   4, 214, 209])
In [55]: x_np = np.array([213, 167, 4, 214, 209], dtype=int); x_np
Out[55]: array([213, 167,   4, 214, 209])

In [56]: x = x_np.view(GF); x
Out[56]: GF([α^183,   α^9,  α^69, α^153,  α^58], order=3^5)

# Modifying x does modify x_np!
In [57]: x[0] = 0; x_np
Out[57]: array([  0, 167,   4, 214, 209])

Scalars

A single finite field element (a scalar) is a 0-D Galois field array. They are created by passing a single array-like object to the Galois field array class GF’s constructor.

In [58]: a = GF(17); a
Out[58]: GF(17, order=3^5)

In [59]: a = GF("x^2 + 2x + 2"); a
Out[59]: GF(17, order=3^5)

In [60]: a = GF.Vector([0, 0, 1, 2, 2]); a
Out[60]: GF(17, order=3^5)

In [61]: a.ndim
Out[61]: 0
In [62]: a = GF(17); a
Out[62]: GF(α^2 + 2α + 2, order=3^5)

In [63]: a = GF("x^2 + 2x + 2"); a
Out[63]: GF(α^2 + 2α + 2, order=3^5)

In [64]: a = GF.Vector([0, 0, 1, 2, 2]); a
Out[64]: GF(α^2 + 2α + 2, order=3^5)

In [65]: a.ndim
Out[65]: 0
In [66]: a = GF(17); a
Out[66]: GF(α^222, order=3^5)

In [67]: a = GF("x^2 + 2x + 2"); a
Out[67]: GF(α^222, order=3^5)

In [68]: a = GF.Vector([0, 0, 1, 2, 2]); a
Out[68]: GF(α^222, order=3^5)

In [69]: a.ndim
Out[69]: 0

Classmethods

Several classmethods are provided in galois.FieldArray to assist with creating arrays.

Constant arrays

The galois.FieldArray.Zeros() and galois.FieldArray.Ones() classmethods provide constant arrays that are useful for initializing empty arrays.

In [70]: GF.Zeros(4)
Out[70]: GF([0, 0, 0, 0], order=3^5)

In [71]: GF.Ones(4)
Out[71]: GF([1, 1, 1, 1], order=3^5)
In [72]: GF.Zeros(4)
Out[72]: GF([0, 0, 0, 0], order=3^5)

In [73]: GF.Ones(4)
Out[73]: GF([1, 1, 1, 1], order=3^5)
In [74]: GF.Zeros(4)
Out[74]: GF([0, 0, 0, 0], order=3^5)

In [75]: GF.Ones(4)
Out[75]: GF([1, 1, 1, 1], order=3^5)

Ordered arrays

The galois.FieldArray.Range() classmethod produces a range of elements similar to numpy.arange(). The integer start and stop values are the integer representation of the polynomial field elements.

In [76]: GF.Range(10, 20)
Out[76]: GF([10, 11, 12, 13, 14, 15, 16, 17, 18, 19], order=3^5)
In [77]: GF.Range(10, 20)
Out[77]: 
GF([     α^2 + 1,      α^2 + 2,      α^2 + α,  α^2 + α + 1,  α^2 + α + 2,
        α^2 + 2α, α^2 + 2α + 1, α^2 + 2α + 2,         2α^2,     2α^2 + 1],
   order=3^5)
In [78]: GF.Range(10, 20)
Out[78]: 
GF([ α^46,  α^74,  α^70,  α^10, α^209,   α^6, α^138, α^222, α^123, α^195],
   order=3^5)

The galois.FieldArray.Elements() classmethod provides a 1-D array of all the finite field elements.

In [79]: GF.Elements()
Out[79]: 
GF([  0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,
     14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,
     28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,
     42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,  54,  55,
     56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,
     70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,  83,
     84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,
     98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
    112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
    126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,
    140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
    154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
    168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181,
    182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195,
    196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209,
    210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
    224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237,
    238, 239, 240, 241, 242], order=3^5)
In [80]: GF.Elements()
Out[80]: 
GF([                          0,                           1,
                              2,                           α,
                          α + 1,                       α + 2,
                             2α,                      2α + 1,
                         2α + 2,                         α^2,
                        α^2 + 1,                     α^2 + 2,
                        α^2 + α,                 α^2 + α + 1,
                    α^2 + α + 2,                    α^2 + 2α,
                   α^2 + 2α + 1,                α^2 + 2α + 2,
                           2α^2,                    2α^2 + 1,
                       2α^2 + 2,                    2α^2 + α,
                   2α^2 + α + 1,                2α^2 + α + 2,
                      2α^2 + 2α,               2α^2 + 2α + 1,
                  2α^2 + 2α + 2,                         α^3,
                        α^3 + 1,                     α^3 + 2,
                        α^3 + α,                 α^3 + α + 1,
                    α^3 + α + 2,                    α^3 + 2α,
                   α^3 + 2α + 1,                α^3 + 2α + 2,
                      α^3 + α^2,               α^3 + α^2 + 1,
                  α^3 + α^2 + 2,               α^3 + α^2 + α,
              α^3 + α^2 + α + 1,           α^3 + α^2 + α + 2,
                 α^3 + α^2 + 2α,          α^3 + α^2 + 2α + 1,
             α^3 + α^2 + 2α + 2,                  α^3 + 2α^2,
                 α^3 + 2α^2 + 1,              α^3 + 2α^2 + 2,
                 α^3 + 2α^2 + α,          α^3 + 2α^2 + α + 1,
             α^3 + 2α^2 + α + 2,             α^3 + 2α^2 + 2α,
            α^3 + 2α^2 + 2α + 1,         α^3 + 2α^2 + 2α + 2,
                           2α^3,                    2α^3 + 1,
                       2α^3 + 2,                    2α^3 + α,
                   2α^3 + α + 1,                2α^3 + α + 2,
                      2α^3 + 2α,               2α^3 + 2α + 1,
                  2α^3 + 2α + 2,                  2α^3 + α^2,
                 2α^3 + α^2 + 1,              2α^3 + α^2 + 2,
                 2α^3 + α^2 + α,          2α^3 + α^2 + α + 1,
             2α^3 + α^2 + α + 2,             2α^3 + α^2 + 2α,
            2α^3 + α^2 + 2α + 1,         2α^3 + α^2 + 2α + 2,
                    2α^3 + 2α^2,             2α^3 + 2α^2 + 1,
                2α^3 + 2α^2 + 2,             2α^3 + 2α^2 + α,
            2α^3 + 2α^2 + α + 1,         2α^3 + 2α^2 + α + 2,
               2α^3 + 2α^2 + 2α,        2α^3 + 2α^2 + 2α + 1,
           2α^3 + 2α^2 + 2α + 2,                         α^4,
                        α^4 + 1,                     α^4 + 2,
                        α^4 + α,                 α^4 + α + 1,
                    α^4 + α + 2,                    α^4 + 2α,
                   α^4 + 2α + 1,                α^4 + 2α + 2,
                      α^4 + α^2,               α^4 + α^2 + 1,
                  α^4 + α^2 + 2,               α^4 + α^2 + α,
              α^4 + α^2 + α + 1,           α^4 + α^2 + α + 2,
                 α^4 + α^2 + 2α,          α^4 + α^2 + 2α + 1,
             α^4 + α^2 + 2α + 2,                  α^4 + 2α^2,
                 α^4 + 2α^2 + 1,              α^4 + 2α^2 + 2,
                 α^4 + 2α^2 + α,          α^4 + 2α^2 + α + 1,
             α^4 + 2α^2 + α + 2,             α^4 + 2α^2 + 2α,
            α^4 + 2α^2 + 2α + 1,         α^4 + 2α^2 + 2α + 2,
                      α^4 + α^3,               α^4 + α^3 + 1,
                  α^4 + α^3 + 2,               α^4 + α^3 + α,
              α^4 + α^3 + α + 1,           α^4 + α^3 + α + 2,
                 α^4 + α^3 + 2α,          α^4 + α^3 + 2α + 1,
             α^4 + α^3 + 2α + 2,             α^4 + α^3 + α^2,
            α^4 + α^3 + α^2 + 1,         α^4 + α^3 + α^2 + 2,
            α^4 + α^3 + α^2 + α,     α^4 + α^3 + α^2 + α + 1,
        α^4 + α^3 + α^2 + α + 2,        α^4 + α^3 + α^2 + 2α,
       α^4 + α^3 + α^2 + 2α + 1,    α^4 + α^3 + α^2 + 2α + 2,
               α^4 + α^3 + 2α^2,        α^4 + α^3 + 2α^2 + 1,
           α^4 + α^3 + 2α^2 + 2,        α^4 + α^3 + 2α^2 + α,
       α^4 + α^3 + 2α^2 + α + 1,    α^4 + α^3 + 2α^2 + α + 2,
          α^4 + α^3 + 2α^2 + 2α,   α^4 + α^3 + 2α^2 + 2α + 1,
      α^4 + α^3 + 2α^2 + 2α + 2,                  α^4 + 2α^3,
                 α^4 + 2α^3 + 1,              α^4 + 2α^3 + 2,
                 α^4 + 2α^3 + α,          α^4 + 2α^3 + α + 1,
             α^4 + 2α^3 + α + 2,             α^4 + 2α^3 + 2α,
            α^4 + 2α^3 + 2α + 1,         α^4 + 2α^3 + 2α + 2,
               α^4 + 2α^3 + α^2,        α^4 + 2α^3 + α^2 + 1,
           α^4 + 2α^3 + α^2 + 2,        α^4 + 2α^3 + α^2 + α,
       α^4 + 2α^3 + α^2 + α + 1,    α^4 + 2α^3 + α^2 + α + 2,
          α^4 + 2α^3 + α^2 + 2α,   α^4 + 2α^3 + α^2 + 2α + 1,
      α^4 + 2α^3 + α^2 + 2α + 2,           α^4 + 2α^3 + 2α^2,
          α^4 + 2α^3 + 2α^2 + 1,       α^4 + 2α^3 + 2α^2 + 2,
          α^4 + 2α^3 + 2α^2 + α,   α^4 + 2α^3 + 2α^2 + α + 1,
      α^4 + 2α^3 + 2α^2 + α + 2,      α^4 + 2α^3 + 2α^2 + 2α,
     α^4 + 2α^3 + 2α^2 + 2α + 1,  α^4 + 2α^3 + 2α^2 + 2α + 2,
                           2α^4,                    2α^4 + 1,
                       2α^4 + 2,                    2α^4 + α,
                   2α^4 + α + 1,                2α^4 + α + 2,
                      2α^4 + 2α,               2α^4 + 2α + 1,
                  2α^4 + 2α + 2,                  2α^4 + α^2,
                 2α^4 + α^2 + 1,              2α^4 + α^2 + 2,
                 2α^4 + α^2 + α,          2α^4 + α^2 + α + 1,
             2α^4 + α^2 + α + 2,             2α^4 + α^2 + 2α,
            2α^4 + α^2 + 2α + 1,         2α^4 + α^2 + 2α + 2,
                    2α^4 + 2α^2,             2α^4 + 2α^2 + 1,
                2α^4 + 2α^2 + 2,             2α^4 + 2α^2 + α,
            2α^4 + 2α^2 + α + 1,         2α^4 + 2α^2 + α + 2,
               2α^4 + 2α^2 + 2α,        2α^4 + 2α^2 + 2α + 1,
           2α^4 + 2α^2 + 2α + 2,                  2α^4 + α^3,
                 2α^4 + α^3 + 1,              2α^4 + α^3 + 2,
                 2α^4 + α^3 + α,          2α^4 + α^3 + α + 1,
             2α^4 + α^3 + α + 2,             2α^4 + α^3 + 2α,
            2α^4 + α^3 + 2α + 1,         2α^4 + α^3 + 2α + 2,
               2α^4 + α^3 + α^2,        2α^4 + α^3 + α^2 + 1,
           2α^4 + α^3 + α^2 + 2,        2α^4 + α^3 + α^2 + α,
       2α^4 + α^3 + α^2 + α + 1,    2α^4 + α^3 + α^2 + α + 2,
          2α^4 + α^3 + α^2 + 2α,   2α^4 + α^3 + α^2 + 2α + 1,
      2α^4 + α^3 + α^2 + 2α + 2,           2α^4 + α^3 + 2α^2,
          2α^4 + α^3 + 2α^2 + 1,       2α^4 + α^3 + 2α^2 + 2,
          2α^4 + α^3 + 2α^2 + α,   2α^4 + α^3 + 2α^2 + α + 1,
      2α^4 + α^3 + 2α^2 + α + 2,      2α^4 + α^3 + 2α^2 + 2α,
     2α^4 + α^3 + 2α^2 + 2α + 1,  2α^4 + α^3 + 2α^2 + 2α + 2,
                    2α^4 + 2α^3,             2α^4 + 2α^3 + 1,
                2α^4 + 2α^3 + 2,             2α^4 + 2α^3 + α,
            2α^4 + 2α^3 + α + 1,         2α^4 + 2α^3 + α + 2,
               2α^4 + 2α^3 + 2α,        2α^4 + 2α^3 + 2α + 1,
           2α^4 + 2α^3 + 2α + 2,           2α^4 + 2α^3 + α^2,
          2α^4 + 2α^3 + α^2 + 1,       2α^4 + 2α^3 + α^2 + 2,
          2α^4 + 2α^3 + α^2 + α,   2α^4 + 2α^3 + α^2 + α + 1,
      2α^4 + 2α^3 + α^2 + α + 2,      2α^4 + 2α^3 + α^2 + 2α,
     2α^4 + 2α^3 + α^2 + 2α + 1,  2α^4 + 2α^3 + α^2 + 2α + 2,
             2α^4 + 2α^3 + 2α^2,      2α^4 + 2α^3 + 2α^2 + 1,
         2α^4 + 2α^3 + 2α^2 + 2,      2α^4 + 2α^3 + 2α^2 + α,
     2α^4 + 2α^3 + 2α^2 + α + 1,  2α^4 + 2α^3 + 2α^2 + α + 2,
        2α^4 + 2α^3 + 2α^2 + 2α, 2α^4 + 2α^3 + 2α^2 + 2α + 1,
    2α^4 + 2α^3 + 2α^2 + 2α + 2], order=3^5)
In [81]: GF.Elements()
Out[81]: 
GF([    0,     1, α^121,     α,  α^69,   α^5, α^122, α^126, α^190,   α^2,
     α^46,  α^74,  α^70,  α^10, α^209,   α^6, α^138, α^222, α^123, α^195,
    α^167, α^127, α^101,  α^17, α^191,  α^88, α^131,   α^3, α^207,  α^15,
     α^47, α^214,  α^49,  α^75, α^198, α^149,  α^71, α^227, α^230,  α^11,
    α^115, α^216, α^210,  α^30, α^143,   α^7, α^112,  α^36, α^139,  α^61,
     α^51, α^223,  α^79, α^160, α^124, α^136,  α^86, α^196,  α^28,  α^77,
    α^168, α^170,  α^93, α^128, α^157, α^233, α^102,  α^39, α^200,  α^18,
    α^172, α^182, α^192, α^109, α^106,  α^89,  α^22, α^151, α^132,  α^95,
    α^236,   α^4, α^189, α^120, α^208, α^221,  α^73,  α^16, α^130, α^166,
     α^48, α^148,  α^14, α^215, α^142, α^229,  α^50, α^159,  α^35,  α^76,
     α^92,  α^85, α^199, α^181, α^232, α^150, α^235, α^105,  α^72, α^165,
    α^119, α^228,  α^34,  α^13, α^231, α^104,  α^84,  α^12,  α^83, α^118,
    α^116,  α^64, α^117, α^217,  α^41,  α^65, α^211,  α^25,  α^66,  α^31,
     α^56, α^218, α^144, α^202,  α^42,   α^8,  α^99,  α^67, α^113,  α^59,
    α^212,  α^37,  α^20,  α^26, α^140, α^179, α^219,  α^62,  α^54,  α^32,
     α^52, α^174,  α^57, α^224, α^154,  α^43,  α^80, α^176, α^145, α^161,
    α^184, α^203, α^125, α^241,  α^68, α^137,  α^45,   α^9,  α^87, α^194,
    α^100, α^197, α^206, α^213,  α^29, α^226, α^114,  α^78, α^111,  α^60,
    α^169, α^135,  α^27, α^171, α^156,  α^38,  α^94, α^108,  α^21, α^129,
    α^188, α^220, α^158, α^147, α^141, α^234,  α^91, α^180, α^103, α^164,
     α^33,  α^40,  α^82,  α^63, α^201,  α^24,  α^55,  α^19,  α^98,  α^58,
    α^173, α^178,  α^53, α^183, α^153, α^175, α^193, α^240,  α^44, α^110,
    α^205, α^225, α^107, α^134, α^155,  α^90, α^187, α^146,  α^23, α^163,
     α^81, α^152,  α^97, α^177, α^133, α^239, α^204,  α^96, α^186, α^162,
    α^237, α^238, α^185], order=3^5)

Random arrays

The galois.FieldArray.Random() classmethod provides a random array of the specified shape. This is convenient for testing. The integer low and high values are the integer representation of the polynomial field elements.

In [82]: GF.Random(4, seed=1234)
Out[82]: GF([176, 177, 172, 237], order=3^5)

In [83]: GF.Random(4, low=10, high=20, seed=5678)
Out[83]: GF([11, 18, 12, 10], order=3^5)
In [84]: GF.Random(4, seed=1234)
Out[84]: 
GF([    2α^4 + α^2 + α + 2,        2α^4 + α^2 + 2α,
            2α^4 + α^2 + 1, 2α^4 + 2α^3 + 2α^2 + α], order=3^5)

In [85]: GF.Random(4, low=10, high=20, seed=5678)
Out[85]: GF([α^2 + 2,    2α^2, α^2 + α, α^2 + 1], order=3^5)
In [86]: GF.Random(4, seed=1234)
Out[86]: GF([α^114,  α^78, α^206,  α^96], order=3^5)

In [87]: GF.Random(4, low=10, high=20, seed=5678)
Out[87]: GF([ α^74, α^123,  α^70,  α^46], order=3^5)

Data types

Galois field arrays support a fixed set of NumPy data types (numpy.dtype). The data type must be able to store all the field elements (in their integer representation).

Valid data types

For small finite fields, like \(\mathrm{GF}(2^4)\), every NumPy integer data type is supported.

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

In [89]: GF.dtypes
Out[89]: 
[numpy.uint8,
 numpy.uint16,
 numpy.uint32,
 numpy.int8,
 numpy.int16,
 numpy.int32,
 numpy.int64]

For medium finite fields, like \(\mathrm{GF}(2^{10})\), some NumPy integer data types are not supported. Here, numpy.uint8 and numpy.int8 are not supported.

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

In [91]: GF.dtypes
Out[91]: [numpy.uint16, numpy.uint32, numpy.int16, numpy.int32, numpy.int64]

For large finite fields, like \(\mathrm{GF}(2^{100})\), only the “object” data type (numpy.object_) is supported. This uses arrays of Python objects, rather than integer data types. For Galois field arrays, the Python objects used are Python integers, which have unlimited size.

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

In [93]: GF.dtypes
Out[93]: [numpy.object_]

Default data type

When arrays are created, unless otherwise specified, they use the default data type. The default data type is the smallest unsigned data type (the first in the galois.FieldClass.dtypes list).

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

In [95]: GF.dtypes
Out[95]: [numpy.uint16, numpy.uint32, numpy.int16, numpy.int32, numpy.int64]

In [96]: x = GF.Random(4); x
Out[96]: GF([494, 162, 297, 357], order=2^10)

In [97]: x.dtype
Out[97]: dtype('uint16')
In [98]: GF = galois.GF(2**100)

In [99]: GF.dtypes
Out[99]: [numpy.object_]

In [100]: x = GF.Random(4); x
Out[100]: 
GF([1189623781819391087880430657130,   55078512358789612746310174353,
     277541231948696570253357980326,  358312569506377661897321945715],
   order=2^100)

In [101]: x.dtype
Out[101]: dtype('O')

Changing data types

The data type may be explicitly set during array creation by setting the dtype keyword argument of the galois.FieldArray constructor.

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

In [103]: x = GF([273, 388, 124, 400], dtype=np.uint32); x
Out[103]: GF([273, 388, 124, 400], order=2^10)

In [104]: x.dtype
Out[104]: dtype('uint32')

Arrays may also have their data types changed using .astype(). The data type must be valid, however.

In [105]: x.dtype
Out[105]: dtype('uint32')

In [106]: x = x.astype(np.int64)

In [107]: x.dtype
Out[107]: dtype('int64')

Last update: Apr 03, 2022