Skip to content

Commit

Permalink
Convert .. math:: to $$...$$
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Aug 6, 2023
1 parent 26e2f50 commit 9242f1d
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 128 deletions.
32 changes: 16 additions & 16 deletions docs/basic-usage/compilation-modes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,36 @@ during the call to :func:`~galois.GF`.
The exponential and logarithm lookup tables map every finite field element to a power of the primitive element
$\alpha$.

.. math::
x = \alpha^i
$$x = \alpha^i$$

.. math::
\textrm{log}_{\alpha}(x) = i
$$\textrm{log}_{\alpha}(x) = i$$

With these lookup tables, many arithmetic operations are simplified. For instance, multiplication of two finite field
elements is reduced to three lookups and one integer addition.

.. math::
x \cdot y &= \alpha^m \cdot \alpha^n \\
&= \alpha^{m + n}
$$
x \cdot y
&= \alpha^m \cdot \alpha^n \\
&= \alpha^{m + n}
$$

The `Zech logarithm <https://en.wikipedia.org/wiki/Zech%27s_logarithm>`_ is defined below. A similar lookup table is
created for it.

.. math::
1 + \alpha^i = \alpha^{Z(i)}
$$1 + \alpha^i = \alpha^{Z(i)}$$

.. math::
Z(i) = \textrm{log}_{\alpha}(1 + \alpha^i)
$$Z(i) = \textrm{log}_{\alpha}(1 + \alpha^i)$$

With Zech logarithms, addition of two finite field elements becomes three lookups, one integer addition, and one
integer subtraction.

.. math::
x + y &= \alpha^m + \alpha^n \\
&= \alpha^m (1 + \alpha^{n - m}) \\
&= \alpha^m \alpha^{Z(n - m)} \\
&= \alpha^{m + Z(n - m)}
$$
x + y
&= \alpha^m + \alpha^n \\
&= \alpha^m (1 + \alpha^{n - m}) \\
&= \alpha^m \alpha^{Z(n - m)} \\
&= \alpha^{m + Z(n - m)}
$$

