Skip to content

Commit

Permalink
Standardize scalar return types
Browse files Browse the repository at this point in the history
Fixes #384
  • Loading branch information
mhostetter committed Nov 17, 2022
1 parent f0d92b3 commit 6ae4a78
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 9 deletions.
26 changes: 19 additions & 7 deletions src/galois/_fields/_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ def primitive_roots_of_unity(cls, n: int) -> Self:
# Instance methods
###############################################################################

def additive_order(self) -> np.integer | np.ndarray:
def additive_order(self) -> int | np.ndarray:
r"""
Computes the additive order of each element in :math:`x`.
Expand Down Expand Up @@ -776,14 +776,14 @@ def additive_order(self) -> np.integer | np.ndarray:
field = type(self)

if x.ndim == 0:
order = np.int64(1) if x == 0 else np.int64(field.characteristic)
order = 1 if x == 0 else field.characteristic
else:
order = field.characteristic * np.ones(x.shape, dtype=np.int64)
order[np.where(x == 0)] = 1

return order

def multiplicative_order(self) -> np.integer | np.ndarray:
def multiplicative_order(self) -> int | np.ndarray:
r"""
Computes the multiplicative order :math:`\textrm{ord}(x)` of each element in :math:`x`.
Expand Down Expand Up @@ -845,9 +845,12 @@ def multiplicative_order(self) -> np.integer | np.ndarray:
idxs = np.argmin(y, axis=-1) # First index of divisors, which is the order of x
order = d[idxs] # The order of each element of x

if np.isscalar(order):
order = int(order)

return order

def is_square(self) -> np.bool_ | np.ndarray:
def is_square(self) -> bool | np.ndarray:
r"""
Determines if the elements of :math:`x` are squares in the finite field.
Expand Down Expand Up @@ -899,10 +902,16 @@ def is_square(self) -> np.bool_ | np.ndarray:

if field.characteristic == 2:
# All elements are squares if the field's characteristic is 2
return np.ones(x.shape, dtype=bool) if x.ndim > 0 else np.bool_(True)
output = np.ones(x.shape, dtype=bool)
if output.ndim == 0:
output = bool(output)
else:
# Compute the Legendre symbol on each element
return x ** ((field.order - 1)//2) != field.characteristic - 1
output = x ** ((field.order - 1)//2) != field.characteristic - 1
if np.isscalar(output):
output = bool(output)

return output

def vector(self, dtype: DTypeLike | None = None) -> FieldArray:
r"""
Expand Down Expand Up @@ -1489,7 +1498,7 @@ def minimal_poly(self) -> Poly:
else:
raise ValueError(f"The array must be either 0-D to return the minimal polynomial of a single element or 2-D to return the minimal polynomial of a square matrix, not have shape {self.shape}.")

def log(self, base: ElementLike | ArrayLike | None = None) -> np.integer | np.ndarray:
def log(self, base: ElementLike | ArrayLike | None = None) -> int | np.ndarray:
r"""
Computes the logarithm of the array :math:`x` base :math:`\beta`.
Expand Down Expand Up @@ -1567,6 +1576,9 @@ def log(self, base: ElementLike | ArrayLike | None = None) -> np.integer | np.nd

# TODO: Could add a method keyword argument to the function to allow different modes.

if np.isscalar(output):
output = int(output)

return output

###############################################################################
Expand Down
4 changes: 2 additions & 2 deletions tests/fields/test_squares.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
def test_shapes():
GF = galois.GF(31)
x = GF.Random()
assert isinstance(x.is_square(), np.bool_)
assert isinstance(x.is_square(), bool)
x = GF.Random((2,))
assert x.is_square().shape == x.shape
x = GF.Random((2,2))
Expand All @@ -56,7 +56,7 @@ def test_shapes():

GF = galois.GF(2**4)
x = GF.Random()
assert isinstance(x.is_square(), np.bool_)
assert isinstance(x.is_square(), bool)
x = GF.Random((2,))
assert x.is_square().shape == x.shape
x = GF.Random((2,2))
Expand Down

0 comments on commit 6ae4a78

Please sign in to comment.