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([467, 693, 976, 973], 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([ 511486478158220197791320352300, 833895380486426855319156517744,
681856390588371112211533322790, 1128488807481347881211256849652],
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')