Fast calculation of cyclotomic polynomials#
This module provides a function cyclotomic_coeffs()
, which calculates the
coefficients of cyclotomic polynomials. This is not intended to be invoked
directly by the user, but it is called by the method
cyclotomic_polynomial()
method of univariate polynomial ring objects and the top-level
cyclotomic_polynomial()
function.
- sage.rings.polynomial.cyclotomic.bateman_bound(nn)[source]#
Reference:
Bateman, P. T.; Pomerance, C.; Vaughan, R. C. On the size of the coefficients of the cyclotomic polynomial.
EXAMPLES:
sage: from sage.rings.polynomial.cyclotomic import bateman_bound sage: bateman_bound(2**8 * 1234567893377) # needs sage.libs.pari 66944986927
from sage.rings.polynomial.cyclotomic import bateman_bound bateman_bound(2**8 * 1234567893377) # needs sage.libs.pari
>>> from sage.all import * >>> from sage.rings.polynomial.cyclotomic import bateman_bound >>> bateman_bound(Integer(2)**Integer(8) * Integer(1234567893377)) # needs sage.libs.pari 66944986927
- sage.rings.polynomial.cyclotomic.cyclotomic_coeffs(nn, sparse=None)[source]#
Return the coefficients of the
-th cyclotomic polynomial by using the formulawhere
is the Möbius function that is 1 if has an even number of distinct prime divisors, if it has an odd number of distinct prime divisors, and if is not squarefree.Multiplications and divisions by polynomials of the form
can be done very quickly in a single pass.If
sparse
isTrue
, the result is returned as a dictionary of the non-zero entries, otherwise the result is returned as a list of python ints.EXAMPLES:
sage: from sage.rings.polynomial.cyclotomic import cyclotomic_coeffs sage: cyclotomic_coeffs(30) [1, 1, 0, -1, -1, -1, 0, 1, 1] sage: cyclotomic_coeffs(10^5) {0: 1, 10000: -1, 20000: 1, 30000: -1, 40000: 1} sage: R = QQ['x'] sage: R(cyclotomic_coeffs(30)) x^8 + x^7 - x^5 - x^4 - x^3 + x + 1
from sage.rings.polynomial.cyclotomic import cyclotomic_coeffs cyclotomic_coeffs(30) cyclotomic_coeffs(10^5) R = QQ['x'] R(cyclotomic_coeffs(30))
>>> from sage.all import * >>> from sage.rings.polynomial.cyclotomic import cyclotomic_coeffs >>> cyclotomic_coeffs(Integer(30)) [1, 1, 0, -1, -1, -1, 0, 1, 1] >>> cyclotomic_coeffs(Integer(10)**Integer(5)) {0: 1, 10000: -1, 20000: 1, 30000: -1, 40000: 1} >>> R = QQ['x'] >>> R(cyclotomic_coeffs(Integer(30))) x^8 + x^7 - x^5 - x^4 - x^3 + x + 1
Check that it has the right degree:
sage: euler_phi(30) # needs sage.libs.pari 8 sage: R(cyclotomic_coeffs(14)).factor() # needs sage.libs.pari x^6 - x^5 + x^4 - x^3 + x^2 - x + 1
euler_phi(30) # needs sage.libs.pari R(cyclotomic_coeffs(14)).factor() # needs sage.libs.pari
>>> from sage.all import * >>> euler_phi(Integer(30)) # needs sage.libs.pari 8 >>> R(cyclotomic_coeffs(Integer(14))).factor() # needs sage.libs.pari x^6 - x^5 + x^4 - x^3 + x^2 - x + 1
The coefficients are not always +/-1:
sage: cyclotomic_coeffs(105) [1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1]
cyclotomic_coeffs(105)
>>> from sage.all import * >>> cyclotomic_coeffs(Integer(105)) [1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1]
In fact the height is not bounded by any polynomial in
(Erdos), although takes a while just to exceed linear:sage: v = cyclotomic_coeffs(1181895) sage: max(v) 14102773
v = cyclotomic_coeffs(1181895) max(v)
>>> from sage.all import * >>> v = cyclotomic_coeffs(Integer(1181895)) >>> max(v) 14102773
The polynomial is a palindrome for any n:
sage: n = ZZ.random_element(50000) sage: v = cyclotomic_coeffs(n, sparse=False) sage: v == list(reversed(v)) True
n = ZZ.random_element(50000) v = cyclotomic_coeffs(n, sparse=False) v == list(reversed(v))
>>> from sage.all import * >>> n = ZZ.random_element(Integer(50000)) >>> v = cyclotomic_coeffs(n, sparse=False) >>> v == list(reversed(v)) True
AUTHORS:
Robert Bradshaw (2007-10-27): initial version (inspired by work of Andrew Arnold and Michael Monagan)
REFERENCE:
- sage.rings.polynomial.cyclotomic.cyclotomic_value(n, x)[source]#
Return the value of the
-th cyclotomic polynomial evaluated at .INPUT:
n
– an Integer, specifying which cyclotomic polynomial is to be evaluatedx
– an element of a ring
OUTPUT:
the value of the cyclotomic polynomial
at
ALGORITHM:
Reduce to the case that
is squarefree: use the identity
where
is the radical of .Use the identity
where
is the Möbius function.Handles the case that
for some , but not the case that is non-invertible: in this case polynomial evaluation is used instead.
EXAMPLES:
sage: cyclotomic_value(51, 3) 1282860140677441 sage: cyclotomic_polynomial(51)(3) 1282860140677441
cyclotomic_value(51, 3) cyclotomic_polynomial(51)(3)
>>> from sage.all import * >>> cyclotomic_value(Integer(51), Integer(3)) 1282860140677441 >>> cyclotomic_polynomial(Integer(51))(Integer(3)) 1282860140677441
It works for non-integral values as well:
sage: cyclotomic_value(144, 4/3) 79148745433504023621920372161/79766443076872509863361 sage: cyclotomic_polynomial(144)(4/3) 79148745433504023621920372161/79766443076872509863361
cyclotomic_value(144, 4/3) cyclotomic_polynomial(144)(4/3)
>>> from sage.all import * >>> cyclotomic_value(Integer(144), Integer(4)/Integer(3)) 79148745433504023621920372161/79766443076872509863361 >>> cyclotomic_polynomial(Integer(144))(Integer(4)/Integer(3)) 79148745433504023621920372161/79766443076872509863361