Skip to content

Commit

Permalink
Define Poly.__index__() to support bin(), oct(), and hex()
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Mar 21, 2022
1 parent 6816adc commit 7f8ce52
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 53 deletions.
129 changes: 89 additions & 40 deletions docs/basic-usage/poly-creation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ Create a polynomial by specifying its coefficients in degree-descending order an

.. ipython:: python
GF = galois.GF(2**8)
galois.Poly([1, 0, 0, 55, 23], field=GF)
GF = galois.GF(2**8)
galois.Poly([1, 0, 0, 55, 23], field=GF)
Or pass a *Galois field array* of coefficients without explicitly specifying the finite field.

.. ipython:: python
coeffs = GF([1, 0, 0, 55, 23]); coeffs
galois.Poly(coeffs)
coeffs = GF([1, 0, 0, 55, 23]); coeffs
galois.Poly(coeffs)
Element representation
----------------------
Expand All @@ -28,18 +28,18 @@ by setting the `display` keyword argument of :func:`galois.GF` or using the :fun

.. ipython:: python
GF = galois.GF(3**5)
GF = galois.GF(3**5)
# Display f using the default integer representation
f = galois.Poly([13, 0, 4, 2], field=GF); f
# Display f using the default integer representation
f = galois.Poly([13, 0, 4, 2], field=GF); f
# Display f using the polynomial representation
GF.display("poly"); f
# Display f using the polynomial representation
GF.display("poly"); f
# Display f using the power representation
GF.display("power"); f
# Display f using the power representation
GF.display("power"); f
GF.display("int");
GF.display("int");
See :ref:`Field Element Representation` for more details.

Expand All @@ -56,26 +56,49 @@ Create a polynomial by specifying its non-zero degrees and coefficients using :f

.. ipython:: python
galois.Poly.Degrees([8, 1], coeffs=[1, 179], field=GF)
galois.Poly.Degrees([8, 1], coeffs=[1, 179], field=GF)
Create a polynomial from its integer representation using :func:`galois.Poly.Int`.
Create a polynomial from its integer representation using :func:`galois.Poly.Int`. Additionally, one may create a polynomial from
a binary, octal, or hexadecimal string of its integer representation.

.. ipython:: python
.. tab-set::

.. tab-item:: Integer

.. ipython:: python
galois.Poly.Int(268, field=GF)
.. tab-item:: Binary string

.. ipython:: python
galois.Poly.Int(int("0b1011", 2))
.. tab-item:: Octal string

.. ipython:: python
galois.Poly.Int(int("0o5034", 8), field=galois.GF(2**3))
.. tab-item:: Hex string

.. ipython:: python
galois.Poly.Int(268, field=GF)
galois.Poly.Int(int("0xf700a275", 16), field=galois.GF(2**8))
Create a polynomial from its string representation using :func:`galois.Poly.Str`.

.. ipython:: python
galois.Poly.Str("x^5 + 143", field=GF)
galois.Poly.Str("x^5 + 143", field=GF)
Create a polynomial from its roots using :func:`galois.Poly.Roots`.

.. ipython:: python
f = galois.Poly.Roots([137, 22, 51], field=GF); f
f.roots()
f = galois.Poly.Roots([137, 22, 51], field=GF); f
f.roots()
Simple polynomials
..................
Expand All @@ -85,9 +108,9 @@ simple polynomials. They are included for convenience.

