From d68f5376fe2160e300ac6b64c8a6db29c1419355 Mon Sep 17 00:00:00 2001 From: mhostetter Date: Fri, 4 Feb 2022 11:16:28 -0500 Subject: [PATCH] Add unit tests for integer logarithms --- galois/_math.py | 2 +- scripts/generate_int_test_vectors.py | 14 +++++++++++- tests/conftest.py | 10 +++++++- tests/data/ilog.pkl | Bin 0 -> 355 bytes tests/test_math.py | 21 +++++++++++++++++ tests/test_number_theory.py | 33 --------------------------- 6 files changed, 44 insertions(+), 36 deletions(-) create mode 100644 tests/data/ilog.pkl diff --git a/galois/_math.py b/galois/_math.py index 79dc47033..bfff7a685 100644 --- a/galois/_math.py +++ b/galois/_math.py @@ -185,7 +185,7 @@ def ilog(n: int, b: int) -> int: n : int A positive integer. b : int - The logarithm base :math:`b`. + The logarithm base :math:`b`, must be at least 2. Returns ------- diff --git a/scripts/generate_int_test_vectors.py b/scripts/generate_int_test_vectors.py index 25f51e037..e2ece2e12 100644 --- a/scripts/generate_int_test_vectors.py +++ b/scripts/generate_int_test_vectors.py @@ -11,7 +11,7 @@ import sage import numpy as np -from sage.all import Integer, xgcd, lcm, prod, isqrt +from sage.all import Integer, xgcd, lcm, prod, isqrt, log PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "tests") FOLDER = os.path.join(PATH, "data") @@ -108,3 +108,15 @@ def save_pickle(d, folder, name): Z[i] = int(z) d = {"X": X, "R": R, "Z": Z} save_pickle(d, FOLDER, "iroot.pkl") + +set_seed(SEED + 107) +X = [random.randint(1, 1000) for _ in range(20)] + [random.randint(1000, 1_000_000_000) for _ in range(20)] +B = [random.randint(2, 6) for _ in range(40)] +Z = [0,]*len(X) +for i in range(len(X)): + x = X[i] + b = B[i] + z = log(Integer(x), b) + Z[i] = int(z) +d = {"X": X, "B": B, "Z": Z} +save_pickle(d, FOLDER, "ilog.pkl") diff --git a/tests/conftest.py b/tests/conftest.py index b48e8aad8..f31d687ae 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -59,4 +59,12 @@ def iroot(): with open(os.path.join(FOLDER, "iroot.pkl"), "rb") as f: print(f"Loading {f}...") d = pickle.load(f) - return d \ No newline at end of file + return d + + +@pytest.fixture(scope="session") +def ilog(): + with open(os.path.join(FOLDER, "ilog.pkl"), "rb") as f: + print(f"Loading {f}...") + d = pickle.load(f) + return d diff --git a/tests/data/ilog.pkl b/tests/data/ilog.pkl new file mode 100644 index 0000000000000000000000000000000000000000..8715d270fe22c647ba1e0e5ecf36c513b9cd57dc GIT binary patch literal 355 zcmZo*nHs^!00y;FGLs@YeI@^!>r;%ggMm!sI)j$@dzQZw-_8E8jRqUn3@O zW#1fT-$hKmpP9S`eH)m4Et!2K8GUasd&Tk!YkP?VO_KH!*nLLa>+lQ<4zC93+wxvk za@L|=x1@eccxlIK%6nBWSYhhL!LZNBYx<2NDqbgeBQ3prtj$@xeoo9_^HLP8vhqsb z(dgX#OhC-)%?1=<1F}Jw z703puU;{%Cp9w4j5(lx_fFwvSNR$}}nSka-fz1VpZ~$dMkQ0bOvaH^WKsGZFGXiyj j>|*xj20|Gy29Z48LO?7F7UlNl1IkDMMTER%QcLv!kgZme literal 0 HcmV?d00001 diff --git a/tests/test_math.py b/tests/test_math.py index 39d0520fa..a0de6351e 100644 --- a/tests/test_math.py +++ b/tests/test_math.py @@ -125,3 +125,24 @@ def test_iroot(iroot): galois.iroot(10, 1) == 10 assert galois.iroot(0, 2) == 0 + + +def test_ilog_exceptions(): + with pytest.raises(TypeError): + galois.ilog(9.0, 2) + with pytest.raises(TypeError): + galois.ilog(9, 2.0) + with pytest.raises(ValueError): + galois.ilog(0, 2) + with pytest.raises(ValueError): + galois.ilog(-9, 2) + with pytest.raises(ValueError): + galois.ilog(9, 1) + + +def test_ilog(ilog): + X, B, Z = ilog["X"], ilog["B"], ilog["Z"] + for i in range(len(X)): + assert galois.ilog(X[i], B[i]) == Z[i] + + assert galois.ilog(10, 10) == 1 diff --git a/tests/test_number_theory.py b/tests/test_number_theory.py index 33f8e4207..4b8fad839 100644 --- a/tests/test_number_theory.py +++ b/tests/test_number_theory.py @@ -203,36 +203,3 @@ def test_is_cyclic(): assert galois.is_cyclic(2*5*7*9) == False assert all(galois.is_cyclic(n) == (galois.euler_phi(n) == galois.carmichael_lambda(n)) for n in range(1, 100)) - - -############################################################################### -# Integer arithmetic -############################################################################### - -def test_ilog_exceptions(): - with pytest.raises(TypeError): - galois.ilog(9.0, 2) - with pytest.raises(TypeError): - galois.ilog(9, 2.0) - with pytest.raises(ValueError): - galois.ilog(-9, 2) - with pytest.raises(ValueError): - galois.ilog(9, 1) - - -# TODO: Find a way to generate test vectors with Sage -def test_ilog(): - p = galois.mersenne_primes(2000)[-1] - exponent = galois.ilog(p, 17) - assert isinstance(exponent, int) - assert 17**exponent <= p and not 17**(exponent + 1) <= p - - p = galois.mersenne_primes(2000)[-1] - 1 - exponent = galois.ilog(p, 17) - assert isinstance(exponent, int) - assert 17**exponent <= p and not 17**(exponent + 1) <= p - - p = galois.mersenne_primes(2000)[-1] + 1 - exponent = galois.ilog(p, 17) - assert isinstance(exponent, int) - assert 17**exponent <= p and not 17**(exponent + 1) <= p