def test_AlgebraicField_integral_basis(): alpha = AlgebraicNumber(sqrt(5), alias='alpha') k = QQ.algebraic_field(alpha) B0 = k.integral_basis() B1 = k.integral_basis(fmt='sympy') B2 = k.integral_basis(fmt='alg') assert B0 == [k([1]), k([S.Half, S.Half])] assert B1 == [1, S.Half + alpha/2] assert B2 == [alpha.field_element([1]), alpha.field_element([S.Half, S.Half])]
def test_to_number_field(): assert to_number_field(sqrt(2)) == AlgebraicNumber(sqrt(2)) assert to_number_field( [sqrt(2), sqrt(3)]) == AlgebraicNumber(sqrt(2) + sqrt(3)) a = AlgebraicNumber(sqrt(2) + sqrt(3), [S.Half, S.Zero, Rational(-9, 2), S.Zero]) assert to_number_field(sqrt(2), sqrt(2) + sqrt(3)) == a assert to_number_field(sqrt(2), AlgebraicNumber(sqrt(2) + sqrt(3))) == a raises(IsomorphismFailed, lambda: to_number_field(sqrt(2), sqrt(3)))
def test_AlgebraicNumber(): a = AlgebraicNumber(sqrt(2)) sT( a, "AlgebraicNumber(Pow(Integer(2), Rational(1, 2)), [Integer(1), Integer(0)])" ) a = AlgebraicNumber(root(-2, 3)) sT( a, "AlgebraicNumber(Pow(Integer(-2), Rational(1, 3)), [Integer(1), Integer(0)])" )
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 test_field_isomorphism_pslq(): a = AlgebraicNumber(I) b = AlgebraicNumber(I * sqrt(3)) raises(NotImplementedError, lambda: field_isomorphism_pslq(a, b)) a = AlgebraicNumber(sqrt(2)) b = AlgebraicNumber(sqrt(3)) c = AlgebraicNumber(sqrt(7)) d = AlgebraicNumber(sqrt(2) + sqrt(3)) e = AlgebraicNumber(sqrt(2) + sqrt(3) + sqrt(7)) assert field_isomorphism_pslq(a, a) == [1, 0] assert field_isomorphism_pslq(a, b) is None assert field_isomorphism_pslq(a, c) is None assert field_isomorphism_pslq(a, d) == [Q(1, 2), 0, -Q(9, 2), 0] assert field_isomorphism_pslq( a, e) == [Q(1, 80), 0, -Q(1, 2), 0, Q(59, 20), 0] assert field_isomorphism_pslq(b, a) is None assert field_isomorphism_pslq(b, b) == [1, 0] assert field_isomorphism_pslq(b, c) is None assert field_isomorphism_pslq(b, d) == [-Q(1, 2), 0, Q(11, 2), 0] assert field_isomorphism_pslq(b, e) == [ -Q(3, 640), 0, Q(67, 320), 0, -Q(297, 160), 0, Q(313, 80), 0 ] assert field_isomorphism_pslq(c, a) is None assert field_isomorphism_pslq(c, b) is None assert field_isomorphism_pslq(c, c) == [1, 0] assert field_isomorphism_pslq(c, d) is None assert field_isomorphism_pslq(c, e) == [ Q(3, 640), 0, -Q(71, 320), 0, Q(377, 160), 0, -Q(469, 80), 0 ] assert field_isomorphism_pslq(d, a) is None assert field_isomorphism_pslq(d, b) is None assert field_isomorphism_pslq(d, c) is None assert field_isomorphism_pslq(d, d) == [1, 0] assert field_isomorphism_pslq(d, e) == [ -Q(3, 640), 0, Q(71, 320), 0, -Q(377, 160), 0, Q(549, 80), 0 ] assert field_isomorphism_pslq(e, a) is None assert field_isomorphism_pslq(e, b) is None assert field_isomorphism_pslq(e, c) is None assert field_isomorphism_pslq(e, d) is None assert field_isomorphism_pslq(e, e) == [1, 0] f = AlgebraicNumber(3 * sqrt(2) + 8 * sqrt(7) - 5) assert field_isomorphism_pslq( f, e) == [Q(3, 80), 0, -Q(139, 80), 0, Q(347, 20), 0, -Q(761, 20), -5]
def test_NumberKind(): assert S.One.kind is NumberKind assert pi.kind is NumberKind assert S.NaN.kind is NumberKind assert zoo.kind is NumberKind assert I.kind is NumberKind assert AlgebraicNumber(1).kind is NumberKind
def test_AlgebraicField_alias(): # No default alias: k = QQ.algebraic_field(sqrt(2)) assert k.ext.alias is None # For a single extension, its alias is used: alpha = AlgebraicNumber(sqrt(2), alias='alpha') k = QQ.algebraic_field(alpha) assert k.ext.alias.name == 'alpha' # Can override the alias of a single extension: k = QQ.algebraic_field(alpha, alias='theta') assert k.ext.alias.name == 'theta' # With multiple extensions, no default alias: k = QQ.algebraic_field(sqrt(2), sqrt(3)) assert k.ext.alias is None # With multiple extensions, no default alias, even if one of # the extensions has one: k = QQ.algebraic_field(alpha, sqrt(3)) assert k.ext.alias is None # With multiple extensions, may set an alias: k = QQ.algebraic_field(sqrt(2), sqrt(3), alias='theta') assert k.ext.alias.name == 'theta' # Alias is passed to constructed field elements: k = QQ.algebraic_field(alpha) beta = k.to_alg_num(k([1, 2, 3])) assert beta.alias is alpha.alias
def test_AlgebraicNumber_to_root(): assert AlgebraicNumber(sqrt(2)).to_root() == sqrt(2) zeta5_squared = AlgebraicNumber(CRootOf(x**5 - 1, 4), coeffs=[1, 0, 0]) assert zeta5_squared.to_root() == CRootOf(x**4 + x**3 + x**2 + x + 1, 1) zeta3_squared = AlgebraicNumber(CRootOf(x**3 - 1, 2), coeffs=[1, 0, 0]) assert zeta3_squared.to_root() == -S(1)/2 - sqrt(3)*I/2 assert zeta3_squared.to_root(radicals=False) == CRootOf(x**2 + x + 1, 0)
def test_to_algebraic_integer(): a = AlgebraicNumber(sqrt(3), gen=x).to_algebraic_integer() assert a.minpoly == x**2 - 3 assert a.root == sqrt(3) assert a.rep == DMP([QQ(1), QQ(0)], QQ) a = AlgebraicNumber(2*sqrt(3), gen=x).to_algebraic_integer() assert a.minpoly == x**2 - 12 assert a.root == 2*sqrt(3) assert a.rep == DMP([QQ(1), QQ(0)], QQ) a = AlgebraicNumber(sqrt(3)/2, gen=x).to_algebraic_integer() assert a.minpoly == x**2 - 12 assert a.root == 2*sqrt(3) assert a.rep == DMP([QQ(1), QQ(0)], QQ) a = AlgebraicNumber(sqrt(3)/2, [Rational(7, 19), 3], gen=x).to_algebraic_integer() assert a.minpoly == x**2 - 12 assert a.root == 2*sqrt(3) assert a.rep == DMP([QQ(7, 19), QQ(3)], QQ)
def alg_field_from_poly(self, poly, alias=None, root_index=-1): r""" Convenience method to construct an algebraic extension on a root of a polynomial, chosen by root index. Parameters ========== poly : :py:class:`~.Poly` The polynomial whose root generates the extension. alias : str, optional (default=None) Symbol name for the generator of the extension. E.g. "alpha" or "theta". 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 most natural choice in the common cases of quadratic and cyclotomic fields (the square root on the positive real or imaginary axis, resp. $\mathrm{e}^{2\pi i/n}$). Examples ======== >>> from sympy import QQ, Poly >>> from sympy.abc import x >>> f = Poly(x**2 - 2) >>> K = QQ.alg_field_from_poly(f) >>> K.ext.minpoly == f True >>> g = Poly(8*x**3 - 6*x - 1) >>> L = QQ.alg_field_from_poly(g, "alpha") >>> L.ext.minpoly == g True >>> L.to_sympy(L([1, 1, 1])) alpha**2 + alpha + 1 """ from sympy.polys.rootoftools import CRootOf root = CRootOf(poly, root_index) alpha = AlgebraicNumber(root, alias=alias) return self.algebraic_field(alpha)
def test_field_isomorphism(): assert field_isomorphism(3, sqrt(2)) == [3] assert field_isomorphism( I*sqrt(3), I*sqrt(3)/2) == [ 2, 0] assert field_isomorphism(-I*sqrt(3), I*sqrt(3)/2) == [-2, 0] assert field_isomorphism( I*sqrt(3), -I*sqrt(3)/2) == [-2, 0] assert field_isomorphism(-I*sqrt(3), -I*sqrt(3)/2) == [ 2, 0] assert field_isomorphism( 2*I*sqrt(3)/7, 5*I*sqrt(3)/3) == [ Rational(6, 35), 0] assert field_isomorphism(-2*I*sqrt(3)/7, 5*I*sqrt(3)/3) == [Rational(-6, 35), 0] assert field_isomorphism( 2*I*sqrt(3)/7, -5*I*sqrt(3)/3) == [Rational(-6, 35), 0] assert field_isomorphism(-2*I*sqrt(3)/7, -5*I*sqrt(3)/3) == [ Rational(6, 35), 0] assert field_isomorphism( 2*I*sqrt(3)/7 + 27, 5*I*sqrt(3)/3) == [ Rational(6, 35), 27] assert field_isomorphism( -2*I*sqrt(3)/7 + 27, 5*I*sqrt(3)/3) == [Rational(-6, 35), 27] assert field_isomorphism( 2*I*sqrt(3)/7 + 27, -5*I*sqrt(3)/3) == [Rational(-6, 35), 27] assert field_isomorphism( -2*I*sqrt(3)/7 + 27, -5*I*sqrt(3)/3) == [ Rational(6, 35), 27] p = AlgebraicNumber( sqrt(2) + sqrt(3)) q = AlgebraicNumber(-sqrt(2) + sqrt(3)) r = AlgebraicNumber( sqrt(2) - sqrt(3)) s = AlgebraicNumber(-sqrt(2) - sqrt(3)) pos_coeffs = [ S.Half, S.Zero, Rational(-9, 2), S.Zero] neg_coeffs = [Rational(-1, 2), S.Zero, Rational(9, 2), S.Zero] a = AlgebraicNumber(sqrt(2)) assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == pos_coeffs assert field_isomorphism(a, q, fast=True) == neg_coeffs assert field_isomorphism(a, r, fast=True) == pos_coeffs assert field_isomorphism(a, s, fast=True) == neg_coeffs assert field_isomorphism(a, p, fast=False) == pos_coeffs assert field_isomorphism(a, q, fast=False) == neg_coeffs assert field_isomorphism(a, r, fast=False) == pos_coeffs assert field_isomorphism(a, s, fast=False) == neg_coeffs a = AlgebraicNumber(-sqrt(2)) assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == neg_coeffs assert field_isomorphism(a, q, fast=True) == pos_coeffs assert field_isomorphism(a, r, fast=True) == neg_coeffs assert field_isomorphism(a, s, fast=True) == pos_coeffs assert field_isomorphism(a, p, fast=False) == neg_coeffs assert field_isomorphism(a, q, fast=False) == pos_coeffs assert field_isomorphism(a, r, fast=False) == neg_coeffs assert field_isomorphism(a, s, fast=False) == pos_coeffs pos_coeffs = [ S.Half, S.Zero, Rational(-11, 2), S.Zero] neg_coeffs = [Rational(-1, 2), S.Zero, Rational(11, 2), S.Zero] a = AlgebraicNumber(sqrt(3)) assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == neg_coeffs assert field_isomorphism(a, q, fast=True) == neg_coeffs assert field_isomorphism(a, r, fast=True) == pos_coeffs assert field_isomorphism(a, s, fast=True) == pos_coeffs assert field_isomorphism(a, p, fast=False) == neg_coeffs assert field_isomorphism(a, q, fast=False) == neg_coeffs assert field_isomorphism(a, r, fast=False) == pos_coeffs assert field_isomorphism(a, s, fast=False) == pos_coeffs a = AlgebraicNumber(-sqrt(3)) assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == pos_coeffs assert field_isomorphism(a, q, fast=True) == pos_coeffs assert field_isomorphism(a, r, fast=True) == neg_coeffs assert field_isomorphism(a, s, fast=True) == neg_coeffs assert field_isomorphism(a, p, fast=False) == pos_coeffs assert field_isomorphism(a, q, fast=False) == pos_coeffs assert field_isomorphism(a, r, fast=False) == neg_coeffs assert field_isomorphism(a, s, fast=False) == neg_coeffs pos_coeffs = [ Rational(3, 2), S.Zero, Rational(-33, 2), -S(8)] neg_coeffs = [Rational(-3, 2), S.Zero, Rational(33, 2), -S(8)] a = AlgebraicNumber(3*sqrt(3) - 8) assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == neg_coeffs assert field_isomorphism(a, q, fast=True) == neg_coeffs assert field_isomorphism(a, r, fast=True) == pos_coeffs assert field_isomorphism(a, s, fast=True) == pos_coeffs assert field_isomorphism(a, p, fast=False) == neg_coeffs assert field_isomorphism(a, q, fast=False) == neg_coeffs assert field_isomorphism(a, r, fast=False) == pos_coeffs assert field_isomorphism(a, s, fast=False) == pos_coeffs a = AlgebraicNumber(3*sqrt(2) + 2*sqrt(3) + 1) pos_1_coeffs = [ S.Half, S.Zero, Rational(-5, 2), S.One] neg_5_coeffs = [Rational(-5, 2), S.Zero, Rational(49, 2), S.One] pos_5_coeffs = [ Rational(5, 2), S.Zero, Rational(-49, 2), S.One] neg_1_coeffs = [Rational(-1, 2), S.Zero, Rational(5, 2), S.One] assert is_isomorphism_possible(a, p) is True assert is_isomorphism_possible(a, q) is True assert is_isomorphism_possible(a, r) is True assert is_isomorphism_possible(a, s) is True assert field_isomorphism(a, p, fast=True) == pos_1_coeffs assert field_isomorphism(a, q, fast=True) == neg_5_coeffs assert field_isomorphism(a, r, fast=True) == pos_5_coeffs assert field_isomorphism(a, s, fast=True) == neg_1_coeffs assert field_isomorphism(a, p, fast=False) == pos_1_coeffs assert field_isomorphism(a, q, fast=False) == neg_5_coeffs assert field_isomorphism(a, r, fast=False) == pos_5_coeffs assert field_isomorphism(a, s, fast=False) == neg_1_coeffs a = AlgebraicNumber(sqrt(2)) b = AlgebraicNumber(sqrt(3)) c = AlgebraicNumber(sqrt(7)) assert is_isomorphism_possible(a, b) is True assert is_isomorphism_possible(b, a) is True assert is_isomorphism_possible(c, p) is False assert field_isomorphism(sqrt(2), sqrt(3), fast=True) is None assert field_isomorphism(sqrt(3), sqrt(2), fast=True) is None assert field_isomorphism(sqrt(2), sqrt(3), fast=False) is None assert field_isomorphism(sqrt(3), sqrt(2), fast=False) is None a = AlgebraicNumber(sqrt(2)) b = AlgebraicNumber(2 ** (S(1) / 3)) assert is_isomorphism_possible(a, b) is False assert field_isomorphism(a, b) is None
def test_core_numbers(): for c in (Integer(2), Rational(2, 3), Float("1.2")): check(c) for c in (AlgebraicNumber, AlgebraicNumber(sqrt(3))): check(c, check_attr=False)
def test_minimal_polynomial(): assert minimal_polynomial(-7, x) == x + 7 assert minimal_polynomial(-1, x) == x + 1 assert minimal_polynomial(0, x) == x assert minimal_polynomial(1, x) == x - 1 assert minimal_polynomial(7, x) == x - 7 assert minimal_polynomial(sqrt(2), x) == x**2 - 2 assert minimal_polynomial(sqrt(5), x) == x**2 - 5 assert minimal_polynomial(sqrt(6), x) == x**2 - 6 assert minimal_polynomial(2 * sqrt(2), x) == x**2 - 8 assert minimal_polynomial(3 * sqrt(5), x) == x**2 - 45 assert minimal_polynomial(4 * sqrt(6), x) == x**2 - 96 assert minimal_polynomial(2 * sqrt(2) + 3, x) == x**2 - 6 * x + 1 assert minimal_polynomial(3 * sqrt(5) + 6, x) == x**2 - 12 * x - 9 assert minimal_polynomial(4 * sqrt(6) + 7, x) == x**2 - 14 * x - 47 assert minimal_polynomial(2 * sqrt(2) - 3, x) == x**2 + 6 * x + 1 assert minimal_polynomial(3 * sqrt(5) - 6, x) == x**2 + 12 * x - 9 assert minimal_polynomial(4 * sqrt(6) - 7, x) == x**2 + 14 * x - 47 assert minimal_polynomial(sqrt(1 + sqrt(6)), x) == x**4 - 2 * x**2 - 5 assert minimal_polynomial(sqrt(I + sqrt(6)), x) == x**8 - 10 * x**4 + 49 assert minimal_polynomial(2 * I + sqrt(2 + I), x) == x**4 + 4 * x**2 + 8 * x + 37 assert minimal_polynomial(sqrt(2) + sqrt(3), x) == x**4 - 10 * x**2 + 1 assert minimal_polynomial(sqrt(2) + sqrt(3) + sqrt(6), x) == x**4 - 22 * x**2 - 48 * x - 23 a = 1 - 9 * sqrt(2) + 7 * sqrt(3) assert minimal_polynomial( 1 / a, x) == 392 * x**4 - 1232 * x**3 + 612 * x**2 + 4 * x - 1 assert minimal_polynomial( 1 / sqrt(a), x) == 392 * x**8 - 1232 * x**6 + 612 * x**4 + 4 * x**2 - 1 raises(NotAlgebraic, lambda: minimal_polynomial(oo, x)) raises(NotAlgebraic, lambda: minimal_polynomial(2**y, x)) raises(NotAlgebraic, lambda: minimal_polynomial(sin(1), x)) assert minimal_polynomial(sqrt(2)).dummy_eq(x**2 - 2) assert minimal_polynomial(sqrt(2), x) == x**2 - 2 assert minimal_polynomial(sqrt(2), polys=True) == Poly(x**2 - 2) assert minimal_polynomial(sqrt(2), x, polys=True) == Poly(x**2 - 2, domain='QQ') assert minimal_polynomial(sqrt(2), x, polys=True, compose=False) == Poly(x**2 - 2, domain='QQ') a = AlgebraicNumber(sqrt(2)) b = AlgebraicNumber(sqrt(3)) assert minimal_polynomial(a, x) == x**2 - 2 assert minimal_polynomial(b, x) == x**2 - 3 assert minimal_polynomial(a, x, polys=True) == Poly(x**2 - 2, domain='QQ') assert minimal_polynomial(b, x, polys=True) == Poly(x**2 - 3, domain='QQ') assert minimal_polynomial(sqrt(a / 2 + 17), x) == 2 * x**4 - 68 * x**2 + 577 assert minimal_polynomial(sqrt(b / 2 + 17), x) == 4 * x**4 - 136 * x**2 + 1153 a, b = sqrt(2) / 3 + 7, AlgebraicNumber(sqrt(2) / 3 + 7) f = 81*x**8 - 2268*x**6 - 4536*x**5 + 22644*x**4 + 63216*x**3 - \ 31608*x**2 - 189648*x + 141358 assert minimal_polynomial(sqrt(a) + sqrt(sqrt(a)), x) == f assert minimal_polynomial(sqrt(b) + sqrt(sqrt(b)), x) == f assert minimal_polynomial(a**Q(3, 2), x) == 729 * x**4 - 506898 * x**2 + 84604519 # issue 5994 eq = S(''' -1/(800*sqrt(-1/240 + 1/(18000*(-1/17280000 + sqrt(15)*I/28800000)**(1/3)) + 2*(-1/17280000 + sqrt(15)*I/28800000)**(1/3)))''') assert minimal_polynomial(eq, x) == 8000 * x**2 - 1 ex = (sqrt(5) * sqrt(I) / (5 * sqrt(1 + 125 * I)) + 25 * sqrt(5) / (I**Q(5, 2) * (1 + 125 * I)**Q(3, 2)) + 3125 * sqrt(5) / (I**Q(11, 2) * (1 + 125 * I)**Q(3, 2)) + 5 * I * sqrt(1 - I / 125)) mp = minimal_polynomial(ex, x) assert mp == 25 * x**4 + 5000 * x**2 + 250016 ex = 1 + sqrt(2) + sqrt(3) mp = minimal_polynomial(ex, x) assert mp == x**4 - 4 * x**3 - 4 * x**2 + 16 * x - 8 ex = 1 / (1 + sqrt(2) + sqrt(3)) mp = minimal_polynomial(ex, x) assert mp == 8 * x**4 - 16 * x**3 + 4 * x**2 + 4 * x - 1 p = (expand((1 + sqrt(2) - 2 * sqrt(3) + sqrt(7))**3))**Rational(1, 3) mp = minimal_polynomial(p, x) assert mp == x**8 - 8 * x**7 - 56 * x**6 + 448 * x**5 + 480 * x**4 - 5056 * x**3 + 1984 * x**2 + 7424 * x - 3008 p = expand((1 + sqrt(2) - 2 * sqrt(3) + sqrt(7))**3) mp = minimal_polynomial(p, x) assert mp == x**8 - 512 * x**7 - 118208 * x**6 + 31131136 * x**5 + 647362560 * x**4 - 56026611712 * x**3 + 116994310144 * x**2 + 404854931456 * x - 27216576512 assert minimal_polynomial(S("-sqrt(5)/2 - 1/2 + (-sqrt(5)/2 - 1/2)**2"), x) == x - 1 a = 1 + sqrt(2) assert minimal_polynomial((a * sqrt(2) + a)**3, x) == x**2 - 198 * x + 1 p = 1 / (1 + sqrt(2) + sqrt(3)) assert minimal_polynomial( p, x, compose=False) == 8 * x**4 - 16 * x**3 + 4 * x**2 + 4 * x - 1 p = 2 / (1 + sqrt(2) + sqrt(3)) assert minimal_polynomial( p, x, compose=False) == x**4 - 4 * x**3 + 2 * x**2 + 4 * x - 2 assert minimal_polynomial(1 + sqrt(2) * I, x, compose=False) == x**2 - 2 * x + 3 assert minimal_polynomial(1 / (1 + sqrt(2)) + 1, x, compose=False) == x**2 - 2 assert minimal_polynomial(sqrt(2) * I + I * (1 + sqrt(2)), x, compose=False) == x**4 + 18 * x**2 + 49 # minimal polynomial of I assert minimal_polynomial(I, x, domain=QQ.algebraic_field(I)) == x - I K = QQ.algebraic_field(I * (sqrt(2) + 1)) assert minimal_polynomial(I, x, domain=K) == x - I assert minimal_polynomial(I, x, domain=QQ) == x**2 + 1 assert minimal_polynomial(I, x, domain='QQ(y)') == x**2 + 1 #issue 11553 assert minimal_polynomial(GoldenRatio, x) == x**2 - x - 1 assert minimal_polynomial(TribonacciConstant + 3, x) == x**3 - 10 * x**2 + 32 * x - 34 assert minimal_polynomial(GoldenRatio, x, domain=QQ.algebraic_field(sqrt(5))) == \ 2*x - sqrt(5) - 1 assert minimal_polynomial(TribonacciConstant, x, domain=QQ.algebraic_field(cbrt(19 - 3*sqrt(33)))) == \ 48*x - 19*(19 - 3*sqrt(33))**Rational(2, 3) - 3*sqrt(33)*(19 - 3*sqrt(33))**Rational(2, 3) \ - 16*(19 - 3*sqrt(33))**Rational(1, 3) - 16 # AlgebraicNumber with an alias. # Wester H24 phi = AlgebraicNumber(S.GoldenRatio.expand(func=True), alias='phi') assert minimal_polynomial(phi, x) == x**2 - x - 1
def test_AlgebraicNumber(): minpoly, root = x**2 - 2, sqrt(2) a = AlgebraicNumber(root, gen=x) assert a.rep == DMP([QQ(1), QQ(0)], QQ) assert a.root == root assert a.alias is None assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is False assert a.coeffs() == [S.One, S.Zero] assert a.native_coeffs() == [QQ(1), QQ(0)] a = AlgebraicNumber(root, gen=x, alias='y') assert a.rep == DMP([QQ(1), QQ(0)], QQ) assert a.root == root assert a.alias == Symbol('y') assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is True a = AlgebraicNumber(root, gen=x, alias=Symbol('y')) assert a.rep == DMP([QQ(1), QQ(0)], QQ) assert a.root == root assert a.alias == Symbol('y') assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is True assert AlgebraicNumber(sqrt(2), []).rep == DMP([], QQ) assert AlgebraicNumber(sqrt(2), ()).rep == DMP([], QQ) assert AlgebraicNumber(sqrt(2), (0, 0)).rep == DMP([], QQ) assert AlgebraicNumber(sqrt(2), [8]).rep == DMP([QQ(8)], QQ) assert AlgebraicNumber(sqrt(2), [Rational(8, 3)]).rep == DMP([QQ(8, 3)], QQ) assert AlgebraicNumber(sqrt(2), [7, 3]).rep == DMP([QQ(7), QQ(3)], QQ) assert AlgebraicNumber( sqrt(2), [Rational(7, 9), Rational(3, 2)]).rep == DMP([QQ(7, 9), QQ(3, 2)], QQ) assert AlgebraicNumber(sqrt(2), [1, 2, 3]).rep == DMP([QQ(2), QQ(5)], QQ) a = AlgebraicNumber(AlgebraicNumber(root, gen=x), [1, 2]) assert a.rep == DMP([QQ(1), QQ(2)], QQ) assert a.root == root assert a.alias is None assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is False assert a.coeffs() == [S.One, S(2)] assert a.native_coeffs() == [QQ(1), QQ(2)] a = AlgebraicNumber((minpoly, root), [1, 2]) assert a.rep == DMP([QQ(1), QQ(2)], QQ) assert a.root == root assert a.alias is None assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is False a = AlgebraicNumber((Poly(minpoly), root), [1, 2]) assert a.rep == DMP([QQ(1), QQ(2)], QQ) assert a.root == root assert a.alias is None assert a.minpoly == minpoly assert a.is_number assert a.is_aliased is False assert AlgebraicNumber( sqrt(3)).rep == DMP([ QQ(1), QQ(0)], QQ) assert AlgebraicNumber(-sqrt(3)).rep == DMP([ QQ(1), QQ(0)], QQ) a = AlgebraicNumber(sqrt(2)) b = AlgebraicNumber(sqrt(2)) assert a == b c = AlgebraicNumber(sqrt(2), gen=x) assert a == b assert a == c a = AlgebraicNumber(sqrt(2), [1, 2]) b = AlgebraicNumber(sqrt(2), [1, 3]) assert a != b and a != sqrt(2) + 3 assert (a == x) is False and (a != x) is True a = AlgebraicNumber(sqrt(2), [1, 0]) b = AlgebraicNumber(sqrt(2), [1, 0], alias=y) assert a.as_poly(x) == Poly(x, domain='QQ') assert b.as_poly() == Poly(y, domain='QQ') assert a.as_expr() == sqrt(2) assert a.as_expr(x) == x assert b.as_expr() == sqrt(2) assert b.as_expr(x) == x a = AlgebraicNumber(sqrt(2), [2, 3]) b = AlgebraicNumber(sqrt(2), [2, 3], alias=y) p = a.as_poly() assert p == Poly(2*p.gen + 3) assert a.as_poly(x) == Poly(2*x + 3, domain='QQ') assert b.as_poly() == Poly(2*y + 3, domain='QQ') assert a.as_expr() == 2*sqrt(2) + 3 assert a.as_expr(x) == 2*x + 3 assert b.as_expr() == 2*sqrt(2) + 3 assert b.as_expr(x) == 2*x + 3 a = AlgebraicNumber(sqrt(2)) b = to_number_field(sqrt(2)) assert a.args == b.args == (sqrt(2), Tuple(1, 0)) b = AlgebraicNumber(sqrt(2), alias='alpha') assert b.args == (sqrt(2), Tuple(1, 0), Symbol('alpha')) a = AlgebraicNumber(sqrt(2), [1, 2, 3]) assert a.args == (sqrt(2), Tuple(1, 2, 3)) a = AlgebraicNumber(sqrt(2), [1, 2], "alpha") b = AlgebraicNumber(a) c = AlgebraicNumber(a, alias="gamma") assert a == b assert c.alias.name == "gamma" a = AlgebraicNumber(sqrt(2) + sqrt(3), [S(1)/2, 0, S(-9)/2, 0]) b = AlgebraicNumber(a, [1, 0, 0]) assert b.root == a.root assert a.to_root() == sqrt(2) assert b.to_root() == 2 a = AlgebraicNumber(2) assert a.is_primitive_element is True
def field_isomorphism(a, b, *, fast=True): r""" Find an embedding of one number field into another. Explanation =========== This function looks for an isomorphism from $\mathbb{Q}(a)$ onto some subfield of $\mathbb{Q}(b)$. Thus, it solves the Subfield Problem. Examples ======== >>> from sympy import sqrt, field_isomorphism, I >>> print(field_isomorphism(3, sqrt(2))) # doctest: +SKIP [3] >>> print(field_isomorphism( I*sqrt(3), I*sqrt(3)/2)) # doctest: +SKIP [2, 0] Parameters ========== a : :py:class:`~.Expr` Any expression representing an algebraic number. b : :py:class:`~.Expr` Any expression representing an algebraic number. fast : boolean, optional (default=True) If ``True``, we first attempt a potentially faster way of computing the isomorphism, falling back on a slower method if this fails. If ``False``, we go directly to the slower method, which is guaranteed to return a result. Returns ======= List of rational numbers, or None If $\mathbb{Q}(a)$ is not isomorphic to some subfield of $\mathbb{Q}(b)$, then return ``None``. Otherwise, return a list of rational numbers representing an element of $\mathbb{Q}(b)$ to which $a$ may be mapped, in order to define a monomorphism, i.e. an isomorphism from $\mathbb{Q}(a)$ to some subfield of $\mathbb{Q}(b)$. The elements of the list are the coefficients of falling powers of $b$. """ a, b = sympify(a), sympify(b) if not a.is_AlgebraicNumber: a = AlgebraicNumber(a) if not b.is_AlgebraicNumber: b = AlgebraicNumber(b) a = a.to_primitive_element() b = b.to_primitive_element() if a == b: return a.coeffs() n = a.minpoly.degree() m = b.minpoly.degree() if n == 1: return [a.root] if m % n != 0: return None if fast: try: result = field_isomorphism_pslq(a, b) if result is not None: return result except NotImplementedError: pass return field_isomorphism_factor(a, b)
def test_issue_22561(): a = AlgebraicNumber(sqrt(2) + sqrt(3), [S(1) / 2, 0, S(-9) / 2, 0], gen=x) assert a.as_expr() == sqrt(2) assert minimal_polynomial(a, x) == x**2 - 2 assert minimal_polynomial(a**3, x) == x**2 - 8
def test_issue_22559(): alpha = AlgebraicNumber(sqrt(2)) assert minimal_polynomial(alpha**3, x) == x**2 - 8
def to_number_field(extension, theta=None, *, gen=None, alias=None): r""" Express one algebraic number in the field generated by another. Explanation =========== Given two algebraic numbers $\eta, \theta$, this function either expresses $\eta$ as an element of $\mathbb{Q}(\theta)$, or else raises an exception if $\eta \not\in \mathbb{Q}(\theta)$. This function is essentially just a convenience, utilizing :py:func:`~.field_isomorphism` (our solution of the Subfield Problem) to solve this, the Field Membership Problem. As an additional convenience, this function allows you to pass a list of algebraic numbers $\alpha_1, \alpha_2, \ldots, \alpha_n$ instead of $\eta$. It then computes $\eta$ for you, as a solution of the Primitive Element Problem, using :py:func:`~.primitive_element` on the list of $\alpha_i$. Examples ======== >>> from sympy import sqrt, to_number_field >>> eta = sqrt(2) >>> theta = sqrt(2) + sqrt(3) >>> a = to_number_field(eta, theta) >>> print(type(a)) <class 'sympy.core.numbers.AlgebraicNumber'> >>> a.root sqrt(2) + sqrt(3) >>> print(a) sqrt(2) >>> a.coeffs() [1/2, 0, -9/2, 0] We get an :py:class:`~.AlgebraicNumber`, whose ``.root`` is $\theta$, whose value is $\eta$, and whose ``.coeffs()`` show how to write $\eta$ as a $\mathbb{Q}$-linear combination in falling powers of $\theta$. Parameters ========== extension : :py:class:`~.Expr` or list of :py:class:`~.Expr` Either the algebraic number that is to be expressed in the other field, or else a list of algebraic numbers, a primitive element for which is to be expressed in the other field. theta : :py:class:`~.Expr`, None, optional (default=None) If an :py:class:`~.Expr` representing an algebraic number, behavior is as described under **Explanation**. If ``None``, then this function reduces to a shorthand for calling :py:func:`~.primitive_element` on ``extension`` and turning the computed primitive element into an :py:class:`~.AlgebraicNumber`. gen : :py:class:`~.Symbol`, None, optional (default=None) If provided, this will be used as the generator symbol for the minimal polynomial in the returned :py:class:`~.AlgebraicNumber`. alias : str, :py:class:`~.Symbol`, None, optional (default=None) If provided, this will be used as the alias symbol for the returned :py:class:`~.AlgebraicNumber`. Returns ======= AlgebraicNumber Belonging to $\mathbb{Q}(\theta)$ and equaling $\eta$. Raises ====== IsomorphismFailed If $\eta \not\in \mathbb{Q}(\theta)$. See Also ======== field_isomorphism primitive_element """ if hasattr(extension, '__iter__'): extension = list(extension) else: extension = [extension] if len(extension) == 1 and isinstance(extension[0], tuple): return AlgebraicNumber(extension[0], alias=alias) minpoly, coeffs = primitive_element(extension, gen, polys=True) root = sum([ coeff*ext for coeff, ext in zip(coeffs, extension) ]) if theta is None: return AlgebraicNumber((minpoly, root), alias=alias) else: theta = sympify(theta) if not theta.is_AlgebraicNumber: theta = AlgebraicNumber(theta, gen=gen, alias=alias) coeffs = field_isomorphism(root, theta) if coeffs is not None: return AlgebraicNumber(theta, coeffs, alias=alias) else: raise IsomorphismFailed( "%s is not in a subfield of %s" % (root, theta.root))
def test_issue_22849(): a = -8 + 3 * sqrt(3) x = AlgebraicNumber(a) assert evalf(a, 1, {}) == evalf(x, 1, {})