Skip to content

Commit 2c9908c

Browse files
maxaleyyyyx4
authored andcommitted
count irreducible multivariate polynomials, too
1 parent 6702f84 commit 2c9908c

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

src/doc/en/reference/references/index.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ REFERENCES:
4747
*Quantum compution with anyons: an F-matrix and braid calculator*
4848
(2022). https://arxiv.org/abs/2212.00831
4949
50+
.. [Alekseyev2006] \M. Alekseyev:
51+
(Forum post on counting irreducible multivariate polynomials),
52+
2006.
53+
https://dxdy.ru/post7034.html
54+
5055
.. [AB2007] \M. Aschenbrenner, C. Hillar,
5156
*Finite generation of symmetric ideals*.
5257
Trans. Amer. Math. Soc. 359 (2007), no. 11, 5171--5192.
@@ -503,6 +508,11 @@ REFERENCES:
503508
*A new construction for Hadamard matrices*.
504509
Bulletin of the American Mathematical Society 71(1):169-170, 1965.
505510
511+
.. [Bodin2007] \A. Bodin:
512+
Number of irreducible polynomials in several variables over finite fields,
513+
The American Mathematical Monthly 115(7), pp. 653-660, 2008.
514+
https://arxiv.org/abs/0706.0157
515+
506516
.. [BH2012] \A. Brouwer and W. Haemers,
507517
Spectra of graphs,
508518
Springer, 2012,

src/sage/combinat/q_analogues.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -976,32 +976,41 @@ def q_stirling_number2(n, k, q=None):
976976
q_int(k, q=q) * q_stirling_number2(n - 1, k, q=q))
977977

978978

979-
def number_of_irreducible_polynomials(n, q=None):
979+
def number_of_irreducible_polynomials(n, q=None, m=1):
980980
r"""
981981
Return the number of monic irreducible polynomials of degree ``n``
982-
over the finite field with ``q`` elements. If ``q`` is not given,
983-
the result is returned as a polynomial in `\QQ[q]`.
982+
in ``m`` variables over the finite field with ``q`` elements.
983+
984+
If ``q`` is not given, the result is returned as an integer-valued
985+
polynomial in `\QQ[q]`.
984986
985987
INPUT:
986988
987989
- ``n`` -- positive integer
988990
- ``q`` -- ``None`` (default) or a prime power
991+
- ``m`` -- positive integer (default `1`)
989992
990-
OUTPUT: integer
993+
OUTPUT: integer or integer-valued polynomial over `\QQ`
991994
992995
EXAMPLES::
993996
994997
sage: number_of_irreducible_polynomials(8, q=2)
995998
30
996999
sage: number_of_irreducible_polynomials(9, q=9)
9971000
43046640
1001+
sage: number_of_irreducible_polynomials(5, q=11, m=3)
1002+
2079650567184059145647246367401741345157369643207055703168
9981003
9991004
::
10001005
10011006
sage: poly = number_of_irreducible_polynomials(12); poly
10021007
1/12*q^12 - 1/12*q^6 - 1/12*q^4 + 1/12*q^2
10031008
sage: poly(5) == number_of_irreducible_polynomials(12, q=5)
10041009
True
1010+
sage: poly = number_of_irreducible_polynomials(5, m=3); poly
1011+
q^55 + q^54 + q^53 + q^52 + q^51 + q^50 + ... + 1/5*q^5 - 1/5*q^3 - 1/5*q^2 - 1/5*q
1012+
sage: poly(11) == number_of_irreducible_polynomials(5, q=11, m=3)
1013+
True
10051014
10061015
This function is *much* faster than enumerating the polynomials::
10071016
@@ -1011,17 +1020,31 @@ def number_of_irreducible_polynomials(n, q=None):
10111020
10121021
ALGORITHM:
10131022
1014-
Classical formula `\frac1n \sum_{d\mid n} \mu(n/d) q^d` using the
1015-
Möbius function `\mu`; see :func:`moebius`.
1023+
In the univariate case, classical formula
1024+
`\frac1n \sum_{d\mid n} \mu(n/d) q^d`
1025+
using the Möbius function `\mu`;
1026+
see :func:`moebius`.
1027+
1028+
In the multivariate case, formula from [Bodin2007]_,
1029+
independently [Alekseyev2006]_.
10161030
"""
10171031
n = ZZ(n)
10181032
if n <= 0:
10191033
raise ValueError('n must be positive')
10201034
if q is None:
1021-
q = ZZ['q'].gen()
1035+
from sage.rings.rational_field import QQ
1036+
q = QQ['q'].gen() # for m > 1, we produce an integer-valued polynomial in q, but it does not necessarily have integer coefficients
10221037
R = parent(q)
1023-
from sage.arith.misc import moebius
1024-
r = sum((moebius(n//d) * q**d for d in ZZ(n).divisors()), R.zero())
1025-
if R is ZZ:
1038+
if m == 1:
1039+
from sage.arith.misc import moebius
1040+
r = sum((moebius(n//d) * q**d for d in n.divisors()), R.zero())
10261041
return r // n
1027-
return r / n
1042+
elif m > 1:
1043+
from sage.functions.other import binomial
1044+
from sage.combinat.partition import Partitions
1045+
r = []
1046+
for d in range(n):
1047+
r.append( (q**binomial(d+m,m-1) - 1) // (q-1) * q**binomial(d+m,m) - sum(prod(binomial(r_+t-1,t) for r_,t in zip(r,p.to_exp(d))) for p in Partitions(d+1,max_part=d)) )
1048+
return r[-1]
1049+
else:
1050+
raise ValueError('m must be positive')

0 commit comments

Comments
 (0)