Skip to content

Commit

Permalink
Adjust dense/sparse poly arithmetic threshold
Browse files Browse the repository at this point in the history
  • Loading branch information
mhostetter committed Mar 27, 2022
1 parent 215ad20 commit c8a753d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 51 deletions.
4 changes: 1 addition & 3 deletions galois/_fields/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2862,9 +2862,7 @@ class GF2(FieldArray, metaclass=GF2Meta, characteristic=2, degree=1, order=2, pr
###############################################################################

# Values were obtained by running scripts/sparse_poly_performance_test.py
SPARSE_VS_BINARY_POLY_FACTOR = 0.00_05
SPARSE_VS_BINARY_POLY_MIN_COEFFS = int(1 / SPARSE_VS_BINARY_POLY_FACTOR)
SPARSE_VS_DENSE_POLY_FACTOR = 0.00_5
SPARSE_VS_DENSE_POLY_FACTOR = 0.00_125 # 1.25% density
SPARSE_VS_DENSE_POLY_MIN_COEFFS = int(1 / SPARSE_VS_DENSE_POLY_FACTOR)


Expand Down
103 changes: 57 additions & 46 deletions scripts/sparse_poly_performance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,60 @@


def get_coeffs(degree, N, field):
degrees = np.random.randint(0, degree + 1, N, dtype=int)
degrees[0] = degree
coeffs = field.Random(N, low=1)
return degrees, coeffs


if True:
print("BinaryPoly vs SparsePoly".center(80, "-"))
GF = galois.GF2
N = 3 # Number of non-zero coefficients
degree = 500
while degree <= 25_000:
print(f"Nonzero: {N} / {degree}, {N/degree*100} %")
sp1 = galois.poly.SparsePoly(*get_coeffs(degree, N, GF))
sp2 = galois.poly.SparsePoly(*get_coeffs(degree, N, GF))
bp1 = galois.poly.BinaryPoly(sp1.integer)
bp2 = galois.poly.BinaryPoly(sp2.integer)

print(" BinaryPoly:\t", end="")
ipython.magic("timeit bp1 * bp2")

print(" SparsePoly:\t", end="")
ipython.magic("timeit sp1 * sp2")

degree *= 2


if True:
print("DensePoly vs SparsePoly".center(80, "-"))
GF = galois.GF(31)
N = 3 # Number of non-zero coefficients
degree = 500
while degree <= 25_000:
print(f"Nonzero: {N} / {degree}, {N/degree*100} %")
sp1 = galois.poly.SparsePoly(*get_coeffs(degree, N, GF))
sp2 = galois.poly.SparsePoly(*get_coeffs(degree, N, GF))
dp1 = galois.poly.BinaryPoly(sp1.integer)
dp2 = galois.poly.BinaryPoly(sp2.integer)

print(" DensePoly:\t", end="")
ipython.magic("timeit dp1 * dp2")

print(" SparsePoly:\t", end="")
ipython.magic("timeit sp1 * sp2")

degree *= 2
while True:
nonzero_degrees = np.random.randint(0, degree + 1, N, dtype=int)
nonzero_degrees[0] = degree
nonzero_coeffs = field.Random(N, low=1)
if nonzero_degrees.size == np.unique(nonzero_degrees).size:
break

return nonzero_degrees, nonzero_coeffs


GF = galois.GF(2**8)


# print("DensePoly vs SparsePoly Addition".center(80, "-"))
# N = 3 # Number of non-zero coefficients
# degree = 2000
# while degree <= 32000:
# print(f"Nonzero: {N} / {degree}, {N/degree*100} %")
# p1 = galois.Poly.Degrees(*get_coeffs(degree, N, GF))
# p2 = galois.Poly.Degrees(*get_coeffs(degree, N, GF))

# print(" SparsePoly:\t", end="")
# p1._type = "sparse"
# p2._type = "sparse"
# p1.nonzero_degrees, p1.nonzero_coeffs, p2.nonzero_degrees, p2.nonzero_coeffs
# ipython.run_line_magic("timeit", "p1 + p2")

# print(" DensePoly:\t", end="")
# p1._type = "dense"
# p2._type = "dense"
# p1.coeffs, p2.coeffs # Ensure _coeffs is created for arithmetic
# ipython.run_line_magic("timeit", "p1 + p2")

# degree *= 2


print("DensePoly vs SparsePoly Multiplication".center(80, "-"))
N = 3 # Number of non-zero coefficients
degree = 100
while degree <= 1000:
print(f"Nonzero: {N} / {degree}, {N/degree*100} %")
p1 = galois.Poly.Degrees(*get_coeffs(degree, N, GF))
p2 = galois.Poly.Degrees(*get_coeffs(degree, N, GF))

print(" SparsePoly:\t", end="")
p1._type = "sparse"
p2._type = "sparse"
p1.nonzero_degrees, p1.nonzero_coeffs, p2.nonzero_degrees, p2.nonzero_coeffs
ipython.run_line_magic("timeit", "p1 * p2")

print(" DensePoly:\t", end="")
p1._type = "dense"
p2._type = "dense"
p1.coeffs, p2.coeffs # Ensure _coeffs is created for arithmetic
ipython.run_line_magic("timeit", "p1 * p2")

degree += 100
4 changes: 2 additions & 2 deletions tests/polys/test_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,9 +196,9 @@ def test_len():
assert p._type == "binary"
assert len(p) == 1

p = galois.Poly.Str("x^1000 + 1", field=GF)
p = galois.Poly.Str("x^2000 + 1", field=GF)
assert p._type == "sparse"
assert len(p) == 1001
assert len(p) == 2001


def test_immutable():
Expand Down

0 comments on commit c8a753d

Please sign in to comment.