Skip to content

Commit

Permalink
Clean up recursive function
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Feb 1, 2023
1 parent 77f8316 commit ff28d97
Showing 1 changed file with 31 additions and 41 deletions.
72 changes: 31 additions & 41 deletions src/galois/_polys/_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import functools
import random
from typing import Callable, Iterable, Iterator, Sequence, Type
from typing import Iterator, Sequence, Type

import numpy as np

Expand Down Expand Up @@ -44,8 +44,11 @@ def _deterministic_search_fixed_terms(
reverse: bool = False,
) -> Iterator[Poly]:
"""
Iterates over all monic polynomials of the given degree and number of non-zero terms in lexicographical
Iterates over all monic polynomials of the given degree and number of non-zero terms in lexicographic
order, only yielding those that pass the specified test (either 'is_irreducible()' or 'is_primitive()').
One of the non-zero degrees is the x^m term and the other is the x^0 term. The x^0 term is required so that
the polynomial is irreducible.
"""
assert test in ["is_irreducible", "is_primitive"]
field = _factory.FIELD_FACTORY(order)
Expand All @@ -56,47 +59,34 @@ def direction(x):
return reversed(x)
return x

# Initialize the search by setting the first term to x^m with coefficient 1. This function will
# recursively add the remaining terms, with the last term being x^0.
yield from _deterministic_search_fixed_terms_recursive([degree], [1], terms - 1, test, field, direction)


def _deterministic_search_fixed_terms_recursive(
degrees: Sequence[int],
coeffs: Sequence[int],
terms: int,
test: str,
field: Type[Array],
direction: Callable[[Iterable[int]], Iterable[int]],
) -> Iterator[Poly]:
"""
Recursively finds all monic polynomials having non-zero coefficients `coeffs` with degree `degrees` with `terms`
additional non-zero terms. The polynomials are found in lexicographical order, only yielding those that pass
the specified test (either 'is_irreducible()' or 'is_primitive()').
"""
if terms == 0:
# There are no more terms, yield the polynomial.
poly = Poly.Degrees(degrees, coeffs, field=field)
if getattr(poly, test)():
yield poly
elif terms == 1:
# The last term must be the x^0 term, so we don't need to loop over possible degrees.
for coeff in direction(range(1, field.order)):
next_degrees = (*degrees, 0)
next_coeffs = (*coeffs, coeff)
yield from _deterministic_search_fixed_terms_recursive(
next_degrees, next_coeffs, terms - 1, test, field, direction
)
else:
# Find the next term's degree. It must be at least terms - 1 so that the polynomial can have the specified
# number of terms of lesser degree. It must also be less than the degree of the previous term.
for degree in direction(range(terms - 1, degrees[-1])):
def recursive(
degrees: Sequence[int],
coeffs: Sequence[int],
terms: int,
) -> Iterator[Poly]:
if terms == 0:
# There are no more terms, yield the polynomial.
poly = Poly.Degrees(degrees, coeffs, field=field)
if getattr(poly, test)():
yield poly
elif terms == 1:
# The last term must be the x^0 term, so we don't need to loop over possible degrees.
for coeff in direction(range(1, field.order)):
next_degrees = (*degrees, degree)
next_degrees = (*degrees, 0)
next_coeffs = (*coeffs, coeff)
yield from _deterministic_search_fixed_terms_recursive(
next_degrees, next_coeffs, terms - 1, test, field, direction
)
yield from recursive(next_degrees, next_coeffs, terms - 1)
else:
# Find the next term's degree. It must be at least terms - 1 so that the polynomial can have the specified
# number of terms of lesser degree. It must also be less than the degree of the previous term.
for degree in direction(range(terms - 1, degrees[-1])):
for coeff in direction(range(1, field.order)):
next_degrees = (*degrees, degree)
next_coeffs = (*coeffs, coeff)
yield from recursive(next_degrees, next_coeffs, terms - 1)

# Initialize the search by setting the first term to x^m with coefficient 1. This function will
# recursively add the remaining terms, with the last term being x^0.
yield from recursive([degree], [1], terms - 1)


def _random_search(order: int, degree: int, test: str) -> Iterator[Poly]:
Expand Down

0 comments on commit ff28d97

Please sign in to comment.