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.properties)
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.properties)
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.properties)
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 scalar¶
A single finite field element (a scalar) is a 0-D FieldArray
. They are created by passing a single
ElementLike
object to GF
’s constructor.
In [7]: a = GF(17); a
Out[7]: GF(17, order=3^5)
In [8]: a = GF("x^2 + 2x + 2"); a
Out[8]: GF(17, order=3^5)
In [9]: a.ndim
Out[9]: 0
In [10]: a = GF(17); a
Out[10]: GF(α^2 + 2α + 2, order=3^5)
In [11]: a = GF("x^2 + 2x + 2"); a
Out[11]: GF(α^2 + 2α + 2, order=3^5)
In [12]: a.ndim
Out[12]: 0
In [13]: a = GF(17); a
Out[13]: GF(α^222, order=3^5)
In [14]: a = GF("x^2 + 2x + 2"); a
Out[14]: GF(α^222, order=3^5)
In [15]: a.ndim
Out[15]: 0
Create a new array¶
Array-Like objects¶
A FieldArray
can be created from various ArrayLike
objects.
In [16]: GF([17, 4, 148, 205])
Out[16]: GF([ 17, 4, 148, 205], order=3^5)
In [17]: GF([["x^2 + 2x + 2", 4], ["x^4 + 2x^3 + x^2 + x + 1", 205]])
Out[17]:
GF([[ 17, 4],
[148, 205]], order=3^5)
In [18]: GF([17, 4, 148, 205])
Out[18]:
GF([ α^2 + 2α + 2, α + 1,
α^4 + 2α^3 + α^2 + α + 1, 2α^4 + α^3 + α^2 + 2α + 1], order=3^5)
In [19]: GF([["x^2 + 2x + 2", 4], ["x^4 + 2x^3 + x^2 + x + 1", 205]])
Out[19]:
GF([[ α^2 + 2α + 2, α + 1],
[ α^4 + 2α^3 + α^2 + α + 1, 2α^4 + α^3 + α^2 + 2α + 1]], order=3^5)
In [20]: GF([17, 4, 148, 205])
Out[20]: GF([α^222, α^69, α^54, α^24], order=3^5)
In [21]: GF([["x^2 + 2x + 2", 4], ["x^4 + 2x^3 + x^2 + x + 1", 205]])
Out[21]:
GF([[α^222, α^69],
[ α^54, α^24]], order=3^5)
Polynomial coefficients¶
Rather than strings, the polynomial coefficients may be passed into GF
’s constructor as length-\(m\) vectors using
the Vector()
classmethod.
In [22]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[22]: GF([17, 4], order=3^5)
In [23]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[23]: GF([α^2 + 2α + 2, α + 1], order=3^5)
In [24]: GF.Vector([[0, 0, 1, 2, 2], [0, 0, 0, 1, 1]])
Out[24]: GF([α^222, α^69], order=3^5)
The 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 [25]: GF([17, 4]).vector()
Out[25]:
GF([[0, 0, 1, 2, 2],
[0, 0, 0, 1, 1]], order=3)
In [26]: GF([17, 4]).vector()
Out[26]:
GF([[0, 0, 1, 2, 2],
[0, 0, 0, 1, 1]], order=3)
In [27]: GF([17, 4]).vector()
Out[27]:
GF([[0, 0, 1, 2, 2],
[0, 0, 0, 1, 1]], order=3)
Primitive element powers¶
A FieldArray
can also be created from the powers of a primitive element \(\alpha\).
In [28]: alpha = GF.primitive_element; alpha
Out[28]: GF(3, order=3^5)
In [29]: powers = np.array([222, 69, 54, 24]); powers
Out[29]: array([222, 69, 54, 24])
In [30]: alpha ** powers
Out[30]: GF([ 17, 4, 148, 205], order=3^5)
In [31]: alpha = GF.primitive_element; alpha
Out[31]: GF(α, order=3^5)
In [32]: powers = np.array([222, 69, 54, 24]); powers
Out[32]: array([222, 69, 54, 24])
In [33]: alpha ** powers
Out[33]:
GF([ α^2 + 2α + 2, α + 1,
α^4 + 2α^3 + α^2 + α + 1, 2α^4 + α^3 + α^2 + 2α + 1], order=3^5)
In [34]: alpha = GF.primitive_element; alpha
Out[34]: GF(α, order=3^5)
In [35]: powers = np.array([222, 69, 54, 24]); powers
Out[35]: array([222, 69, 54, 24])
In [36]: alpha ** powers
Out[36]: GF([α^222, α^69, α^54, α^24], order=3^5)
NumPy array¶
An integer NumPy array may also be passed into GF
. The default keyword argument copy=True
of the FieldArray
constructor will create a copy of the array.
In [37]: x_np = np.array([213, 167, 4, 214, 209]); x_np
Out[37]: array([213, 167, 4, 214, 209])
In [38]: x = GF(x_np); x
Out[38]: GF([213, 167, 4, 214, 209], order=3^5)
# Modifying x does not modify x_np
In [39]: x[0] = 0; x_np
Out[39]: array([213, 167, 4, 214, 209])
In [40]: x_np = np.array([213, 167, 4, 214, 209]); x_np
Out[40]: array([213, 167, 4, 214, 209])
In [41]: x = GF(x_np); x
Out[41]:
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 [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]); x_np
Out[43]: array([213, 167, 4, 214, 209])
In [44]: x = GF(x_np); x
Out[44]: GF([α^183, α^9, α^69, α^153, α^58], 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])
View an existing array¶
Instead of creating a FieldArray
explicitly, you can convert an existing NumPy array into a FieldArray
temporarily and work with it in-place.
Simply call .view(GF)
to view the NumPy array as a FieldArray
. When finished working in the
finite field, call .view(np.ndarray)
to view it back to a NumPy array.
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 = x_np.view(GF); x
Out[47]: GF([213, 167, 4, 214, 209], order=3^5)
# Modifying x does modify x_np!
In [48]: x[0] = 0; x_np
Out[48]: array([ 0, 167, 4, 214, 209])
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([ 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 [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([α^183, α^9, α^69, α^153, α^58], order=3^5)
# Modifying x does modify x_np!
In [54]: x[0] = 0; x_np
Out[54]: array([ 0, 167, 4, 214, 209])
Classmethods¶
Several classmethods are provided in FieldArray
to assist with creating arrays.
Constant arrays¶
The Zeros()
and Ones()
classmethods provide constant arrays that are
useful for initializing empty arrays.
In [55]: GF.Zeros(4)
Out[55]: GF([0, 0, 0, 0], order=3^5)
In [56]: GF.Ones(4)
Out[56]: GF([1, 1, 1, 1], order=3^5)
In [57]: GF.Zeros(4)
Out[57]: GF([0, 0, 0, 0], order=3^5)
In [58]: GF.Ones(4)
Out[58]: GF([1, 1, 1, 1], order=3^5)
In [59]: GF.Zeros(4)
Out[59]: GF([0, 0, 0, 0], order=3^5)
In [60]: GF.Ones(4)
Out[60]: GF([1, 1, 1, 1], order=3^5)
Note
There is no numpy.empty()
equivalent. This is because FieldArray
instances must have values in
\([0, p^m)\). Empty NumPy arrays have whatever values are currently in memory, and therefore would fail those
bounds checks.
Ordered arrays¶
The 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 [61]: GF.Range(10, 20)
Out[61]: GF([10, 11, 12, 13, 14, 15, 16, 17, 18, 19], order=3^5)
In [62]: GF.Range(10, 20)
Out[62]:
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 [63]: GF.Range(10, 20)
Out[63]:
GF([ α^46, α^74, α^70, α^10, α^209, α^6, α^138, α^222, α^123, α^195],
order=3^5)
The Elements()
classmethod provides a 1-D array of all the finite field elements.
In [64]: GF.Elements()
Out[64]:
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 [65]: GF.Elements()
Out[65]:
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 [66]: GF.Elements()
Out[66]:
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 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 [67]: GF.Random(4, seed=1234)
Out[67]: GF([176, 177, 172, 237], order=3^5)
In [68]: GF.Random(4, low=10, high=20, seed=5678)
Out[68]: GF([11, 18, 12, 10], order=3^5)
In [69]: GF.Random(4, seed=1234)
Out[69]:
GF([ 2α^4 + α^2 + α + 2, 2α^4 + α^2 + 2α,
2α^4 + α^2 + 1, 2α^4 + 2α^3 + 2α^2 + α], order=3^5)
In [70]: GF.Random(4, low=10, high=20, seed=5678)
Out[70]: GF([α^2 + 2, 2α^2, α^2 + α, α^2 + 1], order=3^5)
In [71]: GF.Random(4, seed=1234)
Out[71]: GF([α^114, α^78, α^206, α^96], order=3^5)
In [72]: GF.Random(4, low=10, high=20, seed=5678)
Out[72]: GF([ α^74, α^123, α^70, α^46], order=3^5)
Data types¶
FieldArray
instances 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 [73]: GF = galois.GF(2**4)
In [74]: GF.dtypes
Out[74]:
[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 [75]: GF = galois.GF(2**10)
In [76]: GF.dtypes
Out[76]: [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. The Python objects used are Python integers,
which have unlimited size.
In [77]: GF = galois.GF(2**100)
In [78]: GF.dtypes
Out[78]: [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 dtypes
list).
In [79]: GF = galois.GF(2**10)
In [80]: GF.dtypes
Out[80]: [numpy.uint16, numpy.uint32, numpy.int16, numpy.int32, numpy.int64]
In [81]: x = GF.Random(4); x
Out[81]: GF([759, 434, 161, 42], order=2^10)
In [82]: x.dtype
Out[82]: dtype('uint16')
In [83]: GF = galois.GF(2**100)
In [84]: GF.dtypes
Out[84]: [numpy.object_]
In [85]: x = GF.Random(4); x
Out[85]:
GF([ 765231818740739564335799726327, 336142615569941386981697205540,
457648668243923079875807682403, 1140225852527060499051433715899],
order=2^100)
In [86]: x.dtype
Out[86]: dtype('O')
Changing data types¶
The data type may be explicitly set during array creation by setting the dtype
keyword argument of the FieldArray
constructor.
In [87]: GF = galois.GF(2**10)
In [88]: x = GF([273, 388, 124, 400], dtype=np.uint32); x
Out[88]: GF([273, 388, 124, 400], order=2^10)
In [89]: x.dtype
Out[89]: dtype('uint32')
Arrays may also have their data types changed using .astype()
. The data type must be valid, however.
In [90]: x.dtype
Out[90]: dtype('uint32')
In [91]: x = x.astype(np.int64)
In [92]: x.dtype
Out[92]: dtype('int64')