Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit test review before 0.1.0 release #164

Merged
merged 26 commits into from
Aug 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c867d76
Update irreducible and primitive poly unit tests
mhostetter Aug 5, 2021
de16017
Rework testing minimal polynomials
mhostetter Aug 5, 2021
4d4a1c3
Rework testing primitive elements
mhostetter Aug 5, 2021
fbd04fc
Rework unit testing of polynomial GCDs
mhostetter Aug 6, 2021
d31fb29
Rework unit testing of `poly_pow()`
mhostetter Aug 6, 2021
4859068
Add downloads badge to README
mhostetter Aug 6, 2021
bc0f0e9
Rework unit testing of polynomial factorization
mhostetter Aug 6, 2021
ddb56e7
Rework unit testing of number theoretic functions
mhostetter Aug 6, 2021
9566451
Don't update display mode of a Galois field class with defaults
mhostetter Aug 7, 2021
978f6e2
Don't update ufunc mode of a Galois field class with defaults
mhostetter Aug 7, 2021
2bb6331
Use polynomial indeterminate "x" for `repr_table()`
mhostetter Aug 7, 2021
a4871ff
Rework unit testing of Galois field class factory function
mhostetter Aug 7, 2021
77f8193
Disable code coverage on JIT-compiled functions
mhostetter Aug 7, 2021
fb9efd5
Add first version of project logo
mhostetter Aug 7, 2021
ed8f435
Fix literal file includes in docs
mhostetter Aug 7, 2021
e90642a
Rework unit testing of FEC codes
mhostetter Aug 7, 2021
5861a63
Allow polynomial strings as input to `galois.GF()`
mhostetter Aug 7, 2021
decc245
Update basic usage examples
mhostetter Aug 7, 2021
fce347b
Make TOC in README have only one level
mhostetter Aug 7, 2021
b5e633e
Remove `nbsphinx` docs dependency
mhostetter Aug 7, 2021
e57810c
Increase logo resolution
mhostetter Aug 7, 2021
5a44247
Add GitHub social media logo
mhostetter Aug 7, 2021
4dafaaf
Add citation style
mhostetter Aug 7, 2021
3b38c70
Add acknowledgements section to docs
mhostetter Aug 8, 2021
c4b0383
Add versioning section to docs
mhostetter Aug 8, 2021
2342e4f
Add features section to docs
mhostetter Aug 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"python.testing.pytestEnabled": true,
"python.linting.pylintEnabled": true,
"python.linting.enabled": true,
"restructuredtext.confPath": "${workspaceFolder}/docs"
"markdown.extension.toc.levels": "2..2"
}
251 changes: 105 additions & 146 deletions README.md

Large diffs are not rendered by default.

Binary file removed docs/_static/img/evariste.jpg
Binary file not shown.
10 changes: 10 additions & 0 deletions docs/acknowledgements.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Acknowledgements

