def test_Domain_cyclotomic_field(): K = ZZ.cyclotomic_field(12) assert K.ext.minpoly == Poly(cyclotomic_poly(12)) assert K.dom == QQ F = QQ.cyclotomic_field(3) assert F.ext.minpoly == Poly(cyclotomic_poly(3)) assert F.dom == QQ E = F.cyclotomic_field(4) assert field_isomorphism(E.ext, K.ext) is not None assert E.dom == QQ
def roots_cyclotomic(f, factor=False): """Compute roots of cyclotomic polynomials. """ L, U = _inv_totient_estimate(f.degree()) for n in range(L, U + 1): g = cyclotomic_poly(n, f.gen, polys=True) if f == g: break else: # pragma: no cover raise RuntimeError("failed to find index of a cyclotomic polynomial") roots = [] if not factor: # get the indices in the right order so the computed # roots will be sorted h = n//2 ks = [i for i in range(1, n + 1) if igcd(i, n) == 1] ks.sort(key=lambda x: (x, -1) if x <= h else (abs(x - n), 1)) d = 2*I*pi/n for k in reversed(ks): roots.append(exp(k*d).expand(complex=True)) else: g = Poly(f, extension=root(-1, n)) for h, _ in ordered(g.factor_list()[1]): roots.append(-h.TC()) return roots
def roots_cyclotomic(f, factor=False): """Compute roots of cyclotomic polynomials. """ L, U = _inv_totient_estimate(f.degree()) for n in xrange(L, U + 1): g = cyclotomic_poly(n, f.gen, polys=True) if f == g: break else: # pragma: no cover raise RuntimeError("failed to find index of a cyclotomic polynomial") roots = [] if not factor: for k in xrange(1, n + 1): if igcd(k, n) == 1: roots.append(exp(2*k*S.Pi*I/n).expand(complex=True)) else: g = Poly(f, extension=(-1)**Rational(1, n)) for h, _ in g.factor_list()[1]: roots.append(-h.TC()) return sorted(roots, key=default_sort_key)
def roots_cyclotomic(f, factor=False): """Compute roots of cyclotomic polynomials. """ L, U = _inv_totient_estimate(f.degree()) for n in xrange(L, U + 1): g = cyclotomic_poly(n, f.gen, polys=True) if f == g: break else: # pragma: no cover raise RuntimeError("failed to find index of a cyclotomic polynomial") roots = [] if not factor: for k in xrange(1, n + 1): if igcd(k, n) == 1: roots.append(exp(2 * k * S.Pi * I / n).expand(complex=True)) else: g = Poly(f, extension=(-1)**Rational(1, n)) for h, _ in g.factor_list()[1]: roots.append(-h.TC()) return sorted(roots, key=default_sort_key)
def _minpoly_exp(ex, x): """ Returns the minimal polynomial of ``exp(ex)`` """ c, a = ex.args[0].as_coeff_Mul() if a == I * pi: if c.is_rational: q = sympify(c.q) if c.p == 1 or c.p == -1: if q == 3: return x**2 - x + 1 if q == 4: return x**4 + 1 if q == 6: return x**4 - x**2 + 1 if q == 8: return x**8 + 1 if q == 9: return x**6 - x**3 + 1 if q == 10: return x**8 - x**6 + x**4 - x**2 + 1 if q.is_prime: s = 0 for i in range(q): s += (-x)**i return s # x**(2*q) = product(factors) factors = [cyclotomic_poly(i, x) for i in divisors(2 * q)] mp = _choose_factor(factors, x, ex) return mp else: raise NotAlgebraic("%s does not seem to be an algebraic element" % ex) raise NotAlgebraic("%s does not seem to be an algebraic element" % ex)
def _minpoly_exp(ex, x): """ Returns the minimal polynomial of ``exp(ex)`` """ c, a = ex.args[0].as_coeff_Mul() p = sympify(c.p) q = sympify(c.q) if a == I*pi: if c.is_rational: if c.p == 1 or c.p == -1: if q == 3: return x**2 - x + 1 if q == 4: return x**4 + 1 if q == 6: return x**4 - x**2 + 1 if q == 8: return x**8 + 1 if q == 9: return x**6 - x**3 + 1 if q == 10: return x**8 - x**6 + x**4 - x**2 + 1 if q.is_prime: s = 0 for i in range(q): s += (-x)**i return s # x**(2*q) = product(factors) factors = [cyclotomic_poly(i, x) for i in divisors(2*q)] mp = _choose_factor(factors, x, ex) return mp else: raise NotAlgebraic("%s doesn't seem to be an algebraic element" % ex) raise NotAlgebraic("%s doesn't seem to be an algebraic element" % ex)
def test_cyclotomic_poly(): raises(ValueError, lambda: cyclotomic_poly(0, x)) assert cyclotomic_poly(1, x, polys=True) == Poly(x - 1) assert cyclotomic_poly(1, x) == x - 1 assert cyclotomic_poly(2, x) == x + 1 assert cyclotomic_poly(3, x) == x**2 + x + 1 assert cyclotomic_poly(4, x) == x**2 + 1 assert cyclotomic_poly(5, x) == x**4 + x**3 + x**2 + x + 1 assert cyclotomic_poly(6, x) == x**2 - x + 1
def test_evalf_real_alg_num(): # This test demonstrates why the entry for `AlgebraicNumber` in # `sympy.core.evalf._create_evalf_table()` has to use `x.to_root()`, # instead of `x.as_expr()`. If the latter is used, then `z` will be # a complex number with `0.e-20` for imaginary part, even though `a5` # is a real number. zeta = Symbol('zeta') a5 = AlgebraicNumber(CRootOf(cyclotomic_poly(5), -1), [-1, -1, 0, 0], alias=zeta) z = a5.evalf() assert isinstance(z, Float) assert not hasattr(z, '_mpc_') assert hasattr(z, '_mpf_')
def cyclotomic_field(self, n, ss=False, alias="zeta", gen=None, root_index=-1): r""" Convenience method to construct a cyclotomic field. Parameters ========== n : int Construct the nth cyclotomic field. ss : boolean, optional (default=False) If True, append *n* as a subscript on the alias string. alias : str, optional (default="zeta") Symbol name for the generator. gen : :py:class:`~.Symbol`, optional (default=None) Desired variable for the cyclotomic polynomial that defines the field. If ``None``, a dummy variable will be used. root_index : int, optional (default=-1) Specifies which root of the polynomial is desired. The ordering is as defined by the :py:class:`~.ComplexRootOf` class. The default of ``-1`` selects the root $\mathrm{e}^{2\pi i/n}$. Examples ======== >>> from sympy import QQ, latex >>> K = QQ.cyclotomic_field(5) >>> K.to_sympy(K([-1, 1])) 1 - zeta >>> L = QQ.cyclotomic_field(7, True) >>> a = L.to_sympy(L([-1, 1])) >>> print(a) 1 - zeta7 >>> print(latex(a)) 1 - \zeta_{7} """ from sympy.polys.specialpolys import cyclotomic_poly if ss: alias += str(n) return self.alg_field_from_poly(cyclotomic_poly(n, gen), alias=alias, root_index=root_index)