@@ -988,3 +988,92 @@ def q_stirling_number2(n, k, q=None):
988
988
return parent (q )(0 )
989
989
return (q ** (k - 1 )* q_stirling_number2 (n - 1 , k - 1 , q = q ) +
990
990
q_int (k , q = q ) * q_stirling_number2 (n - 1 , k , q = q ))
991
+
992
+
993
+ def number_of_irreducible_polynomials (n , q = None , m = 1 ):
994
+ r"""
995
+ Return the number of monic irreducible polynomials of degree ``n``
996
+ in ``m`` variables over the finite field with ``q`` elements.
997
+
998
+ If ``q`` is not given, the result is returned as an integer-valued
999
+ polynomial in `\QQ[q]`.
1000
+
1001
+ INPUT:
1002
+
1003
+ - ``n`` -- positive integer
1004
+ - ``q`` -- ``None`` (default) or a prime power
1005
+ - ``m`` -- positive integer (default `1`)
1006
+
1007
+ OUTPUT: integer or integer-valued polynomial over `\QQ`
1008
+
1009
+ EXAMPLES::
1010
+
1011
+ sage: number_of_irreducible_polynomials(8, q=2)
1012
+ 30
1013
+ sage: number_of_irreducible_polynomials(9, q=9)
1014
+ 43046640
1015
+ sage: number_of_irreducible_polynomials(5, q=11, m=3)
1016
+ 2079650567184059145647246367401741345157369643207055703168
1017
+
1018
+ ::
1019
+
1020
+ sage: poly = number_of_irreducible_polynomials(12); poly
1021
+ 1/12*q^12 - 1/12*q^6 - 1/12*q^4 + 1/12*q^2
1022
+ sage: poly(5) == number_of_irreducible_polynomials(12, q=5)
1023
+ True
1024
+ sage: poly = number_of_irreducible_polynomials(5, m=3); poly
1025
+ 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
1026
+ sage: poly(11) == number_of_irreducible_polynomials(5, q=11, m=3)
1027
+ True
1028
+
1029
+ This function is *much* faster than enumerating the polynomials::
1030
+
1031
+ sage: num = number_of_irreducible_polynomials(99, q=101)
1032
+ sage: num.bit_length()
1033
+ 653
1034
+
1035
+ ALGORITHM:
1036
+
1037
+ In the univariate case, classical formula
1038
+ `\frac1n \sum_{d\mid n} \mu(n/d) q^d`
1039
+ using the Möbius function `\mu`;
1040
+ see :func:`moebius`.
1041
+
1042
+ In the multivariate case, formula from [Bodin2007]_,
1043
+ independently [Alekseyev2006]_.
1044
+ """
1045
+ n = ZZ (n )
1046
+ if n <= 0 :
1047
+ raise ValueError ('n must be positive' )
1048
+ if m <= 0 :
1049
+ raise ValueError ('m must be positive' )
1050
+
1051
+ if q is None :
1052
+ from sage .rings .rational_field import QQ
1053
+ q = QQ ['q' ].gen () # we produce an integer-valued polynomial in q, but it does not necessarily have integer coefficients
1054
+
1055
+ if m == 1 :
1056
+ from sage .arith .misc import moebius
1057
+ r = sum ((moebius (n // d ) * q ** d for d in n .divisors ()), parent (q ).zero ())
1058
+ return r // n
1059
+
1060
+ from sage .functions .other import binomial
1061
+ from sage .combinat .partition import Partitions
1062
+
1063
+ def monic_reducible (irreducible , d ):
1064
+ """
1065
+ Compute the number of monic reducible polynomials of degree `d`
1066
+ given the numbers of irreducible polynomials up to degree `d-1`.
1067
+ """
1068
+ res = 0
1069
+ for p in Partitions (d + 1 , max_part = d ):
1070
+ res += prod (binomial (r + t - 1 , t ) for r , t in zip (irreducible , p .to_exp (d )))
1071
+ return res
1072
+
1073
+ r = []
1074
+ for d in range (n ):
1075
+ monic = (q ** binomial (d + m , m - 1 ) - 1 ) * q ** binomial (d + m , m ) // (q - 1 )
1076
+ reducible = monic_reducible (r , d )
1077
+ r .append (monic - reducible )
1078
+
1079
+ return r [- 1 ]
0 commit comments