@@ -976,32 +976,41 @@ def q_stirling_number2(n, k, q=None):
976
976
q_int (k , q = q ) * q_stirling_number2 (n - 1 , k , q = q ))
977
977
978
978
979
- def number_of_irreducible_polynomials (n , q = None ):
979
+ def number_of_irreducible_polynomials (n , q = None , m = 1 ):
980
980
r"""
981
981
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]`.
984
986
985
987
INPUT:
986
988
987
989
- ``n`` -- positive integer
988
990
- ``q`` -- ``None`` (default) or a prime power
991
+ - ``m`` -- positive integer (default `1`)
989
992
990
- OUTPUT: integer
993
+ OUTPUT: integer or integer-valued polynomial over `\QQ`
991
994
992
995
EXAMPLES::
993
996
994
997
sage: number_of_irreducible_polynomials(8, q=2)
995
998
30
996
999
sage: number_of_irreducible_polynomials(9, q=9)
997
1000
43046640
1001
+ sage: number_of_irreducible_polynomials(5, q=11, m=3)
1002
+ 2079650567184059145647246367401741345157369643207055703168
998
1003
999
1004
::
1000
1005
1001
1006
sage: poly = number_of_irreducible_polynomials(12); poly
1002
1007
1/12*q^12 - 1/12*q^6 - 1/12*q^4 + 1/12*q^2
1003
1008
sage: poly(5) == number_of_irreducible_polynomials(12, q=5)
1004
1009
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
1005
1014
1006
1015
This function is *much* faster than enumerating the polynomials::
1007
1016
@@ -1011,17 +1020,31 @@ def number_of_irreducible_polynomials(n, q=None):
1011
1020
1012
1021
ALGORITHM:
1013
1022
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]_.
1016
1030
"""
1017
1031
n = ZZ (n )
1018
1032
if n <= 0 :
1019
1033
raise ValueError ('n must be positive' )
1020
1034
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
1022
1037
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 ())
1026
1041
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