.. ipython:: python
galois.Poly.Zero(GF)
galois.Poly.One(GF)
galois.Poly.Identity(GF)
galois.Poly.Zero(GF)
galois.Poly.One(GF)
galois.Poly.Identity(GF)
Random polynomials
..................
Expand All @@ -96,7 +119,7 @@ Random polynomials of a given degree are easily created with :func:`galois.Poly.

.. ipython:: python
galois.Poly.Random(4, field=GF)
galois.Poly.Random(4, field=GF)
Methods
-------
Expand All @@ -107,15 +130,15 @@ Compute the derivative of a polynomial using :func:`galois.Poly.derivative`.

.. ipython:: python
GF = galois.GF(7)
f = galois.Poly([1, 0, 5, 2, 3], field=GF); f
f.derivative()
GF = galois.GF(7)
f = galois.Poly([1, 0, 5, 2, 3], field=GF); f
f.derivative()
Compute the roots of a polynomial using :func:`galois.Poly.roots`.

.. ipython:: python
f.roots()
f.roots()
Properties
----------
Expand All @@ -127,22 +150,48 @@ and :obj:`galois.Poly.nonzero_coeffs`.

.. ipython:: python
GF = galois.GF(7)
f = galois.Poly([1, 0, 3], field=GF); f
f.nonzero_degrees
f.nonzero_coeffs
GF = galois.GF(7)
f = galois.Poly([1, 0, 3], field=GF); f
f.nonzero_degrees
f.nonzero_coeffs
Find the integer equivalent of the polynomial using :func:`galois.Poly.__int__`.
Find the integer equivalent of the polynomial using :func:`int`, see :func:`galois.Poly.__int__`. Additionally, one may
convert a polynomial into the binary, octal, or hexadecimal string of its integer representation.

.. ipython:: python
.. tab-set::

.. tab-item:: Integer

.. ipython:: python
int(f)
.. tab-item:: Binary string

.. ipython:: python
g = galois.Poly([1, 0, 1, 1]); g
bin(g)
.. tab-item:: Octal string

.. ipython:: python
g = galois.Poly([5, 0, 3, 4], field=galois.GF(2**3)); g
oct(g)
.. tab-item:: Hex string

.. ipython:: python
int(f)
g = galois.Poly([0xf7, 0x00, 0xa2, 0x75], field=galois.GF(2**8)); g
hex(g)
Get the string representation of the polynomial using :func:`str`.

.. ipython:: python
str(f)
str(f)
Special polynomials
-------------------
Expand All @@ -153,18 +202,18 @@ Find one or all irreducible polynomials with :func:`galois.irreducible_poly` and

.. ipython:: python
galois.irreducible_poly(3, 3)
galois.irreducible_polys(3, 3)
galois.irreducible_poly(3, 3)
galois.irreducible_polys(3, 3)
Find one or all primitive polynomials with :func:`galois.primitive_poly` and :func:`galois.primitive_polys`.

.. ipython:: python
galois.primitive_poly(3, 3)
galois.primitive_polys(3, 3)
galois.primitive_poly(3, 3)
galois.primitive_polys(3, 3)
Find the Conway polynomial using :func:`galois.conway_poly`.

.. ipython:: python
galois.conway_poly(3, 3)
galois.conway_poly(3, 3)
63 changes: 50 additions & 13 deletions galois/_fields/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3164,7 +3164,7 @@ def Str(cls, string: str, field: Optional[FieldClass] = GF2) -> "Poly":
str(f)
"""
if not isinstance(string, str):
raise TypeError(f"Argument `string` be an string, not {type(string)}")
raise TypeError(f"Argument `string` be a string, not {type(string)}")

return Poly.Degrees(*str_to_sparse_poly(string), field=field)

Expand All @@ -3189,22 +3189,55 @@ def Int(cls, integer: int, field: Optional[FieldClass] = GF2) -> "Poly":
Examples
--------
Construct a polynomial over :math:`\mathrm{GF}(2)` from its integer representation.
.. tab-set::
.. ipython:: python
.. tab-item:: Integer
f = galois.Poly.Int(5); f
int(f)
Construct a polynomial over :math:`\mathrm{GF}(2)` from its integer representation.
Construct a polynomial over :math:`\mathrm{GF}(3^5)` from its integer representation.
.. ipython:: python
.. ipython:: python
f = galois.Poly.Int(5); f
int(f)
GF = galois.GF(3**5)
f = galois.Poly.Int(186535908, field=GF); f
int(f)
# The polynomial/integer equivalence
int(f) == 13*GF.order**3 + 117
Construct a polynomial over :math:`\mathrm{GF}(3^5)` from its integer representation.
.. ipython:: python
GF = galois.GF(3**5)
f = galois.Poly.Int(186535908, field=GF); f
int(f)
# The polynomial/integer equivalence
int(f) == 13*GF.order**3 + 117
.. tab-item:: Binary string
Construct a polynomial over :math:`\mathrm{GF}(2)` from its binary string.
.. ipython:: python
f = galois.Poly.Int(int("0b1011", 2)); f
bin(f)
.. tab-item:: Octal string
Construct a polynomial over :math:`\mathrm{GF}(2^3)` from its octal string.
.. ipython:: python
GF = galois.GF(2**3)
f = galois.Poly.Int(int("0o5034", 8), field=GF); f
oct(f)
.. tab-item:: Hex string
Construct a polynomial over :math:`\mathrm{GF}(2^8)` from its hexadecimal string.
.. ipython:: python
GF = galois.GF(2**8)
f = galois.Poly.Int(int("0xf700a275", 16), field=GF); f
hex(f)
"""
if not isinstance(integer, (int, np.integer)):
raise TypeError(f"Argument `integer` be an integer, not {type(integer)}")
Expand Down Expand Up @@ -3729,6 +3762,10 @@ def __str__(self) -> str:
"""
return sparse_poly_to_str(self.nonzero_degrees, self.nonzero_coeffs)

def __index__(self) -> int:
# Define __index__ to enable use of bin(), oct(), and hex()
return sparse_poly_to_integer(self.nonzero_degrees, self.nonzero_coeffs, self.field.order)

def __int__(self) -> int:
r"""
The integer representation of the polynomial.
Expand All @@ -3753,7 +3790,7 @@ def __int__(self) -> int:
int(f)
int(f) == 3*GF.order**3 + 5*GF.order**1 + 2*GF.order**0
"""
return sparse_poly_to_integer(self.nonzero_degrees, self.nonzero_coeffs, self.field.order)
return self.__index__()

def __hash__(self):
t = tuple([self.field.order,] + self.nonzero_degrees.tolist() + self.nonzero_coeffs.tolist())
Expand Down
17 changes: 17 additions & 0 deletions tests/polys/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,23 @@ def test_int():
assert int(poly) == 4295000729


def test_bin():
poly = galois.Poly([1, 0, 1, 1])
assert bin(poly) == "0b1011"


def test_oct():
GF = galois.GF(2**3)
poly = galois.Poly([5, 0, 3, 4], field=GF)
assert oct(poly) == "0o5034"


def test_hex():
GF = galois.GF(2**8)
poly = galois.Poly([0xf7, 0x00, 0xa2, 0x75], field=GF)
assert hex(poly) == "0xf700a275"


def test_equal(field):
# NOTE: GF(11) is not included in the `field` pytest fixture
c = field.Random(6)
Expand Down

0 comments on commit 7f8ce52

Please sign in to comment.