Skip to content

Commit

Permalink
Clean up arithmetic examples
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Nov 8, 2022
1 parent 6ee9d79 commit 01f86f1
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 69 deletions.
107 changes: 65 additions & 42 deletions docs/basic-usage/array-arithmetic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ In the sections below, the finite field :math:`\mathrm{GF}(3^5)` and arrays :mat
x = GF([184, 25, 157, 31]); x
y = GF([179, 9, 139, 27]); y
Ufuncs
------
Standard arithmetic
-------------------

`NumPy ufuncs <https://numpy.org/devdocs/reference/ufuncs.html>`_ are universal functions that operate on scalars. Unary ufuncs operate on
a single scalar and binary ufuncs operate on two scalars. NumPy extends the scalar operation of ufuncs to operate on arrays in various ways.
Expand All @@ -23,123 +23,140 @@ Expand any section for more details.

.. details:: Addition: `x + y == np.add(x, y)`
:class: example
:open:

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x + y
np.add(x, y)

.. details:: Additive inverse: `-x == np.negative(x)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
-x
np.negative(x)

Any array added to its additive inverse results in zero.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
x + np.negative(x)

.. details:: Subtraction: `x - y == np.subtract(x, y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x - y
np.subtract(x, y)

.. details:: Multiplication: `x * y == np.multiply(x, y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x * y
np.multiply(x, y)

.. details:: Scalar multiplication: `x * z == np.multiply(x, z)`
.. details:: Scalar multiplication: `x * 4 == np.multiply(x, 4)`
:class: example

Scalar multiplication is essentially *repeated addition*. It is the "multiplication" of finite field elements
and integers. The integer value indicates how many additions of the field element to sum.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
x * 4
np.multiply(x, 4)
x + x + x + x

In finite fields :math:`\mathrm{GF}(p^m)`, the characteristic :math:`p` is the smallest value when multiplied by
any non-zero field element that results in 0.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

p = GF.characteristic; p
x * p

.. details:: Multiplicative inverse: `y ** -1 == np.reciprocal(y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

y
y ** -1
GF(1) / y
np.reciprocal(y)

Any array multiplied by its multiplicative inverse results in one.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

y * np.reciprocal(y)

.. details:: Division: `x / y == x // y == np.divide(x, y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x / y
x // y
np.divide(x, y)

.. details:: Remainder: `x % y == np.remainder(x, y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x % y
np.remainder(x, y)

.. details:: Divmod: `divmod(x, y) == np.divmod(x, y)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
x // y, x % y
divmod(x, y)
np.divmod(x, y)

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

q, r = divmod(x, y)
q*y + r == x

.. details:: Exponentiation: `x ** z == np.power(x, z)`
.. details:: Exponentiation: `x ** 3 == np.power(x, 3)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
x ** 3
np.power(x, 3)
x * x * x

.. details:: Square root: `np.sqrt(x)`
:class: example

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
x.is_square()
z = np.sqrt(x); z
z ** 2 == x
Expand All @@ -151,17 +168,19 @@ Expand any section for more details.

Compute the logarithm base :math:`\alpha`, the primitive element of the field.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

y
z = np.log(y); z
alpha = GF.primitive_element; alpha
alpha ** z == y

Compute the logarithm base :math:`\beta`, a different primitive element of the field. See :func:`FieldArray.log` for more
details.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

y
beta = GF.primitive_elements[-1]; beta
z = y.log(beta); z
beta ** z == y
Expand All @@ -176,16 +195,16 @@ Expand any section for more details.

.. details:: `reduce()`
:class: example
:open:

The :obj:`~numpy.ufunc.reduce` methods reduce the input array's dimension by one, applying the ufunc across one axis.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
np.add.reduce(x)
x[0] + x[1] + x[2] + x[3]

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

np.multiply.reduce(x)
x[0] * x[1] * x[2] * x[3]
Expand All @@ -195,12 +214,13 @@ Expand any section for more details.

The :obj:`~numpy.ufunc.accumulate` methods accumulate the result of the ufunc across a specified axis.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
np.add.accumulate(x)
GF([x[0], x[0] + x[1], x[0] + x[1] + x[2], x[0] + x[1] + x[2] + x[3]])

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

np.multiply.accumulate(x)
GF([x[0], x[0] * x[1], x[0] * x[1] * x[2], x[0] * x[1] * x[2] * x[3]])
Expand All @@ -211,12 +231,13 @@ Expand any section for more details.
The :obj:`~numpy.ufunc.reduceat` methods reduces the input array's dimension by one, applying the ufunc across one axis
in-between certain indices.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
np.add.reduceat(x, [0, 3])
GF([x[0] + x[1] + x[2], x[3]])

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

np.multiply.reduceat(x, [0, 3])
GF([x[0] * x[1] * x[2], x[3]])
Expand All @@ -226,11 +247,13 @@ Expand any section for more details.

The :obj:`~numpy.ufunc.outer` methods applies the ufunc to each pair of inputs.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
np.add.outer(x, y)

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

np.multiply.outer(x, y)

Expand All @@ -239,8 +262,9 @@ Expand any section for more details.

The :obj:`~numpy.ufunc.at` methods performs the ufunc in-place at the specified indices.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
z = x.copy()
# Negate indices 0 and 1 in-place
np.negative.at(x, [0, 1]); x
Expand All @@ -253,10 +277,11 @@ Advanced arithmetic

.. details:: Convolution: `np.convolve(x, y)`
:class: example
:open:

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

x
y
np.convolve(x, y)

.. details:: FFT: `np.fft.fft(x)`
Expand All @@ -265,13 +290,13 @@ Advanced arithmetic
The Discrete Fourier Transform (DFT) of size :math:`n` over the finite field :math:`\mathrm{GF}(p^m)` exists when there
exists a primitive :math:`n`-th root of unity. This occurs when :math:`n\ |\ p^m - 1`.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

GF = galois.GF(7**5)
n = 6
# n divides p^m - 1
(GF.order - 1) % n
x = GF.Random(n); x
x = GF.Random(n, seed=1); x
X = np.fft.fft(x); X
np.fft.ifft(X)

Expand All @@ -283,13 +308,13 @@ Advanced arithmetic
The inverse Discrete Fourier Transform (DFT) of size :math:`n` over the finite field :math:`\mathrm{GF}(p^m)` exists when there
exists a primitive :math:`n`-th root of unity. This occurs when :math:`n\ |\ p^m - 1`.

.. ipython:: python
.. ipython-with-reprs:: int,poly,power

GF = galois.GF(7**5)
n = 6
# n divides p^m - 1
(GF.order - 1) % n
x = GF.Random(n); x
x = GF.Random(n, seed=1); x
X = np.fft.fft(x); X
np.fft.ifft(X)

Expand All @@ -305,7 +330,6 @@ Expand any section for more details.

.. details:: Dot product: `np.dot(a, b)`
:class: example
:open:

.. ipython:: python
Expand Down Expand Up @@ -355,7 +379,7 @@ Expand any section for more details.
A @ B
np.matmul(A, B)
.. details:: Matrix exponentiation: `np.linalg.matrix_power(A, z)`
.. details:: Matrix exponentiation: `np.linalg.matrix_power(A, 3)`
:class: example

.. ipython:: python
Expand All @@ -374,7 +398,7 @@ Expand any section for more details.
A = GF([[23, 11, 3, 3], [13, 6, 16, 4], [12, 10, 5, 3], [17, 23, 15, 28]]); A
np.linalg.det(A)
.. details:: Matrix rank: `np.linalg.matrix_rank(A, z)`
.. details:: Matrix rank: `np.linalg.matrix_rank(A)`
:class: example

.. ipython:: python
Expand Down Expand Up @@ -423,7 +447,6 @@ not included in NumPy.

.. details:: Row space: `A.row_space()`
:class: example
:open:

.. ipython:: python
Expand Down
Loading

0 comments on commit 01f86f1

Please sign in to comment.