mhostetter / galois

A performant NumPy extension for Galois fields and their applications
https://mhostetter.github.io/galois/
MIT License
327 stars 30 forks source link

poly.degrees also returns degrees of zero coefficients #217

Closed geostergiop closed 2 years ago

geostergiop commented 2 years ago

Hi again Matt and happy new year,

Hope you are healthy. Just came across this one, not sure if it's a bug or intended functionality. the poly.degrees function on some polynomial returns all degrees including those with zero coefficient. Example:

In:
test = galois.Poly.Degrees([15, 5, 2 , 0])
print(test)

Out:
Poly(x^15 + x^5 + x^2 + 1, GF(2))
In:
test = galois.Poly.Degrees([15, 5, 2 , 0])
print(test.degrees)

Out:
[15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0]

Maybe this is intended, although I cannot seem to find a reason to get all positions on .degrees. I assume the most useful scenario would be to return degrees on coefs != 0 . If this is intended, is there another function to call to only get the no-zero degrees?

Happy 2022, George

mhostetter commented 2 years ago

Hey George,

Yes, it is by design. The accessor you're looking for is Poly.nonzero_degrees.

I can see the confusion since Poly.Degrees creates a polynomial from nonzero degrees/coefficients you might expect Poly.degrees to return the nonzero degrees. However, I set it up so that .degrees and .coeffs are one-for-one pairs and .nonzero_degrees and .nonzero_coeffs are one-for-one pairs.

Perhaps renaming Poly.Degrees to Poly.NonzeroDegrees would be more consistent, but it seems a bit verbose. :confused:

geostergiop commented 2 years ago

Thanks! I will close the current issue. In any case, I am looking for a way to test common coefficients between two galois.Polys, i.e. the coefficients in which they differ (both in 1s and 0s), but I am having a trouble accessing the .coeffs galois.FieldArray with .flat[0]. Currently I am using this ugly piece of code which simply counts the 1s from their difference, assuming that all zero coeffs are same between the two. len( (poly1 - poly2).nonzero_degrees) Is there a way to return the full binary matrix as as a single array/list?

mhostetter commented 2 years ago

@geostergiop are you trying to do something like this?

In [21]: import numpy as np                                                                                               

In [22]: poly1 = galois.Poly.Degrees([5, 4, 3, 0]); poly1.coeffs                                                          
Out[22]: GF([1, 1, 1, 0, 0, 1], order=2)

In [23]: poly2 = galois.Poly.Degrees([5, 3, 2, 0]); poly2.coeffs                                                          
Out[23]: GF([1, 0, 1, 1, 0, 1], order=2)

# Array the same shape as the coefficients and True when they're different
In [24]: poly1.coeffs != poly2.coeffs                                                                                     
Out[24]: array([False,  True, False,  True, False, False])

# The number of different coefficients
In [25]: np.sum(poly1.coeffs != poly2.coeffs)                                                                             
Out[25]: 2
geostergiop commented 2 years ago

Yep @mhostetter , that's way better, thanks! Actually, I am trying to build a characteristic polynomial of an element A in a GF, seems though you don't have anything implemented on that matter, right? For reference from wikipedia: image

Two element matrices may have the same characteristic polynomial but different minimal polynomials, e.g. image

mhostetter commented 2 years ago

@geostergiop no I don't yet, but open a new issue and we can add it. It could maybe be a method FieldArray.characteristic_poly() for square matrices only.