Skip to content

Commit

Permalink
Use verify_isinstance() and verify_issubclass() throughout library
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Aug 19, 2022
1 parent d2c458a commit 8edc8b4
Show file tree
Hide file tree
Showing 23 changed files with 264 additions and 346 deletions.
20 changes: 7 additions & 13 deletions galois/_codes/_bch.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from .._domains._function import Function
from .._fields import Field, FieldArray, GF2
from .._helper import set_module
from .._helper import set_module, verify_isinstance
from .._lfsr import berlekamp_massey_jit
from .._polys import Poly, matlab_primitive_poly
from .._polys._dense import roots_jit, divmod_jit
Expand All @@ -32,12 +32,9 @@ def _check_and_compute_field(
primitive_poly: Optional[PolyLike] = None,
primitive_element: Optional[PolyLike] = None
) -> Type[FieldArray]:
if not isinstance(n, (int, np.integer)):
raise TypeError(f"Argument `n` must be an integer, not {type(n)}.")
if not isinstance(k, (int, np.integer)):
raise TypeError(f"Argument `k` must be an integer, not {type(k)}.")
if not isinstance(c, (int, np.integer)):
raise TypeError(f"Argument `c` must be an integer, not {type(c)}.")
verify_isinstance(n, int)
verify_isinstance(k, int)
verify_isinstance(c, int)

p, m = factors(n + 1)
if not (len(p) == 1 and p[0] == 2):
Expand Down Expand Up @@ -95,10 +92,8 @@ def bch_valid_codes(n: int, t_min: int = 1) -> List[Tuple[int, int, int]]:
:group: fec
"""
if not isinstance(n, (int, np.integer)):
raise TypeError(f"Argument `n` must be an integer, not {type(n)}.")
if not isinstance(t_min, (int, np.integer)):
raise TypeError(f"Argument `t_min` must be an integer, not {type(t_min)}.")
verify_isinstance(n, int)
verify_isinstance(t_min, int)
if not t_min >= 1:
raise ValueError(f"Argument `t_min` must be at least 1, not {t_min}.")

Expand Down Expand Up @@ -210,8 +205,7 @@ def __init__(
bch_valid_codes, primitive_poly, primitive_element
"""
# NOTE: All other arguments will be verified in `_check_and_compute_field()`
if not isinstance(systematic, bool):
raise TypeError(f"Argument `systematic` must be a bool, not {type(systematic)}.")
verify_isinstance(systematic, bool)

self._n = n
self._k = k
Expand Down
17 changes: 6 additions & 11 deletions galois/_codes/_cyclic.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np

from .._fields import FieldArray
from .._helper import set_module
from .._helper import set_module, verify_isinstance
from .._polys import Poly