- This library is an extension of, and completely dependent on, [NumPy](https://numpy.org/).
- We heavily rely on [Numba](https://numba.pydata.org/) and its just-in-time compiler for optimizing performance of Galois field arithmetic.
- We use Frank Luebeck's compilation of [Conway polynomials](http://www.math.rwth-aachen.de/~Frank.Luebeck/data/ConwayPol/index.html).
- We also use Wolfram's compilation of [primitive polynomials](https://datarepository.wolframcloud.com/resources/Primitive-Polynomials/).
- We extensively use [SageMath](https://www.sagemath.org/) for generating test vectors.
- We also use [Octave](https://www.gnu.org/software/octave/index) for generating test vectors.

Many thanks!
4 changes: 2 additions & 2 deletions docs/api/polys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ Polynomial functions
poly_pow
poly_factors

Special polynomial creation
---------------------------
Special polynomials
-------------------

.. rubric::
.. autosummary::
Expand Down
104 changes: 64 additions & 40 deletions docs/basic-usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,19 @@ Basic Usage

The main idea of the :obj:`galois` package can be summarized as follows. The user creates a "Galois field array class" using `GF = galois.GF(p**m)`.
A Galois field array class `GF` is a subclass of :obj:`numpy.ndarray` and its constructor `x = GF(array_like)` mimics
the call signature of :func:`numpy.array`. A Galois field array `x` is operated on like any other numpy array, but all
the call signature of :func:`numpy.array`. A Galois field array `x` is operated on like any other NumPy array, but all
arithmetic is performed in :math:`\mathrm{GF}(p^m)` not :math:`\mathbb{Z}` or :math:`\mathbb{R}`.

Internally, the Galois field arithmetic is implemented by replacing `numpy ufuncs <https://numpy.org/doc/stable/reference/ufuncs.html>`_.
The new ufuncs are written in python and then `just-in-time compiled <https://numba.pydata.org/numba-doc/dev/user/vectorize.html>`_ with
`numba <https://numba.pydata.org/>`_. The ufuncs can be configured to use either lookup tables (for speed) or explicit
calculation (for memory savings). Numba also provides the ability to `"target" <https://numba.readthedocs.io/en/stable/user/vectorize.html?highlight=target>`_
the JIT-compiled ufuncs for CPUs or GPUs.
Internally, the Galois field arithmetic is implemented by replacing `NumPy ufuncs <https://numpy.org/doc/stable/reference/ufuncs.html>`_.
The new ufuncs are written in Python and then `just-in-time compiled <https://numba.pydata.org/numba-doc/dev/user/vectorize.html>`_ with
`Numba <https://numba.pydata.org/>`_. The ufuncs can be configured to use either lookup tables (for speed) or explicit
calculation (for memory savings).

In addition to normal array arithmetic, :obj:`galois` also supports linear algebra (with :obj:`numpy.linalg` functions) and polynomials over Galois fields
(with the :obj:`galois.Poly` class).
Galois field arrays
-------------------

Class construction
------------------
..................

Galois field array classes are created using the :func:`galois.GF` class factory function.

Expand Down Expand Up @@ -47,19 +46,19 @@ is calculated or displayed. See the attributes and methods in :obj:`galois.Field
# Access each attribute individually
GF256.irreducible_poly

The :obj:`galois` package even supports arbitrarily-large fields! This is accomplished by using numpy arrays
with `dtype=object` and pure-python ufuncs. This comes at a performance penalty compared to smaller fields
which use numpy integer dtypes (e.g., :obj:`numpy.uint32`) and have compiled ufuncs.
The :obj:`galois` package even supports arbitrarily-large fields! This is accomplished by using NumPy arrays
with `dtype=object` and pure-Python ufuncs. This comes at a performance penalty compared to smaller fields
which use NumPy integer dtypes (e.g., :obj:`numpy.uint32`) and have compiled ufuncs.

.. ipython:: python

GF = galois.GF(36893488147419103183); print(GF.properties)
GF = galois.GF(2**100); print(GF.properties)

Array creation
--------------
..............

Galois field arrays can be created from existing numpy arrays.
Galois field arrays can be created from existing NumPy arrays.

.. ipython:: python

Expand Down Expand Up @@ -96,27 +95,27 @@ manager, the display mode will only be temporarily changed.

.. ipython:: python

x = GF256(["y**6 + 1", 0, 2, "1", "y**5 + y**4 + y"]); x
a = GF256(["x^6 + 1", 0, 2, "1", "x^5 + x^4 + x"]); a

# Set the display mode to represent GF(2^8) field elements as polynomials over GF(2) with degree less than 8
GF256.display("poly");
x
a

# Temporarily set the display mode to represent GF(2^8) field elements as powers of the primitive element
with GF256.display("power"):
print(x)
print(a)

# Resets the display mode to the integer representation
GF256.display();

Field arithmetic
----------------
................

Galois field arrays are treated like any other numpy array. Array arithmetic is performed using python operators or numpy
Galois field arrays are treated like any other NumPy array. Array arithmetic is performed using Python operators or NumPy
functions.

In the list below, `GF` is a Galois field array class created by `GF = galois.GF(p**m)`, `x` and `y` are `GF` arrays, and `z` is an
integer `numpy.ndarray`. All arithmetic operations follow normal numpy `broadcasting <https://numpy.org/doc/stable/user/basics.broadcasting.html>`_ rules.
integer :obj:`numpy.ndarray`. All arithmetic operations follow normal NumPy `broadcasting <https://numpy.org/doc/stable/user/basics.broadcasting.html>`_ rules.

- Addition: `x + y == np.add(x, y)`
- Subtraction: `x - y == np.subtract(x, y)`
Expand All @@ -138,9 +137,9 @@ integer `numpy.ndarray`. All arithmetic operations follow normal numpy `broadcas
x + y

Linear algebra
--------------
..............

The :obj:`galois` package intercepts relevant calls to numpy's linear algebra functions and performs the specified
The :obj:`galois` package intercepts relevant calls to NumPy's linear algebra functions and performs the specified
operation in :math:`\mathrm{GF}(p^m)` not in :math:`\mathbb{R}`. Some of these functions include:

- :func:`np.dot`, :func:`np.vdot`, :func:`np.inner`, :func:`np.outer`, :func:`np.matmul`, :func:`np.linalg.matrix_power`
Expand All @@ -157,14 +156,14 @@ operation in :math:`\mathrm{GF}(p^m)` not in :math:`\mathbb{R}`. Some of these f
x = np.linalg.solve(A, b); x
np.array_equal(A @ x, b)

Galois field arrays also contain matrix decomposition routines not included in numpy. These include:
Galois field arrays also contain matrix decomposition routines not included in NumPy. These include:

- :func:`galois.FieldArray.row_reduce`, :func:`galois.FieldArray.lu_decompose`, :func:`galois.FieldArray.lup_decompose`

Numpy ufunc methods
-------------------
NumPy ufunc methods
...................

Galois field arrays support `numpy ufunc methods <https://numpy.org/devdocs/reference/ufuncs.html#methods>`_. This allows the user to apply a ufunc in a unique way across the target
Galois field arrays support `NumPy ufunc methods <https://numpy.org/devdocs/reference/ufuncs.html#methods>`_. This allows the user to apply a ufunc in a unique way across the target
array. The ufunc method signature is `<ufunc>.<method>(*args, **kwargs)`. All arithmetic ufuncs are supported. Below
is a list of their ufunc methods.

Expand All @@ -181,15 +180,8 @@ is a list of their ufunc methods.
y = GF256.Random(5); y
np.multiply.outer(x, y)

Numpy functions
---------------

Many other relevant numpy functions are supported on Galois field arrays. These include:

- :func:`np.copy`, :func:`np.concatenate`, :func:`np.insert`, :func:`np.reshape`

Polynomial construction
-----------------------
Polynomials over Galois fields
------------------------------

The :obj:`galois` package supports polynomials over Galois fields with the :obj:`galois.Poly` class. :obj:`galois.Poly`
does not subclass :obj:`numpy.ndarray` but instead contains a :obj:`galois.FieldArray` of coefficients as an attribute
Expand All @@ -205,7 +197,7 @@ object with the `field` keyword argument.
coeffs = GF256([33, 17, 0, 225]); coeffs
p = galois.Poly(coeffs, order="asc"); p

Polynomials over Galois fields can also display the field elements as polynomials over their prime subfields.
Polynomials over Galois fields can also display their coefficients as polynomials over their prime subfields.
This can be quite confusing to read, so be warned!

.. ipython:: python
Expand All @@ -224,10 +216,7 @@ Polynomials can also be created using a number of constructor class methods. The
q = galois.Poly.Roots([155, 37], field=GF256); q
q.roots()

Polynomial arithmetic
---------------------

Polynomial arithmetic is performed using python operators.
Polynomial arithmetic is performed using Python operators.

.. ipython:: python

Expand Down Expand Up @@ -265,3 +254,38 @@ polynomial at one of its elements.

# Since p(x) is a primitive polynomial, alpha is one of its roots
p(alpha, field=GF256)

Forward error correction codes
------------------------------

To demonstrate the FEC code API, here is an example using BCH codes. Other FEC codes have a similar API.

.. ipython:: python

import numpy as np
import galois
bch = galois.BCH(15, 7); bch
bch.generator_poly
# The error-correcting capability
bch.t

A message can be either a 1-D vector or a 2-D matrix of messages. Shortened codes are also supported. See the docs for more details.

.. ipython:: python

# Create a matrix of two messages
M = galois.GF2.Random((2, bch.k)); M

Encoding the message(s) is performed with :func:`galois.BCH.encode`.

.. ipython:: python

C = bch.encode(M); C

Decoding the codeword(s) is performed with :func:`galois.BCH.decode`.

.. ipython:: python

# Corrupt the first bit in each codeword
C[:,0] ^= 1; C
bch.decode(C)
13 changes: 13 additions & 0 deletions docs/citation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Citation

If this library was useful to you in your research, feel free to cite us. Following other Python package
[citation standards](https://github.com/leonoverweel/bibtex-python-package-citations), here is the recommended citation.

```bibtex
@misc{galois,
title={Galois: A performant NumPy extension for Galois fields},
author={Matt Hostetter},
year={2020},
howpublished={\url{https://galois.readthedocs.io/en/stable/}},
}
```
1 change: 0 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@
'sphinx.ext.intersphinx',
'recommonmark',
'sphinx_rtd_theme',
'nbsphinx',
'IPython.sphinxext.ipython_console_highlighting',
'IPython.sphinxext.ipython_directive'
]
Expand Down
6 changes: 3 additions & 3 deletions docs/development.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Lint the package

Linting is done with `pylint <https://www.pylint.org/>`_. The linting dependencies are stored in `requirements-lint.txt`.

.. literalinclude:: ../../requirements-lint.txt
.. literalinclude:: ../requirements-lint.txt
:caption: requirements-lint.txt
:linenos:

Expand All @@ -31,7 +31,7 @@ Unit testing is done through `pytest <https://docs.pytest.org/en/stable/>`_. The
against test vectors, stored in `tests/data/`. generated using `SageMath <https://www.sagemath.org/>`_.
See the `scripts/generate_test_vectors.py` script. The testing dependencies are stored in `requirements-test.txt`.

.. literalinclude:: ../../requirements-test.txt
.. literalinclude:: ../requirements-test.txt
:caption: requirements-test.txt
:linenos:

Expand All @@ -53,7 +53,7 @@ Build the documentation
The documentation is generated with `Sphinx <https://www.sphinx-doc.org/en/master/>`_. The dependencies are
stored in `requirements-doc.txt`.

.. literalinclude:: ../../requirements-doc.txt
.. literalinclude:: ../requirements-doc.txt
:caption: requirements-doc.txt
:linenos:

Expand Down
14 changes: 14 additions & 0 deletions docs/features.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Features
========

- Supports all Galois fields :math:`\mathrm{GF}(p^m)`, even arbitrarily-large fields!
- **Faster** than native NumPy! `GF(x) * GF(y)` is faster than `(x * y) % p` for :math:`\mathrm{GF}(p)`
- Seamless integration with NumPy -- normal NumPy functions work on Galois field arrays
- Linear algebra on Galois field matrices using normal `np.linalg` functions
- Functions to generate irreducible, primitive, and Conway polynomials
- Polynomials over Galois fields with :obj:`galois.Poly`
- Forward error correction codes with :obj:`galois.BCH` and :obj:`galois.ReedSolomon`
- Fibonacci and Galois linear feedback shift registers with :obj:`galois.LFSR`, both binary and p-ary
- Various number theoretic functions
- Integer factorization and accompanying algorithms
- Prime number generation and primality testing
18 changes: 7 additions & 11 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
Galois: A performant numpy extension for Galois fields and their applications
=============================================================================
.. image:: ../logo/galois-heading.png
:align: center

*Ask Jacobi or Gauss publicly to give their opinion, not as to the truth, but as to the importance of these theorems. Later there
will be, I hope, some people who will find it to their advantage to decipher all this mess.* -- Évariste Galois, two days before his death

.. figure:: _static/img/evariste.jpg
:scale: 50%
:alt: alternate text
:align: right

Évariste Galois, `image credit <https://www.deviantart.com/daga-ra/art/Evariste-Galois-283582290>`_
|

.. toctree::
:maxdepth: 2

features.rst
installation.rst
versioning.md
basic-usage.rst
tutorials.rst
performance.rst
development.rst
api/galois.rst
acknowledgements.md
citation.md

.. toctree::
:maxdepth: 1
Expand Down
2 changes: 1 addition & 1 deletion docs/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Install for development with min dependencies

The package dependencies have minimum supported versions. They are stored in `requirements-min.txt`.

.. literalinclude:: ../../requirements-min.txt
.. literalinclude:: ../requirements-min.txt
:caption: requirements-min.txt
:linenos:

Expand Down
Loading