Finite fields with order less than $2^{20}$ use lookup tables by default. In the limited cases where explicit calculation
is faster than table lookup, the explicit calculation is used.
Expand Down
10 changes: 3 additions & 7 deletions src/galois/_codes/_bch.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ class BCH(_CyclicCode):
evaluated in $\mathrm{GF}(q^m)$. The element $\alpha$ is a primitive $n$-th root of unity in
$\mathrm{GF}(q^m)$.
.. math::
g(x) = \textrm{LCM}(m_{\alpha^c}(x), \dots, m_{\alpha^{c+d-2}}(x))
$$g(x) = \textrm{LCM}(m_{\alpha^c}(x), \dots, m_{\alpha^{c+d-2}}(x))$$
Examples:
Construct a binary $\textrm{BCH}(15, 7)$ code.
Expand Down Expand Up @@ -507,11 +505,9 @@ def decode(
operation computes the remainder of $r(x)$ by $g(x)$ in the extension field
$\mathrm{GF}(q^m)$.
.. math::
\mathbf{s} = [r(\alpha^c),\ \dots,\ r(\alpha^{c+d-2})] \in \mathrm{GF}(q^m)^{d-1}
$$\mathbf{s} = [r(\alpha^c),\ \dots,\ r(\alpha^{c+d-2})] \in \mathrm{GF}(q^m)^{d-1}$$
.. math::
s(x) = r(x)\ \textrm{mod}\ g(x) \in \mathrm{GF}(q^m)[x]
$$s(x) = r(x)\ \textrm{mod}\ g(x) \in \mathrm{GF}(q^m)[x]$$
A syndrome of zeros indicates the received codeword is a valid codeword and there are no errors. If the
syndrome is non-zero, the decoder will find an error-locator polynomial $\sigma(x)$ and the corresponding
Expand Down
30 changes: 10 additions & 20 deletions src/galois/_codes/_cyclic.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,30 +61,24 @@ def __init__(
The message vector $\mathbf{m}$ is a member of $\mathrm{GF}(q)^k$. The corresponding
message polynomial $m(x)$ is a degree-$k$ polynomial over $\mathrm{GF}(q)$.
.. math::
\mathbf{m} = [m_{k-1},\ \dots,\ m_1,\ m_0] \in \mathrm{GF}(q)^k
$$\mathbf{m} = [m_{k-1},\ \dots,\ m_1,\ m_0] \in \mathrm{GF}(q)^k$$
.. math::
m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0 \in \mathrm{GF}(q)[x]
$$m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0 \in \mathrm{GF}(q)[x]$$
The codeword vector $\mathbf{c}$ is a member of $\mathrm{GF}(q)^n$. The corresponding
codeword polynomial $c(x)$ is a degree-$n$ polynomial over $\mathrm{GF}(q)$.
.. math::
\mathbf{c} = [c_{n-1},\ \dots,\ c_1,\ c_0] \in \mathrm{GF}(q)^n
$$\mathbf{c} = [c_{n-1},\ \dots,\ c_1,\ c_0] \in \mathrm{GF}(q)^n$$
.. math::
c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0 \in \mathrm{GF}(q)[x]
$$c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0 \in \mathrm{GF}(q)[x]$$
The codeword vector is computed by matrix multiplication of the message vector with the generator matrix.
The equivalent polynomial operation is multiplication of the message polynomial with the generator
polynomial.
.. math::
\mathbf{c} = \mathbf{m} \mathbf{G}
$$\mathbf{c} = \mathbf{m} \mathbf{G}$$
.. math::
c(x) = m(x) g(x)
$$c(x) = m(x) g(x)$$
""",
)
def encode(self, message: ArrayLike, output: Literal["codeword", "parity"] = "codeword") -> FieldArray:
Expand Down Expand Up @@ -116,21 +110,17 @@ def decode(
The message vector $\mathbf{m}$ is a member of $\mathrm{GF}(q)^k$. The corresponding
message polynomial $m(x)$ is a degree-$k$ polynomial over $\mathrm{GF}(q)$.
.. math::
\mathbf{m} = [m_{k-1},\ \dots,\ m_1,\ m_0] \in \mathrm{GF}(q)^k
$$\mathbf{m} = [m_{k-1},\ \dots,\ m_1,\ m_0] \in \mathrm{GF}(q)^k$$
.. math::
m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0 \in \mathrm{GF}(q)[x]
$$m(x) = m_{k-1} x^{k-1} + \dots + m_1 x + m_0 \in \mathrm{GF}(q)[x]$$
The codeword vector $\mathbf{c}$ is a member of $\mathrm{GF}(q)^n$. The corresponding
codeword polynomial $c(x)$ is a degree-$n$ polynomial over $\mathrm{GF}(q)$.
Each codeword polynomial $c(x)$ is divisible by the generator polynomial $g(x)$.
.. math::
\mathbf{c} = [c_{n-1},\ \dots,\ c_1,\ c_0] \in \mathrm{GF}(q)^n
$$\mathbf{c} = [c_{n-1},\ \dots,\ c_1,\ c_0] \in \mathrm{GF}(q)^n$$
.. math::
c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0 \in \mathrm{GF}(q)[x]
$$c(x) = c_{n-1} x^{n-1} + \dots + c_1 x + c_0 \in \mathrm{GF}(q)[x]$$
""",
)
def decode(self, codeword, output="message", errors=False):
Expand Down
3 changes: 1 addition & 2 deletions src/galois/_codes/_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,8 +337,7 @@ def t(self) -> int:
Notes:
The code can correct $t$ symbol errors in a codeword.
.. math::
t = \bigg\lfloor \frac{d - 1}{2} \bigg\rfloor
$$t = \bigg\lfloor \frac{d - 1}{2} \bigg\rfloor$$
"""
return (self.d - 1) // 2

Expand Down
10 changes: 3 additions & 7 deletions src/galois/_codes/_reed_solomon.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@ class ReedSolomon(_CyclicCode):
generator polynomial has $d-1$ roots $\alpha^c, \dots, \alpha^{c+d-2}$. The element $\alpha$ is
a primitive $n$-th root of unity in $\mathrm{GF}(q)$.
.. math::
g(x) = (x - \alpha^c) \dots (x - \alpha^{c+d-2})
$$g(x) = (x - \alpha^c) \dots (x - \alpha^{c+d-2})$$
Examples:
Construct a $\textrm{RS}(15, 9)$ code.
Expand Down Expand Up @@ -461,11 +459,9 @@ def decode(
$\mathbf{r}$ at the roots $\alpha^c, \dots, \alpha^{c+d-2}$ of the generator polynomial
$g(x)$. The equivalent polynomial operation computes the remainder of $r(x)$ by $g(x)$.
.. math::
\mathbf{s} = [r(\alpha^c),\ \dots,\ r(\alpha^{c+d-2})] \in \mathrm{GF}(q)^{d-1}
$$\mathbf{s} = [r(\alpha^c),\ \dots,\ r(\alpha^{c+d-2})] \in \mathrm{GF}(q)^{d-1}$$
.. math::
s(x) = r(x)\ \textrm{mod}\ g(x) \in \mathrm{GF}(q)[x]
$$s(x) = r(x)\ \textrm{mod}\ g(x) \in \mathrm{GF}(q)[x]$$
A syndrome of zeros indicates the received codeword is a valid codeword and there are no errors. If the
syndrome is non-zero, the decoder will find an error-locator polynomial $\sigma(x)$ and the corresponding
Expand Down
6 changes: 2 additions & 4 deletions src/galois/_fields/_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1474,8 +1474,7 @@ def field_trace(self) -> FieldArray:
For finite fields, since $L$ is a Galois extension of $K$, the field trace of $x$ is
defined as a sum of the Galois conjugates of $x$.
.. math::
\mathrm{Tr}_{L / K}(x) = \sum_{i=0}^{m-1} x^{p^i}
$$\mathrm{Tr}_{L / K}(x) = \sum_{i=0}^{m-1} x^{p^i}$$
References:
- https://en.wikipedia.org/wiki/Field_trace
Expand Down Expand Up @@ -1520,8 +1519,7 @@ def field_norm(self) -> FieldArray:
For finite fields, since $L$ is a Galois extension of $K$, the field norm of $x$ is
defined as a product of the Galois conjugates of $x$.
.. math::
\mathrm{N}_{L / K}(x) = \prod_{i=0}^{m-1} x^{p^i} = x^{(p^m - 1) / (p - 1)}
$$\mathrm{N}_{L / K}(x) = \prod_{i=0}^{m-1} x^{p^i} = x^{(p^m - 1) / (p - 1)}$$
References:
- https://en.wikipedia.org/wiki/Field_norm
Expand Down
24 changes: 8 additions & 16 deletions src/galois/_lfsr.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,17 +183,14 @@ class FLFSR(_LFSR):
Notes:
A Fibonacci LFSR is defined by its feedback polynomial $f(x)$.
.. math::
f(x) = -c_{0}x^{n} - c_{1}x^{n-1} - \dots - c_{n-2}x^{2} - c_{n-1}x + 1 = x^n c(x^{-1})
$$f(x) = -c_{0}x^{n} - c_{1}x^{n-1} - \dots - c_{n-2}x^{2} - c_{n-1}x + 1 = x^n c(x^{-1})$$
The feedback polynomial is the reciprocal of the characteristic polynomial $c(x)$ of the linear recurrent
sequence $y$ produced by the Fibonacci LFSR.
.. math::
c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}
$$c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}$$
.. math::
y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}
$$y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}$$
.. code-block:: text
:caption: Fibonacci LFSR Configuration
Expand Down Expand Up @@ -816,17 +813,14 @@ class GLFSR(_LFSR):
Notes:
A Galois LFSR is defined by its feedback polynomial $f(x)$.
.. math::
f(x) = -c_{0}x^{n} - c_{1}x^{n-1} - \dots - c_{n-2}x^{2} - c_{n-1}x + 1 = x^n c(x^{-1})
$$f(x) = -c_{0}x^{n} - c_{1}x^{n-1} - \dots - c_{n-2}x^{2} - c_{n-1}x + 1 = x^n c(x^{-1})$$
The feedback polynomial is the reciprocal of the characteristic polynomial $c(x)$ of the linear recurrent
sequence $y$ produced by the Galois LFSR.
.. math::
c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}
$$c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}$$
.. math::
y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}
$$y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}$$
.. code-block:: text
:caption: Galois LFSR Configuration
Expand Down Expand Up @@ -1460,11 +1454,9 @@ def berlekamp_massey(sequence, output="minimal"):
The minimal polynomial is the characteristic polynomial $c(x)$ of minimal degree that produces the
linear recurrent sequence $y$.
.. math::
c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}
$$c(x) = x^{n} - c_{n-1}x^{n-1} - c_{n-2}x^{n-2} - \dots - c_{1}x - c_{0}$$
.. math::
y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}
$$y_t = c_{n-1}y_{t-1} + c_{n-2}y_{t-2} + \dots + c_{1}y_{t-n+2} + c_{0}y_{t-n+1}$$
For a linear sequence with order $n$, at least $2n$ output symbols are required to determine the
minimal polynomial.
Expand Down
6 changes: 2 additions & 4 deletions src/galois/_modular.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ def euler_phi(n: int) -> int:
Notes:
This function implements the Euler totient function
.. math::
\phi(n) = n \prod_{p\ |\ n} \bigg(1 - \frac{1}{p}\bigg) = \prod_{i=1}^{k} p_i^{e_i-1} \big(p_i - 1\big)
$$\phi(n) = n \prod_{p\ |\ n} \bigg(1 - \frac{1}{p}\bigg) = \prod_{i=1}^{k} p_i^{e_i-1} \big(p_i - 1\big)$$
for prime $p$ and the prime factorization $n = p_1^{e_1} \dots p_k^{e_k}$.
Expand Down Expand Up @@ -743,8 +742,7 @@ def is_primitive_root(g: int, n: int) -> bool:
Alternatively said, $g$ is a primitive root modulo $n$ if and only if $g$ is a generator of
the multiplicative group of integers modulo $n$,
.. math::
(\mathbb{Z}/n\mathbb{Z}){^\times} = \{1, g, g^2, \dots, g^{\phi(n)-1}\}
$$(\mathbb{Z}/n\mathbb{Z}){^\times} = \{1, g, g^2, \dots, g^{\phi(n)-1}\}$$
where $\phi(n)$ is order of the group.
Expand Down
6 changes: 2 additions & 4 deletions src/galois/_ntt.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ def ntt(
The $k$-th value of the $N$-point NTT $X = \mathrm{NTT}(x)$ is
.. math::
X_k = \sum_{j=0}^{N-1} x_j \omega_N^{jk} ,
$$X_k = \sum_{j=0}^{N-1} x_j \omega_N^{jk} ,$$
with all arithmetic performed in $\mathrm{GF}(p)$.
Expand Down Expand Up @@ -163,8 +162,7 @@ def intt(
The $j$-th value of the scaled $N$-point INTT $x = \mathrm{INTT}(X)$ is
.. math::
x_j = \frac{1}{N} \sum_{k=0}^{N-1} X_k \omega_N^{-kj} ,
$$x_j = \frac{1}{N} \sum_{k=0}^{N-1} X_k \omega_N^{-kj} ,$$
with all arithmetic performed in $\mathrm{GF}(p)$. The scaled INTT has the property that
$x = \mathrm{INTT}(\mathrm{NTT}(x))$.
Expand Down
17 changes: 8 additions & 9 deletions src/galois/_polymorphic.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,11 +409,12 @@ def crt(remainders, moduli):
Notes:
This function implements the Chinese Remainder Theorem.
.. math::
x &\equiv a_1\ (\textrm{mod}\ m_1) \\
x &\equiv a_2\ (\textrm{mod}\ m_2) \\
x &\equiv \ldots \\
x &\equiv a_n\ (\textrm{mod}\ m_n)
$$
x &\equiv a_1\ (\textrm{mod}\ m_1) \\
x &\equiv a_2\ (\textrm{mod}\ m_2) \\
x &\equiv \ldots \\
x &\equiv a_n\ (\textrm{mod}\ m_n)
$$
References:
- Section 14.5 from https://cacr.uwaterloo.ca/hac/about/chap14.pdf
Expand Down Expand Up @@ -684,16 +685,14 @@ def is_square_free(value):
A square-free integer $n$ is divisible by no perfect squares. As a consequence, the prime
factorization of a square-free integer $n$ is
.. math::
n = \prod_{i=1}^{k} p_i^{e_i} = \prod_{i=1}^{k} p_i .
$$n = \prod_{i=1}^{k} p_i^{e_i} = \prod_{i=1}^{k} p_i .$$
.. md-tab-item:: Polynomials
A square-free polynomial $f(x)$ has no irreducible factors with multiplicity greater than one.
Therefore, its canonical factorization is
.. math::
f(x) = \prod_{i=1}^{k} g_i(x)^{e_i} = \prod_{i=1}^{k} g_i(x) .
$$f(x) = \prod_{i=1}^{k} g_i(x)^{e_i} = \prod_{i=1}^{k} g_i(x) .$$
This test is also available in :func:`Poly.is_square_free`.
Expand Down
20 changes: 9 additions & 11 deletions src/galois/_polys/_factor.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def is_square_free(f) -> bool:
A square-free polynomial $f(x)$ has no irreducible factors with multiplicity greater than one.
Therefore, its canonical factorization is
.. math::
f(x) = \prod_{i=1}^{k} g_i(x)^{e_i} = \prod_{i=1}^{k} g_i(x) .
$$f(x) = \prod_{i=1}^{k} g_i(x)^{e_i} = \prod_{i=1}^{k} g_i(x) .$$
Examples:
Generate irreducible polynomials over $\mathrm{GF}(3)$.
Expand Down Expand Up @@ -74,8 +73,7 @@ def square_free_factors(f: Poly) -> tuple[list[Poly], list[int]]:
The Square-Free Factorization algorithm factors $f(x)$ into a product of $m$ square-free
polynomials $h_j(x)$ with multiplicity $j$.
.. math::
f(x) = \prod_{j=1}^{m} h_j(x)^j
$$f(x) = \prod_{j=1}^{m} h_j(x)^j$$
Some $h_j(x) = 1$, but those polynomials are not returned by this function.
Expand Down Expand Up @@ -175,17 +173,17 @@ def distinct_degree_factors(f: Poly) -> tuple[list[Poly], list[int]]:
$d$ into a product of $d$ polynomials $f_i(x)$, where $f_i(x)$ is the product of
all irreducible factors of $f(x)$ with degree $i$.
.. math::
f(x) = \prod_{i=1}^{d} f_i(x)
$$f(x) = \prod_{i=1}^{d} f_i(x)$$
For example, suppose $f(x) = x(x + 1)(x^2 + x + 1)(x^3 + x + 1)(x^3 + x^2 + 1)$ over
$\mathrm{GF}(2)$, then the distinct-degree factorization is
.. math::
f_1(x) &= x(x + 1) = x^2 + x \\
f_2(x) &= x^2 + x + 1 \\
f_3(x) &= (x^3 + x + 1)(x^3 + x^2 + 1) = x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 \\
f_i(x) &= 1\ \textrm{for}\ i = 4, \dots, 10.
$$
f_1(x) &= x(x + 1) = x^2 + x \\
f_2(x) &= x^2 + x + 1 \\
f_3(x) &= (x^3 + x + 1)(x^3 + x^2 + 1) = x^6 + x^5 + x^4 + x^3 + x^2 + x + 1 \\
f_i(x) &= 1\ \textrm{for}\ i = 4, \dots, 10.
$$
Some $f_i(x) = 1$, but those polynomials are not returned by this function. In this example,
the function returns $\{f_1(x), f_2(x), f_3(x)\}$ and $\{1, 2, 3\}$.
Expand Down
6 changes: 2 additions & 4 deletions src/galois/_polys/_lagrange.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ def lagrange_poly(x: Array, y: Array) -> Poly:
Notes:
The Lagrange interpolating polynomial is defined as
.. math::
L(x) = \sum_{j=0}^{k-1} y_j \ell_j(x)
$$L(x) = \sum_{j=0}^{k-1} y_j \ell_j(x)$$
.. math::
\ell_j(x) = \prod_{\substack{0 \le m < k \\ m \ne j}} \frac{x - x_m}{x_j - x_m} .
$$\ell_j(x) = \prod_{\substack{0 \le m < k \\ m \ne j}} \frac{x - x_m}{x_j - x_m} .$$
It is the polynomial of minimal degree that satisfies $L(x_i) = y_i$.
Expand Down
Loading

0 comments on commit 9242f1d

Please sign in to comment.