__all__ = ["poly_to_generator_matrix", "roots_to_parity_check_matrix"]
Expand Down Expand Up @@ -45,12 +45,9 @@ def poly_to_generator_matrix(n: int, generator_poly: Poly, systematic: bool = Tr
:group: fec
"""
if not isinstance(n, (int, np.integer)):
raise TypeError(f"Argument `n` must be an integer, not {type(n)}.")
if not isinstance(generator_poly, Poly):
raise TypeError(f"Argument `generator_poly` must be a galois.Poly, not {type(generator_poly)}.")
if not isinstance(systematic, bool):
raise TypeError(f"Argument `systematic` must be a bool, not {type(systematic)}.")
verify_isinstance(n, int)
verify_isinstance(generator_poly, Poly)
verify_isinstance(systematic, bool)

GF = generator_poly.field
k = n - generator_poly.degree
Expand Down Expand Up @@ -110,10 +107,8 @@ def roots_to_parity_check_matrix(n: int, roots: FieldArray) -> FieldArray:
:group: fec
"""
if not isinstance(n, (int, np.integer)):
raise TypeError(f"Argument `n` must be an integer, not {type(n)}.")
if not isinstance(roots, FieldArray):
raise TypeError(f"Argument `roots` must be a galois.FieldArray, not {type(roots)}.")
verify_isinstance(n, int)
verify_isinstance(roots, FieldArray)

GF = type(roots)
H = np.power.outer(roots, np.arange(n - 1, -1, -1, dtype=GF.dtypes[-1]))
Expand Down
8 changes: 3 additions & 5 deletions galois/_codes/_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import numpy as np

from .._fields import FieldArray
from .._helper import set_module
from .._helper import set_module, verify_isinstance

__all__ = ["generator_to_parity_check_matrix", "parity_check_to_generator_matrix"]

Expand Down Expand Up @@ -40,8 +40,7 @@ def generator_to_parity_check_matrix(G: FieldArray) -> FieldArray:
:group: fec
"""
if not isinstance(G, (FieldArray)):
raise TypeError(f"Argument `G` must be a galois.FieldArray, not {type(G)}.")
verify_isinstance(G, FieldArray)

field = type(G)
k, n = G.shape
Expand Down Expand Up @@ -85,8 +84,7 @@ def parity_check_to_generator_matrix(H: FieldArray) -> FieldArray:
:group: fec
"""
if not isinstance(H, (FieldArray)):
raise TypeError(f"Argument `H` must be a galois.FieldArray, not {type(H)}.")
verify_isinstance(H, FieldArray)

field = type(H)
n_k, n = H.shape
Expand Down
14 changes: 5 additions & 9 deletions galois/_codes/_reed_solomon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from .._domains._function import Function
from .._fields import Field, FieldArray
from .._helper import set_module
from .._helper import set_module, verify_isinstance
from .._lfsr import berlekamp_massey_jit
from .._polys import Poly, matlab_primitive_poly
from .._polys._dense import divmod_jit, roots_jit, evaluate_elementwise_jit
Expand Down Expand Up @@ -106,14 +106,10 @@ def __init__(
--------
primitive_poly, primitive_element
"""
if not isinstance(n, (int, np.integer)):
raise TypeError(f"Argument `n` must be an integer, not {type(n)}.")
if not isinstance(k, (int, np.integer)):
raise TypeError(f"Argument `k` must be an integer, not {type(k)}.")
if not isinstance(c, (int, np.integer)):
raise TypeError(f"Argument `c` must be an integer, not {type(c)}.")
if not isinstance(systematic, bool):
raise TypeError(f"Argument `systematic` must be a bool, not {type(systematic)}.")
verify_isinstance(n, int)
verify_isinstance(k, int)
verify_isinstance(c, int)
verify_isinstance(systematic, bool)

if not (n - k) % 2 == 0:
raise ValueError("Arguments `n - k` must be even.")
Expand Down
8 changes: 3 additions & 5 deletions galois/_domains/_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import numpy as np

from .._helper import set_module, SPHINX_BUILD
from .._helper import set_module, verify_isinstance, SPHINX_BUILD

from ._function import FunctionMixin
from ._linalg import LinalgFunctionMixin
Expand Down Expand Up @@ -326,8 +326,7 @@ def compile(cls, mode: Literal["auto", "jit-lookup", "jit-calculate", "python-ca
- `"python-calculate"`: Uses pure-Python ufuncs with explicit calculation. This is reserved for fields whose elements cannot be
represented with :obj:`numpy.int64` and instead use :obj:`numpy.object_` with Python :obj:`int` (which has arbitrary precision).
"""
if not isinstance(mode, str):
raise TypeError(f"Argument `mode` must be a string, not {type(mode)}.")
verify_isinstance(mode, str)
if not mode in ["auto", "jit-lookup", "jit-calculate", "python-calculate"]:
raise ValueError(f"Argument `mode` must be in ['auto', 'jit-lookup', 'jit-calculate', 'python-calculate'], not {mode!r}.")
mode = cls.default_ufunc_mode if mode == "auto" else mode
Expand Down Expand Up @@ -432,8 +431,7 @@ def display(cls, mode: Literal["int", "poly", "power"] = "int") -> Generator[Non
@suppress
GF.display()
"""
if not isinstance(mode, (type(None), str)):
raise TypeError(f"Argument `mode` must be a string, not {type(mode)}.")
verify_isinstance(mode, str, optional=True)
if mode not in ["int", "poly", "power"]:
raise ValueError(f"Argument `mode` must be in ['int', 'poly', 'power'], not {mode!r}.")

Expand Down
11 changes: 7 additions & 4 deletions galois/_domains/_function.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from numba import int64
import numpy as np

from .._helper import verify_isinstance

from ._meta import ArrayMeta

if TYPE_CHECKING:
Expand Down Expand Up @@ -97,9 +99,9 @@ class convolve_jit(Function):
"""
Function dispatcher to convolve two 1-D arrays.
"""
def __call__(self, a: np.ndarray, b: np.ndarray, mode="full") -> np.ndarray:
if not type(a) is type(b):
raise TypeError(f"Arguments `a` and `b` must be of the same FieldArray subclass, not {type(a)} and {type(b)}.")
def __call__(self, a: Array, b: Array, mode="full") -> Array:
verify_isinstance(a, self.field)
verify_isinstance(b, self.field)
if not mode == "full":
raise ValueError(f"Operation 'convolve' currently only supports mode of 'full', not {mode!r}.")
dtype = a.dtype
Expand Down Expand Up @@ -152,7 +154,8 @@ class fft_jit(Function):
"""
_direction = "forward"

def __call__(self, x: np.ndarray, n=None, axis=-1, norm=None) -> np.ndarray:
def __call__(self, x: Array, n=None, axis=-1, norm=None) -> Array:
verify_isinstance(x, self.field)
norm = "backward" if norm is None else norm
if not axis == -1:
raise ValueError("The FFT is only implemented on 1-D arrays.")
Expand Down
33 changes: 21 additions & 12 deletions galois/_domains/_linalg.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from numba import int64
import numpy as np

from .._helper import verify_isinstance

from ._function import Function, FunctionMixin
from ._meta import DTYPES

Expand Down Expand Up @@ -71,8 +73,8 @@ class dot_jit(Function):
"""

def __call__(self, a: Array, b: Array, out=None) -> Array:
if not type(a) is type(b):
raise TypeError(f"Operation 'dot' requires both arrays be in the same Galois field, not {type(a)} and {type(b)}.")
verify_isinstance(a, self.field)
verify_isinstance(b, self.field)

if self.field._is_prime_field:
return _lapack_linalg(self.field, a, b, np.dot, out=out)
Expand All @@ -98,8 +100,8 @@ class vdot_jit(Function):
"""

def __call__(self, a: Array, b: Array) -> Array:
if not type(a) is type(b):
raise TypeError(f"Operation 'vdot' requires both arrays be in the same Galois field, not {type(a)} and {type(b)}.")
verify_isinstance(a, self.field)
verify_isinstance(b, self.field)

if self.field._is_prime_field:
return _lapack_linalg(self.field, a, b, np.vdot)
Expand All @@ -118,8 +120,8 @@ class inner_jit(Function):
"""

def __call__(self, a: Array, b: Array) -> Array:
if not type(a) is type(b):
raise TypeError(f"Operation 'inner' requires both arrays be in the same Galois field, not {type(a)} and {type(b)}.")
verify_isinstance(a, self.field)
verify_isinstance(b, self.field)

if self.field._is_prime_field:
return _lapack_linalg(self.field, a, b, np.inner)
Expand All @@ -140,8 +142,8 @@ class outer_jit(Function):
"""

def __call__(self, a: Array, b: Array, out=None) -> Array:
if not type(a) is type(b):
raise TypeError(f"Operation 'outer' requires both arrays be in the same Galois field, not {type(a)} and {type(b)}.")
verify_isinstance(a, self.field)
verify_isinstance(b, self.field)

if self.field._is_prime_field:
return _lapack_linalg(self.field, a, b, np.outer, out=out, n_sum=1)
Expand All @@ -159,8 +161,8 @@ class matmul_jit(Function):
"""

def __call__(self, A: Array, B: Array, out=None, **kwargs) -> Array: # pylint: disable=unused-argument
if not type(A) is type(B):
raise TypeError(f"Operation 'matmul' requires both arrays be in the same Galois field, not {type(A)} and {type(B)}.")
verify_isinstance(A, self.field)
verify_isinstance(B, self.field)
if not (A.ndim >= 1 and B.ndim >= 1):
raise ValueError(f"Operation 'matmul' requires both arrays have dimension at least 1, not {A.ndim}-D and {B.ndim}-D.")
if not (A.ndim <= 2 and B.ndim <= 2):
Expand Down Expand Up @@ -244,6 +246,7 @@ class row_reduce_jit(Function):
"""

def __call__(self, A: Array, ncols: Optional[int] = None) -> Tuple[Array, int]:
verify_isinstance(A, self.field)
if not A.ndim == 2:
raise ValueError(f"Only 2-D matrices can be converted to reduced row echelon form, not {A.ndim}-D.")

Expand Down Expand Up @@ -282,6 +285,7 @@ class lu_decompose_jit(Function):
"""

def __call__(self, A: Array) -> Tuple[Array, Array]:
verify_isinstance(A, self.field)
if not A.ndim == 2:
raise ValueError(f"Argument `A` must be a 2-D matrix, not have shape {A.shape}.")

Expand Down Expand Up @@ -313,6 +317,7 @@ class plu_decompose_jit(Function):
"""

def __call__(self, A: Array) -> Tuple[Array, Array, Array, int]:
verify_isinstance(A, self.field)
if not A.ndim == 2:
raise ValueError(f"Argument `A` must be a 2-D matrix, not have shape {A.shape}.")

Expand Down Expand Up @@ -358,6 +363,7 @@ class triangular_det_jit(Function):
"""

def __call__(self, A: Array) -> Array:
verify_isinstance(A, self.field)
if not (A.ndim == 2 and A.shape[0] == A.shape[1]):
raise np.linalg.LinAlgError(f"Argument `A` must be square, not {A.shape}.")
idxs = np.arange(0, A.shape[0])
Expand All @@ -370,6 +376,7 @@ class det_jit(Function):
"""

def __call__(self, A: Array) -> Array:
verify_isinstance(A, self.field)
if not (A.ndim == 2 and A.shape[0] == A.shape[1]):
raise np.linalg.LinAlgError(f"Argument `A` must be square, not {A.shape}.")

Expand Down Expand Up @@ -398,6 +405,7 @@ class matrix_rank_jit(Function):
"""

def __call__(self, A: Array) -> int:
verify_isinstance(A, self.field)
A_rre, _ = row_reduce_jit(self.field)(A)
rank = np.sum(~np.all(A_rre == 0, axis=1))
return rank
Expand All @@ -409,6 +417,7 @@ class inv_jit(Function):
"""

def __call__(self, A: Array) -> Array:
verify_isinstance(A, self.field)
if not (A.ndim == 2 and A.shape[0] == A.shape[1]):
raise np.linalg.LinAlgError(f"Argument `A` must be square, not {A.shape}.")

Expand Down Expand Up @@ -437,8 +446,8 @@ class solve_jit(Function):
"""

def __call__(self, A: Array, b: Array) -> Array:
if not type(A) is type(b):
raise TypeError(f"Arguments `A` and `b` must be of the same FieldArray subclass, not {type(A)} and {type(b)}.")
verify_isinstance(A, self.field)
verify_isinstance(b, self.field)
if not (A.ndim == 2 and A.shape[0] == A.shape[1]):
raise np.linalg.LinAlgError(f"Argument `A` must be square, not {A.shape}.")
if not b.ndim in [1, 2]:
Expand Down
14 changes: 5 additions & 9 deletions galois/_fields/_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import numpy as np

from .._domains import Array, _linalg
from .._helper import set_module, extend_docstring, SPHINX_BUILD
from .._helper import set_module, extend_docstring, verify_isinstance, SPHINX_BUILD
from .._polys import Poly
from .._polys._conversions import integer_to_poly, str_to_integer, poly_to_str
from .._prime import divisors
Expand Down Expand Up @@ -332,12 +332,9 @@ def Vandermonde(cls, element: ElementLike, rows: int, cols: int, dtype: Optional
@suppress
GF.display()
"""
if not isinstance(element, (int, np.integer, cls)):
raise TypeError(f"Argument `element` must be an integer or element of {cls.name}, not {type(element)}.")
if not isinstance(rows, (int, np.integer)):
raise TypeError(f"Argument `rows` must be an integer, not {type(rows)}.")
if not isinstance(cols, (int, np.integer)):
raise TypeError(f"Argument `cols` must be an integer, not {type(cols)}.")
verify_isinstance(element, (int, np.integer, cls))
verify_isinstance(rows, int)
verify_isinstance(cols, int)
if not rows > 0:
raise ValueError(f"Argument `rows` must be non-negative, not {rows}.")
if not cols > 0:
Expand Down Expand Up @@ -691,8 +688,7 @@ def primitive_root_of_unity(cls, n: int) -> FieldArray:
powers = np.arange(1, 5 + 1); powers
root ** powers
"""
if not isinstance(n, (int, np.ndarray)):
raise TypeError(f"Argument `n` must be an int, not {type(n)!r}.")
verify_isinstance(n, (int, np.ndarray))
if not 1 <= n < cls.order:
raise ValueError(f"Argument `n` must be in [1, {cls.order}), not {n}.")
if not (cls.order - 1) % n == 0:
Expand Down
14 changes: 5 additions & 9 deletions galois/_fields/_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from typing import Union, Optional, Type
from typing_extensions import Literal

from .._helper import set_module
from .._helper import set_module, verify_isinstance
from .._modular import primitive_root, is_primitive_root
from .._polys import Poly, conway_poly
from .._prime import factors
Expand Down Expand Up @@ -197,14 +197,10 @@ def GF(
:group: galois-fields
"""
if not isinstance(order, int):
raise TypeError(f"Argument `order` must be an integer, not {type(order)}.")
if not isinstance(verify, bool):
raise TypeError(f"Argument `verify` must be a bool, not {type(verify)}.")
if not isinstance(compile, (type(None), str)):
raise TypeError(f"Argument `compile` must be a string, not {type(compile)}.")
if not isinstance(display, (type(None), str)):
raise TypeError(f"Argument `display` must be a string, not {type(display)}.")
verify_isinstance(order, int)
verify_isinstance(verify, bool)
verify_isinstance(compile, str, optional=True)
verify_isinstance(display, str, optional=True)

p, e = factors(order)
if not len(p) == len(e) == 1:
Expand Down
Loading

0 comments on commit 8edc8b4

Please sign in to comment.