diff --git a/src/doc/en/prep/Programming.rst b/src/doc/en/prep/Programming.rst index 22a613a081b..8ca88b1a90d 100644 --- a/src/doc/en/prep/Programming.rst +++ b/src/doc/en/prep/Programming.rst @@ -728,7 +728,7 @@ not have :math:`I=\sqrt{-1}`, decimal points, or division. sage: parent(c) Real Field with 53 bits of precision sage: parent(d) - Symbolic Ring + Number Field in I with defining polynomial x^2 + 1 with I = 1*I sage: parent(e) - Symbolic Ring + Complex Field with 53 bits of precision diff --git a/src/sage/all.py b/src/sage/all.py index 3d144381cf6..a55dfcfd8e5 100644 --- a/src/sage/all.py +++ b/src/sage/all.py @@ -224,7 +224,6 @@ from sage.rings.qqbar import _init_qqbar _init_qqbar() - ########################################################### #### WARNING: # DO *not* import numpy / matplotlib / networkx here!! @@ -241,6 +240,8 @@ true = True false = False oo = infinity +from sage.rings.imaginary_unit import I +i = I from sage.misc.copying import license copying = license diff --git a/src/sage/categories/rings.py b/src/sage/categories/rings.py index 9a1acdd02ac..ea02c088a8b 100644 --- a/src/sage/categories/rings.py +++ b/src/sage/categories/rings.py @@ -999,7 +999,7 @@ def __getitem__(self, arg): and orders in number fields:: sage: ZZ[I] - Order in Number Field in I with defining polynomial x^2 + 1 with I = 1*I + Order in Number Field in I0 with defining polynomial x^2 + 1 with I0 = 1*I sage: ZZ[sqrt(5)] Order in Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? sage: ZZ[sqrt(2)+sqrt(3)] @@ -1054,8 +1054,6 @@ def __getitem__(self, arg): Embeddings:: - sage: QQ[I](I.pyobject()) - I sage: a = 10^100; expr = (2*a + sqrt(2))/(2*a^2-1) sage: QQ[expr].coerce_embedding() is None False diff --git a/src/sage/functions/special.py b/src/sage/functions/special.py index a41e6f2087c..31b59c8695f 100644 --- a/src/sage/functions/special.py +++ b/src/sage/functions/special.py @@ -166,7 +166,7 @@ from sage.symbolic.function import BuiltinFunction from sage.libs.mpmath import utils as mpmath_utils from sage.functions.all import sqrt, sin, cot, exp -from sage.symbolic.all import I +from sage.symbolic.constants import I class SphericalHarmonic(BuiltinFunction): diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py index 66edc59bc82..f3eab52363b 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_coercion.py @@ -20,7 +20,7 @@ #*********************************************************************** from sage.categories.morphism import Morphism -from sage.symbolic.all import I +from sage.symbolic.constants import I from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector from sage.rings.integer import Integer diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index b8244bf65e1..8f4e8503d8f 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -83,7 +83,7 @@ # ********************************************************************** from sage.structure.sage_object import SageObject -from sage.symbolic.all import I +from sage.symbolic.constants import I from sage.misc.lazy_attribute import lazy_attribute from sage.rings.infinity import infinity from sage.rings.all import CC, RR diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py index c3be5d26e15..9ccbb7caa63 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_model.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_model.py @@ -85,7 +85,7 @@ from sage.functions.all import arccosh from sage.rings.all import CC, RR, RDF from sage.rings.infinity import infinity -from sage.symbolic.all import I +from sage.symbolic.constants import I from sage.matrix.constructor import matrix from sage.categories.homset import Hom diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py index e297634a18b..570a1cd7310 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_point.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_point.py @@ -62,7 +62,7 @@ from sage.structure.element import Element from sage.structure.richcmp import richcmp, op_NE -from sage.symbolic.all import I +from sage.symbolic.constants import I from sage.misc.latex import latex from sage.structure.element import is_Matrix from sage.matrix.constructor import matrix diff --git a/src/sage/groups/abelian_gps/values.py b/src/sage/groups/abelian_gps/values.py index 288fb95b93c..1220230f7c8 100644 --- a/src/sage/groups/abelian_gps/values.py +++ b/src/sage/groups/abelian_gps/values.py @@ -164,7 +164,7 @@ class AbelianGroupWithValuesEmbedding(Morphism): sage: embedding = Z4.values_embedding(); embedding Generic morphism: From: Multiplicative Abelian group isomorphic to C4 - To: Symbolic Ring + To: Number Field in I with defining polynomial x^2 + 1 with I = 1*I sage: embedding(1) 1 sage: embedding(g) @@ -184,7 +184,7 @@ def __init__(self, domain, codomain): sage: AbelianGroupWithValuesEmbedding(Z4, Z4.values_group()) Generic morphism: From: Multiplicative Abelian group isomorphic to C4 - To: Symbolic Ring + To: Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ assert domain.values_group() is codomain from sage.categories.homset import Hom @@ -479,7 +479,7 @@ def values_group(self): sage: Z4 = AbelianGroupWithValues([I], [4]) sage: Z4.values_group() - Symbolic Ring + Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ return self._values_group @@ -497,6 +497,6 @@ def values_embedding(self): sage: Z4.values_embedding() Generic morphism: From: Multiplicative Abelian group isomorphic to C4 - To: Symbolic Ring + To: Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ return AbelianGroupWithValuesEmbedding(self, self.values_group()) diff --git a/src/sage/interfaces/fricas.py b/src/sage/interfaces/fricas.py index 597afea3df7..d838b67cda2 100644 --- a/src/sage/interfaces/fricas.py +++ b/src/sage/interfaces/fricas.py @@ -1563,8 +1563,7 @@ def _sage_expression(fricas_InputForm): D[0, 0, 1](f)(x + y, y) """ from sage.libs.pynac.pynac import register_symbol - from sage.symbolic.all import I - from sage.symbolic.constants import e, pi + from sage.symbolic.constants import e, pi, I from sage.calculus.functional import diff from sage.functions.log import dilog, lambert_w from sage.functions.trig import sin, cos, tan, cot, sec, csc @@ -1838,10 +1837,9 @@ def _sage_(self): Cannot convert the value from type Any to InputForm . """ - from sage.rings.all import PolynomialRing, RDF + from sage.rings.all import PolynomialRing, RDF, I from sage.rings.real_mpfr import RealField from sage.symbolic.ring import SR - from sage.symbolic.all import I from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector from sage.structure.factorization import Factorization diff --git a/src/sage/interfaces/gp.py b/src/sage/interfaces/gp.py index ee15afd5752..defae636800 100644 --- a/src/sage/interfaces/gp.py +++ b/src/sage/interfaces/gp.py @@ -891,9 +891,9 @@ def _sage_(self): EXAMPLES:: - sage: gp(I).sage() + sage: gp(SR(I)).sage() i - sage: gp(I).sage().parent() + sage: gp(SR(I)).sage().parent() Number Field in i with defining polynomial x^2 + 1 with i = 1*I :: @@ -971,7 +971,7 @@ def _complex_mpfr_field_(self, CC): EXAMPLES:: - sage: z = gp(1+15*I); z + sage: z = gp(SR(1+15*I)); z 1 + 15*I sage: z._complex_mpfr_field_(CC) 1.00000000000000 + 15.0000000000000*I diff --git a/src/sage/libs/pari/tests.py b/src/sage/libs/pari/tests.py index 415a707fe8b..eb1c04f1e6f 100644 --- a/src/sage/libs/pari/tests.py +++ b/src/sage/libs/pari/tests.py @@ -542,10 +542,14 @@ 0 sage: pari(-1/2).sign() -1 - sage: pari(I).sign() + sage: pari(SR(I)).sign() Traceback (most recent call last): ... PariError: incorrect type in gsigne (t_COMPLEX) + sage: pari(I).sign() + Traceback (most recent call last): + ... + PariError: incorrect type in gsigne (t_POLMOD) sage: y = pari('y') sage: x = pari('9') + y - y @@ -1197,7 +1201,7 @@ [0, 1/2, 0, -3/4, 0, 2, -3/2, 0, -9/16, 40, -116, 117/4, 256000/117, Vecsmall([1]), [Vecsmall([64, 1])], [0, 0, 0, 0, 0, 0, 0, 0]] sage: pari([0,0.5,0,-0.75,0]).ellinit() [0, 0.500000000000000, 0, -0.750000000000000, 0, 2.00000000000000, -1.50000000000000, 0, -0.562500000000000, 40.0000000000000, -116.000000000000, 29.2500000000000, 2188.03418803419, Vecsmall([0]), [Vecsmall([64, 1])], [0, 0, 0, 0]] - sage: pari([0,I,0,1,0]).ellinit() + sage: pari([0,SR(I),0,1,0]).ellinit() [0, I, 0, 1, 0, 4*I, 2, 0, -1, -64, 352*I, -80, 16384/5, Vecsmall([0]), [Vecsmall([64, 0])], [0, 0, 0, 0]] sage: x = SR.symbol('x') sage: pari([0,x,0,2*x,1]).ellinit() @@ -1336,9 +1340,9 @@ sage: e = pari([0,1,1,-2,0]).ellinit() sage: e.ellordinate(0) [0, -1] - sage: e.ellordinate(I) + sage: e.ellordinate(SR(I)) [0.582203589721741 - 1.38606082464177*I, -1.58220358972174 + 1.38606082464177*I] - sage: e.ellordinate(I, precision=128)[0].sage() + sage: e.ellordinate(SR(I), precision=128)[0].sage() 0.58220358972174117723338947874993600727 - 1.3860608246417697185311834209833653345*I sage: e.ellordinate(1+3*5^1+O(5^3)) [4*5 + 5^2 + O(5^3), 4 + 3*5^2 + O(5^3)] @@ -1361,9 +1365,9 @@ [0] sage: e.ellmul(p, 2) [1/4, -7/8] - sage: q = e.ellmul(p, 1+I); q + sage: q = e.ellmul(p, SR(1+I)); q [-2*I, 1 + I] - sage: e.ellmul(q, 1-I) + sage: e.ellmul(q, SR(1-I)) [1/4, -7/8] sage: for D in [-7, -8, -11, -12, -16, -19, -27, -28]: # long time (1s) ....: hcpol = hilbert_class_polynomial(D) @@ -1416,15 +1420,15 @@ sage: e.ellztopoint(0) [0] - sage: pari(I).ellj() + sage: pari(SR(I)).ellj() 1728.00000000000 - sage: pari(3*I).ellj() + sage: pari(SR(3*I)).ellj() 153553679.396729 sage: pari('quadgen(-3)').ellj() 0.E-54 sage: pari('quadgen(-7)').ellj(precision=256).sage() -3375.000000000000000000000000000000000000000000000000000000000000000000000000 - sage: pari(-I).ellj() + sage: pari(SR(-I)).ellj() Traceback (most recent call last): ... PariError: domain error in modular function: Im(argument) <= 0 diff --git a/src/sage/libs/pynac/pynac.pyx b/src/sage/libs/pynac/pynac.pyx index 882765e1f70..4c645545ac5 100644 --- a/src/sage/libs/pynac/pynac.pyx +++ b/src/sage/libs/pynac/pynac.pyx @@ -1174,9 +1174,9 @@ def py_is_crational_for_doctest(x): True sage: py_is_crational_for_doctest(1.5) False - sage: py_is_crational_for_doctest(I.pyobject()) + sage: py_is_crational_for_doctest(I) True - sage: py_is_crational_for_doctest(I.pyobject()+1/2) + sage: py_is_crational_for_doctest(I+1/2) True """ return py_is_crational(x) @@ -1310,11 +1310,11 @@ def py_is_cinteger_for_doctest(x): sage: from sage.libs.pynac.pynac import py_is_cinteger_for_doctest sage: py_is_cinteger_for_doctest(1) True - sage: py_is_cinteger_for_doctest(I.pyobject()) + sage: py_is_cinteger_for_doctest(I) True - sage: py_is_cinteger_for_doctest(I.pyobject() - 3) + sage: py_is_cinteger_for_doctest(I - 3) True - sage: py_is_cinteger_for_doctest(I.pyobject() + 1/2) + sage: py_is_cinteger_for_doctest(I + 1/2) False """ return py_is_cinteger(x) @@ -2350,20 +2350,21 @@ def init_pynac_I(): EXAMPLES:: - sage: I + sage: from sage.libs.pynac.pynac import I as symbolic_I + sage: symbolic_I I - sage: I^2 + sage: symbolic_I^2 -1 Note that conversions to real fields will give TypeErrors:: - sage: float(I) + sage: float(symbolic_I) Traceback (most recent call last): ... TypeError: unable to simplify to float approximation - sage: gp(I) + sage: gp(symbolic_I) I - sage: RR(I) + sage: RR(symbolic_I) Traceback (most recent call last): ... TypeError: unable to convert '1.00000000000000*I' to a real number @@ -2372,53 +2373,53 @@ def init_pynac_I(): sage: C = ComplexField(200); C Complex Field with 200 bits of precision - sage: C(I) + sage: C(symbolic_I) 1.0000000000000000000000000000000000000000000000000000000000*I - sage: I._complex_mpfr_field_(ComplexField(53)) + sage: symbolic_I._complex_mpfr_field_(ComplexField(53)) 1.00000000000000*I - sage: I._complex_double_(CDF) + sage: symbolic_I._complex_double_(CDF) 1.0*I - sage: CDF(I) + sage: CDF(symbolic_I) 1.0*I - sage: z = I + I; z + sage: z = symbolic_I + symbolic_I; z 2*I sage: C(z) 2.0000000000000000000000000000000000000000000000000000000000*I - sage: 1e8*I + sage: 1e8*symbolic_I 1.00000000000000e8*I - sage: complex(I) + sage: complex(symbolic_I) 1j - sage: QQbar(I) + sage: QQbar(symbolic_I) I - sage: abs(I) + sage: abs(symbolic_I) 1 - sage: I.minpoly() + sage: symbolic_I.minpoly() x^2 + 1 - sage: maxima(2*I) + sage: maxima(2*symbolic_I) 2*%i TESTS: - sage: repr(I) + sage: repr(symbolic_I) 'I' - sage: latex(I) + sage: latex(symbolic_I) i sage: sage.libs.pynac.pynac.init_pynac_I() sage: type(sage.libs.pynac.pynac.I) sage: type(sage.libs.pynac.pynac.I.pyobject()) - + Check that :trac:`10064` is fixed:: - sage: y = I*I*x / x # so y is the expression -1 + sage: y = symbolic_I*symbolic_I*x / x # so y is the expression -1 sage: y.is_positive() False sage: z = -x / x @@ -2428,9 +2429,8 @@ def init_pynac_I(): True """ global pynac_I, I - from sage.rings.number_field.number_field import QuadraticField - K = QuadraticField(-1, 'I', embedding=CC.gen(), latex_name='i') - pynac_I = K.gen() + from sage.rings.number_field.number_field import GaussianField + pynac_I = GaussianField().gen() ginac_pyinit_I(pynac_I) I = new_Expression_from_GEx(ring.SR, g_I) diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index 00136f65530..6f26b899bc4 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -2865,7 +2865,7 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_row(1,0,i) + sage: a.add_multiple_of_row(1,0,SR.I()) Traceback (most recent call last): ... TypeError: Multiplying row by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_row instead. @@ -2949,7 +2949,7 @@ cdef class Matrix(sage.structure.element.Matrix): If not, we get an error message:: - sage: a.add_multiple_of_column(1,0,i) + sage: a.add_multiple_of_column(1,0,SR.I()) Traceback (most recent call last): ... TypeError: Multiplying column by Symbolic Ring element cannot be done over Rational Field, use change_ring or with_added_multiple_of_column instead. diff --git a/src/sage/matrix/special.py b/src/sage/matrix/special.py index 5bc4e4e116e..bbaaf05034f 100644 --- a/src/sage/matrix/special.py +++ b/src/sage/matrix/special.py @@ -1233,7 +1233,7 @@ def elementary_matrix(arg0, arg1=None, **kwds): sage: E = elementary_matrix(4, row1=1, scale=I) sage: E.parent() - Full MatrixSpace of 4 by 4 dense matrices over Symbolic Ring + Full MatrixSpace of 4 by 4 dense matrices over Number Field in I with defining polynomial x^2 + 1 with I = 1*I sage: E = elementary_matrix(4, row1=1, scale=CDF(I)) sage: E.parent() diff --git a/src/sage/matrix/tests.py b/src/sage/matrix/tests.py index a284f86c37e..21b7920307a 100644 --- a/src/sage/matrix/tests.py +++ b/src/sage/matrix/tests.py @@ -52,7 +52,7 @@ [-1.00000000000000*I -1.00000000000000*I] [-1.00000000000000*I -1.00000000000000*I] sage: A.parent() - Full MatrixSpace of 2 by 2 dense matrices over Symbolic Ring + Full MatrixSpace of 2 by 2 dense matrices over Complex Field with 53 bits of precision We test an example determinant computation where LinBox gave an incorrect result:: diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index d05b67c87af..32b3fe79520 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -341,10 +341,10 @@ def default_num_prec(self, prec=None): sage: MF.default_num_prec() 10 sage: E6 = MF.E6() - sage: E6(i + 1e-1000) + sage: E6(i + 10^(-1000)) 0.002... - 6.7...e-1000*I sage: MF.default_num_prec(100) - sage: E6(i + 1e-1000) + sage: E6(i + 10^(-1000)) 3.9946838...e-1999 - 6.6578064...e-1000*I sage: MF = ModularForms(n=5, k=4/3) diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index 092fa8c7c39..fe8657df316 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -17,8 +17,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.symbolic.all import i -from sage.rings.all import ZZ, QQ, infinity, AlgebraicField +from sage.rings.all import ZZ, QQ, infinity, AlgebraicField, I from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.power_series_ring import is_PowerSeriesRing from sage.rings.laurent_series_ring import is_LaurentSeriesRing @@ -759,7 +758,7 @@ def aut_factor(self, gamma, t): if (gamma.is_translation()): return ZZ(1) elif (gamma.is_reflection()): - return self._ep * (t/AlgebraicField()(i))**self._weight + return self._ep * (t/AlgebraicField()(I))**self._weight else: L = [v for v in gamma.word_S_T()[0]] aut_f = ZZ(1) diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py index eb0811ebc68..f0625ec01a5 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py @@ -2758,7 +2758,7 @@ def linking_number(self): 5.40301236071... + 0.926018962976...*I 6 - sage: z = - 2.3 + 3.1*i + sage: z = ComplexField(1000)(- 2.3 + 3.1*i) sage: B = G.I() sage: for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: ....: print("A={}: ".format(A.string_repr("conj"))) @@ -2780,7 +2780,7 @@ def linking_number(self): 5.99730551444... + 0.000847636355069...*I 6 - sage: z = - 2.3 + 3.1*i + sage: z = ComplexField(5000)(- 2.3 + 3.1*i) sage: B = G.U() sage: for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: # long time ....: print("A={}: ".format(A.string_repr("conj"))) @@ -3106,10 +3106,15 @@ def acton(self, tau): sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(5) - sage: G.S().acton(1 + i/2) + sage: G.S().acton(SR(1 + i/2)) 2/5*I - 4/5 - sage: G.S().acton(1 + i/2).parent() + sage: G.S().acton(SR(1 + i/2)).parent() Symbolic Ring + sage: G.S().acton(QQbar(1 + i/2)) + 2/5*I - 4/5 + sage: G.S().acton(QQbar(1 + i/2)).parent() + Algebraic Field + sage: G.S().acton(i + exp(-2)) -1/(e^(-2) + I) sage: G.S().acton(i + exp(-2)).parent() diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index cb336f64c43..db0fcb5acca 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -17,10 +17,10 @@ # **************************************************************************** from __future__ import print_function, absolute_import -from sage.rings.all import ZZ, QQ, AA, AlgebraicField, infinity, PolynomialRing, NumberField +from sage.rings.all import ZZ, QQ, AA, AlgebraicField, infinity, I, PolynomialRing, NumberField from sage.functions.all import cos, exp, sec from sage.functions.gamma import psi1 -from sage.symbolic.all import pi, i +from sage.symbolic.all import pi from sage.matrix.constructor import matrix from sage.misc.latex import latex from sage.misc.misc_c import prod @@ -300,7 +300,7 @@ def rho(self): if self._n == infinity: return coerce_AA(1) else: - rho = AlgebraicField()(exp(pi / self._n * i)) + rho = AlgebraicField()(exp(pi / self._n * I)) rho.simplify() return rho diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 73e304b2702..60591731fe9 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -213,9 +213,9 @@ def _call_with_args(self, x, args=(), kwds={}): sage: f((1, 0)) Traceback (most recent call last): ... - TypeError: Unable to coerce entries (=[1.00000000000000*I, 0]) to coefficients in Real Field with 53 bits of precision + TypeError: Unable to coerce entries (=[1.00000000000000*I, 0.000000000000000]) to coefficients in Real Field with 53 bits of precision sage: f((1, 0), coerce=False) - (1.00000000000000*I, 0) + (1.00000000000000*I, 0.000000000000000) """ if self.domain().is_ambient(): diff --git a/src/sage/quadratic_forms/special_values.py b/src/sage/quadratic_forms/special_values.py index 2bda155663d..d1cbbf8cab4 100644 --- a/src/sage/quadratic_forms/special_values.py +++ b/src/sage/quadratic_forms/special_values.py @@ -18,8 +18,7 @@ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.rational_field import QQ from sage.rings.real_mpfr import is_RealField -from sage.symbolic.constants import pi -from sage.symbolic.all import I +from sage.symbolic.constants import pi, I # ---------------- The Gamma Function ------------------ diff --git a/src/sage/rings/all.py b/src/sage/rings/all.py index 03105c6b82f..50f0a4e190c 100644 --- a/src/sage/rings/all.py +++ b/src/sage/rings/all.py @@ -109,6 +109,8 @@ from sage.rings.complex_arb import ComplexBallField, CBF +lazy_import("sage.rings.imaginary_unit", "I") + # Power series rings from .power_series_ring import PowerSeriesRing from .power_series_ring_element import PowerSeries diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index 950435f9691..3bcb2a3790d 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -422,7 +422,7 @@ cdef class MPComplexField_class(sage.rings.ring.Field): sage: C20(i*4, 7) Traceback (most recent call last): ... - TypeError: unable to coerce to a ComplexNumber: + TypeError: unable to coerce to a ComplexNumber: Each part can be set with strings (written in base ten):: @@ -863,14 +863,9 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): real, imag = z elif isinstance(z, complex): real, imag = z.real, z.imag - elif isinstance(z, sage.symbolic.expression.Expression): - zz = sage.rings.complex_mpfr.ComplexField(self._parent.prec())(z) - self._set(zz) - return elif type(z) is gmpy2.mpc: mpc_set(self.value, (z).c, rnd) return - # then, no imaginary part elif type(z) is gmpy2.mpfr: mpc_set_fr(self.value, (z).f, rnd) return @@ -891,8 +886,13 @@ cdef class MPComplexNumber(sage.structure.element.FieldElement): mpc_set_si(self.value, z, rnd) return else: - real = z - imag = 0 + C = sage.rings.complex_mpfr.ComplexField(self._parent.prec()) + if C.has_coerce_map_from(z.parent()) or isinstance(z, sage.symbolic.expression.Expression): + self._set(C(z)) + return + else: + real = z + imag = 0 else: real = z imag = y diff --git a/src/sage/rings/imaginary_unit.py b/src/sage/rings/imaginary_unit.py new file mode 100644 index 00000000000..09349e66e8b --- /dev/null +++ b/src/sage/rings/imaginary_unit.py @@ -0,0 +1,5 @@ +# coding: utf-8 + +from .number_field.number_field import GaussianField + +I = GaussianField().gen() diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index 469f0446552..c3dd79b4e3e 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -1274,6 +1274,17 @@ def _coerce_map_from_(self, R): pass return False + def _pushout_(self, other): + r""" + EXAMPLES:: + + sage: QQbar(-2*i)*infinity + (-I)*Infinity + """ + from sage.symbolic.ring import SR + if SR.has_coerce_map_from(other): + return SR + class FiniteNumber(RingElement): diff --git a/src/sage/rings/number_field/number_field.py b/src/sage/rings/number_field/number_field.py index 9bb756cc82c..9a5bc410ea4 100644 --- a/src/sage/rings/number_field/number_field.py +++ b/src/sage/rings/number_field/number_field.py @@ -979,6 +979,24 @@ def QuadraticField(D, name='a', check=True, embedding=True, latex_name='sqrt', * latex_name = r'\sqrt{%s}' % D return NumberField(f, name, check=False, embedding=embedding, latex_name=latex_name, **args) +def GaussianField(): + r""" + The field QQ[i]. + + TESTS:: + + sage: from sage.rings.number_field.number_field import GaussianField + sage: QQi = GaussianField() + sage: QQi.coerce_embedding() + Generic morphism: + From: Number Field in I with defining polynomial x^2 + 1 with I = 1*I + To: Complex Lazy Field + Defn: I -> 1*I + sage: (I + 1/2).parent() is GaussianField() + True + """ + return QuadraticField(-1, 'I', latex_name='i') + def is_AbsoluteNumberField(x): """ Return True if x is an absolute number field. @@ -11387,8 +11405,11 @@ def __init__(self, polynomial, name=None, latex_name=None, check=True, embedding embedding=embedding, latex_name=latex_name, assume_disc_small=assume_disc_small, maximize_at_primes=maximize_at_primes, structure=structure) self._standard_embedding = True - self._element_class = number_field_element_quadratic.NumberFieldElement_quadratic c, b, a = [QQ(t) for t in self.defining_polynomial().list()] + if a.is_one() and b.is_zero() and c.is_one(): + self._element_class = number_field_element_quadratic.NumberFieldElement_gaussian + else: + self._element_class = number_field_element_quadratic.NumberFieldElement_quadratic # set the generator Dpoly = b*b - 4*a*c D = (Dpoly.numer() * Dpoly.denom()).squarefree_part(bound=10000) diff --git a/src/sage/rings/number_field/number_field_element.pyx b/src/sage/rings/number_field/number_field_element.pyx index 33414cea37a..0c2499bfeeb 100644 --- a/src/sage/rings/number_field/number_field_element.pyx +++ b/src/sage/rings/number_field/number_field_element.pyx @@ -2324,7 +2324,7 @@ cdef class NumberFieldElement(FieldElement): sage: 2^a Traceback (most recent call last): ... - TypeError: an embedding into RR or CC must be specified + TypeError: no canonical coercion from Number Field in a with defining polynomial x^2 + 1 to Symbolic Ring """ if (isinstance(base, NumberFieldElement) and (isinstance(exp, Integer) or type(exp) is int or exp in ZZ)): diff --git a/src/sage/rings/number_field/number_field_element_quadratic.pyx b/src/sage/rings/number_field/number_field_element_quadratic.pyx index 9583a2c20ba..b261d26d6c9 100644 --- a/src/sage/rings/number_field/number_field_element_quadratic.pyx +++ b/src/sage/rings/number_field/number_field_element_quadratic.pyx @@ -44,6 +44,7 @@ from sage.libs.ntl.ntl_ZZ cimport ntl_ZZ from sage.libs.ntl.ntl_ZZX cimport ntl_ZZX from sage.libs.mpfi cimport * + from sage.structure.parent_base cimport ParentWithBase from sage.structure.element cimport Element from sage.structure.richcmp cimport rich_to_bool_sgn @@ -1857,7 +1858,7 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): -1/2 sage: SR(a) 1/2*I*sqrt(3) - 1/2 - sage: bool(I*a.imag() + a.real() == a) + sage: bool(QQbar(I)*QQbar(a.imag()) + QQbar(a.real()) == QQbar(a)) True TESTS:: @@ -2373,6 +2374,79 @@ cdef class NumberFieldElement_quadratic(NumberFieldElement_absolute): else: return n +cdef class NumberFieldElement_gaussian(NumberFieldElement_quadratic): + r""" + An element of `\QQ[i]`. + + Some methods of this class behave slightly differently than the + corresponding methods of general elements of quadratic number fields, + especially with regard to conversions to parents that can represent complex + numbers in rectangular form. + + In addition, this class provides some convenience methods similar to methods + of symbolic expressions to make the behavior of ``a + I*b`` with rational + ``a``, ``b`` closer to that when ``a``, ``b`` are expressions. + + TESTS:: + + sage: type(I) + + """ + + def _symbolic_(self, SR): + r""" + EXAMPLES:: + + sage: SR(1 + 2*i) + 2*I + 1 + """ + from sage.symbolic.constants import I + return self[1]*I + self[0] + + cpdef real_part(self): + r""" + Real part. + + EXAMPLES:: + + sage: (1 + 2*I).real() + 1 + sage: (1 + 2*I).real().parent() + Rational Field + """ + return self[0] + + real = real_part + + cpdef imag_part(self): + r""" + Imaginary part. + + EXAMPLES:: + + sage: (1 + 2*I).imag() + 2 + sage: (1 + 2*I).imag().parent() + Rational Field + """ + return self[1] + + imag = imag_part + + # for compatibility with the old symbolic I + + def log(self, *args, **kwds): + r""" + Complex logarithm (standard branch). + + EXAMPLES:: + + sage: I.log() + 1/2*I*pi + """ + from sage.symbolic.ring import SR + return SR(self).log(*args, **kwds) + cdef class OrderElement_quadratic(NumberFieldElement_quadratic): """ Element of an order in a quadratic field. diff --git a/src/sage/rings/number_field/order.py b/src/sage/rings/number_field/order.py index 82e2cd2d078..82a9da5cdb0 100644 --- a/src/sage/rings/number_field/order.py +++ b/src/sage/rings/number_field/order.py @@ -2140,7 +2140,7 @@ def relative_order_from_ring_generators(gens, return RelativeOrder(K, abs_order, check=False, is_maximal=is_maximal) -def GaussianIntegers(names="I"): +def GaussianIntegers(names="I", latex_name="i"): r""" Return the ring of Gaussian integers. @@ -2163,7 +2163,7 @@ def GaussianIntegers(names="I"): """ from sage.rings.all import CDF, NumberField f = ZZ['x']([1, 0, 1]) - nf = NumberField(f, names, embedding=CDF(0, 1)) + nf = NumberField(f, names, embedding=CDF(0, 1), latex_name=latex_name) return nf.ring_of_integers() diff --git a/src/sage/rings/polynomial/cyclotomic.pyx b/src/sage/rings/polynomial/cyclotomic.pyx index 06c5231466d..813249ad05c 100644 --- a/src/sage/rings/polynomial/cyclotomic.pyx +++ b/src/sage/rings/polynomial/cyclotomic.pyx @@ -283,9 +283,7 @@ def cyclotomic_value(n, x): Check that the issue with symbolic element in :trac:`14982` is fixed:: sage: a = cyclotomic_value(3, I) - sage: a.pyobject() - I - sage: parent(_) + sage: parent(a) Number Field in I with defining polynomial x^2 + 1 with I = 1*I """ n = ZZ(n) diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index 11b553fb5a4..441f901c1af 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -667,7 +667,7 @@ cdef class Polynomial_rational_flint(Polynomial): else: try: len = (degree + 1) - except ValueError: + except (TypeError, ValueError): raise ValueError('degree must be convertible to long') res = self._new() diff --git a/src/sage/rings/puiseux_series_ring_element.pyx b/src/sage/rings/puiseux_series_ring_element.pyx index ea9501c4c4b..50299bd7c2e 100644 --- a/src/sage/rings/puiseux_series_ring_element.pyx +++ b/src/sage/rings/puiseux_series_ring_element.pyx @@ -49,7 +49,7 @@ Mind the base ring. However, the base ring can be changed:: sage: I*q Traceback (most recent call last): ... - TypeError: unsupported operand parent(s) for *: 'Symbolic Ring' and 'Puiseux Series Ring in x over Rational Field' + TypeError: unsupported operand parent(s) for *: 'Number Field in I with defining polynomial x^2 + 1 with I = 1*I' and 'Puiseux Series Ring in x over Rational Field' sage: qz = q.change_ring(ZZ); qz x^(1/3) + x^(1/2) sage: qz.parent() diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index a39cb55104a..4882bf66eaf 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -542,7 +542,7 @@ from sage.rings.polynomial.polynomial_element import is_Polynomial from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.rings.number_field.number_field import NumberField, QuadraticField, CyclotomicField +from sage.rings.number_field.number_field import NumberField, GaussianField, CyclotomicField from sage.rings.number_field.number_field_element_quadratic import NumberFieldElement_quadratic from sage.arith.all import factor from . import infinity @@ -8341,7 +8341,7 @@ def _init_qqbar(): AA_0 = AA.zero() - QQbar_I_nf = QuadraticField(-1, 'I', embedding=CC.gen(), latex_name='i') + QQbar_I_nf = GaussianField() QQbar_I_generator = AlgebraicGenerator(QQbar_I_nf, ANRoot(AAPoly.gen()**2 + 1, CIF(0, 1))) QQbar_I = AlgebraicNumber(ANExtensionElement(QQbar_I_generator, QQbar_I_nf.gen())) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 300165bfacb..d977e6a72fb 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -2585,7 +2585,7 @@ cdef class Rational(sage.structure.element.FieldElement): return c elif d == -1 and n.denominator() == 2: # Exact rational times a power of I - from sage.symbolic.all import I + from sage.rings.imaginary_unit import I return c * I ** (n.numerator() % 4) # Result is c * d^n but we cannot simplify d^n further: diff --git a/src/sage/rings/universal_cyclotomic_field.py b/src/sage/rings/universal_cyclotomic_field.py index d56d74f9366..ff4e50ffcb7 100644 --- a/src/sage/rings/universal_cyclotomic_field.py +++ b/src/sage/rings/universal_cyclotomic_field.py @@ -532,8 +532,7 @@ def _symbolic_(self, R): sage: SR(1+E(4)) I + 1 """ - from sage.symbolic.constants import pi - from sage.symbolic.all import i as I + from sage.symbolic.constants import pi, I k = ZZ(self._obj.Conductor()) coeffs = self._obj.CoeffsCyc(k).sage() s = R.zero() diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 96c9d3ae1b0..0ad31f7f9a5 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -345,7 +345,8 @@ from sage.plot.colors import rainbow from sage.arith.all import falling_factorial, lcm from sage.rings.all import Integer, PolynomialRing, QQ, ZZ -from sage.symbolic.all import I, pi, SR +from sage.symbolic.constants import I, pi +from sage.symbolic.ring import SR # TODO: remove the following line once 4ti2 functions are removed path_to_zsolve = os.path.join(SAGE_LOCAL, 'bin', 'zsolve') diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 6a53a384081..b9743c4ad69 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -274,7 +274,7 @@ class EllipticCurveFactory(UniqueFactory): sage: type(E) - sage: E = EllipticCurve([i,i]); E + sage: E = EllipticCurve([SR(i),i]); E Elliptic Curve defined by y^2 = x^3 + I*x + I over Symbolic Ring sage: type(E) diff --git a/src/sage/schemes/elliptic_curves/ell_rational_field.py b/src/sage/schemes/elliptic_curves/ell_rational_field.py index 6ae3121c4f5..3631a12f1de 100644 --- a/src/sage/schemes/elliptic_curves/ell_rational_field.py +++ b/src/sage/schemes/elliptic_curves/ell_rational_field.py @@ -83,6 +83,8 @@ IntegerRing, RealField, ComplexField, RationalField) +from sage.structure.coerce import py_scalar_to_element +from sage.structure.element import Element import sage.misc.all as misc from sage.misc.verbose import verbose as verbose_verbose @@ -5410,13 +5412,17 @@ def eval_modular_form(self, points, order): 0.0018604485340371083710285594393397945456, -0.0018743978548152085771342944989052703431] - sage: E.eval_modular_form(2.1+I, 100) # abs tol 1e-20 + sage: E.eval_modular_form(2.1+I, 100) # abs tol 1e-16 + [0.00150864362757267079 + 0.00109100341113449845*I] + + TESTS:: + + sage: E.eval_modular_form(CDF(2.1+I), 100) # abs tol 1e-16 [0.00150864362757267079 + 0.00109100341113449845*I] """ if not isinstance(points, list): - try: - points = list(points) - except TypeError: + points = py_scalar_to_element(points) + if isinstance(points, Element): return self.eval_modular_form([points], order) an = self.pari_mincurve().ellan(order) s = 0 diff --git a/src/sage/symbolic/all.py b/src/sage/symbolic/all.py index f7432b8f126..9bef7b1e806 100644 --- a/src/sage/symbolic/all.py +++ b/src/sage/symbolic/all.py @@ -1,7 +1,11 @@ from __future__ import absolute_import +from sage.misc.lazy_import import lazy_import -from sage.libs.pynac.pynac import I -i = I +import sage.libs.pynac.pynac # initialize pynac before .ring +lazy_import("sage.libs.pynac.pynac", "I", deprecation=(18036, + "import I from sage.symbolic.constants for the imaginary unit viewed as an element of SR, or from sage.rings.imaginary_unit for the element of ZZ[i]")) +lazy_import("sage.libs.pynac.pynac", "I", as_="i", deprecation=(18036, + "import I from sage.symbolic.constants for the imaginary unit viewed as an element of SR, or from sage.rings.imaginary_unit for the element of ZZ[i]")) from .ring import SR from .constants import (pi, e, NaN, golden_ratio, log2, euler_gamma, catalan, diff --git a/src/sage/symbolic/constants.py b/src/sage/symbolic/constants.py index 760be00c864..c48268de39f 100644 --- a/src/sage/symbolic/constants.py +++ b/src/sage/symbolic/constants.py @@ -611,20 +611,20 @@ def _sympy_(self): EXAMPLES:: - sage: I + sage: SR.I() I - sage: I^2 + sage: SR.I()^2 -1 Note that conversions to real fields will give TypeErrors:: - sage: float(I) + sage: float(SR.I()) Traceback (most recent call last): ... TypeError: unable to simplify to float approximation - sage: gp(I) + sage: gp(SR.I()) I - sage: RR(I) + sage: RR(SR.I()) Traceback (most recent call last): ... TypeError: unable to convert '1.00000000000000*I' to a real number @@ -640,42 +640,42 @@ def _sympy_(self): sage: C = ComplexField(200); C Complex Field with 200 bits of precision - sage: C(I) + sage: C(SR.I()) 1.0000000000000000000000000000000000000000000000000000000000*I - sage: I._complex_mpfr_field_(ComplexField(53)) + sage: SR.I()._complex_mpfr_field_(ComplexField(53)) 1.00000000000000*I - sage: I._complex_double_(CDF) + sage: SR.I()._complex_double_(CDF) 1.0*I - sage: CDF(I) + sage: CDF(SR.I()) 1.0*I - sage: z = I + I; z + sage: z = SR.I() + I; z 2*I sage: C(z) 2.0000000000000000000000000000000000000000000000000000000000*I - sage: 1e8*I + sage: 1e8*SR.I() 1.00000000000000e8*I - sage: complex(I) + sage: complex(SR.I()) 1j - sage: QQbar(I) + sage: QQbar(SR.I()) I - sage: abs(I) + sage: abs(SR.I()) 1 - sage: I.minpoly() + sage: SR.I().minpoly() x^2 + 1 - sage: maxima(2*I) + sage: maxima(2*SR.I()) 2*%i TESTS:: - sage: repr(I) + sage: repr(SR.I()) 'I' - sage: latex(I) + sage: latex(SR.I()) i """ diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 48bcf01e6a7..94acf6701f6 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -255,7 +255,7 @@ This example is from :trac:`10833`:: Check if :trac:`10849` is fixed:: - sage: t = I.pyobject().parent()(-1/2) + sage: t = I.parent()(-1/2) sage: t > 0 False sage: t = I*x-1/2; t @@ -950,11 +950,11 @@ cdef class Expression(CommutativeRingElement): Check that complex numbers are handled correctly (:trac:`28903`):: - sage: unicode_art(I) + sage: unicode_art(SR(I)) ⅈ - sage: unicode_art(13 - I) + sage: unicode_art(SR(13 - I)) 13 - ⅈ - sage: unicode_art(1.3 - I) + sage: unicode_art(SR(1.3 - I)) 1.3 - 1.0⋅ⅈ sage: unicode_art(cos(I)) cosh(1) @@ -1731,7 +1731,7 @@ cdef class Expression(CommutativeRingElement): True sage: AA(-golden_ratio) -1.618033988749895? - sage: QQbar((2*I)^(1/2)) + sage: QQbar(SR(2*I)^(1/2)) 1 + 1*I sage: QQbar(e^(pi*I/3)) 0.50000000000000000? + 0.866025403784439?*I @@ -2564,9 +2564,9 @@ cdef class Expression(CommutativeRingElement): Note that the complex I is not a constant:: - sage: I._is_registered_constant_() + sage: SR(I)._is_registered_constant_() False - sage: I.is_numeric() + sage: SR(I).is_numeric() True """ return is_a_constant(self._gobj) @@ -2588,7 +2588,7 @@ cdef class Expression(CommutativeRingElement): True sage: log(2).is_constant() True - sage: I.is_constant() + sage: SR(I).is_constant() True sage: x.is_constant() False @@ -4055,21 +4055,22 @@ cdef class Expression(CommutativeRingElement): Test complex numeric powers:: - sage: I^0.5 + sage: symI = SR(I) + sage: symI^0.5 0.707106781186548 + 0.707106781186547*I - sage: (I + 1) ^ (0.5 + I) + sage: (symI + 1) ^ (0.5 + symI) 0.400667052375828 + 0.365310866736929*I - sage: I^I + sage: symI^symI I^I - sage: I^x + sage: symI^x I^x - sage: I^(1/2) + sage: symI^(1/2) sqrt(I) - sage: I^(2/3) + sage: symI^(2/3) I^(2/3) sage: 2^(1/2) sqrt(2) - sage: (2*I)^(1/2) + sage: (2*symI)^(1/2) sqrt(2*I) Test if we can take powers of elements of `\QQ(i)` (:trac:`8659`):: @@ -8054,21 +8055,21 @@ cdef class Expression(CommutativeRingElement): Using the ``hold`` parameter it is possible to prevent automatic evaluation:: - sage: I.imag_part() + sage: SR(I).imag_part() 1 - sage: I.imag_part(hold=True) + sage: SR(I).imag_part(hold=True) imag_part(I) This also works using functional notation:: - sage: imag_part(I,hold=True) + sage: imag_part(I, hold=True) imag_part(I) - sage: imag_part(I) + sage: imag_part(SR(I)) 1 To then evaluate again, we use :meth:`unhold`:: - sage: a = I.imag_part(hold=True); a.unhold() + sage: a = SR(I).imag_part(hold=True); a.unhold() 1 TESTS:: @@ -9888,7 +9889,7 @@ cdef class Expression(CommutativeRingElement): sage: a = RR.random_element() sage: b = RR.random_element() - sage: f = a + b*I + sage: f = SR(a + b*I) sage: bool(f.rectform() == a + b*I) True diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index dd33ba2cf18..7690f79b51e 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -19,13 +19,13 @@ import operator as _operator from sage.rings.rational_field import QQ from sage.symbolic.ring import SR -from sage.libs.pynac.pynac import I -from sage.functions.log import exp +from sage.symbolic.constants import I +from sage.functions.all import exp from sage.symbolic.operators import arithmetic_operators, relation_operators, FDerivativeOperator, add_vararg, mul_vararg +from sage.rings.number_field.number_field import GaussianField from sage.rings.number_field.number_field_element_quadratic import NumberFieldElement_quadratic from sage.rings.universal_cyclotomic_field import UniversalCyclotomicField from functools import reduce -GaussianField = I.pyobject().parent() class FakeExpression(object): @@ -438,7 +438,7 @@ def pyobject(self, ex, obj): sage: from sage.symbolic.expression_conversions import InterfaceInit sage: ii = InterfaceInit(gp) - sage: f = 2+I + sage: f = 2+SR(I) sage: ii.pyobject(f, f.pyobject()) 'I + 2' @@ -450,7 +450,7 @@ def pyobject(self, ex, obj): """ if (self.interface.name() in ['pari','gp'] and isinstance(obj, NumberFieldElement_quadratic) and - obj.parent() == GaussianField): + obj.parent() is GaussianField()): return repr(obj) try: return getattr(obj, self.name_init)() @@ -1240,7 +1240,7 @@ def algebraic(ex, field): True sage: AA(-golden_ratio) -1.618033988749895? - sage: QQbar((2*I)^(1/2)) + sage: QQbar((2*SR(I))^(1/2)) 1 + 1*I sage: QQbar(e^(pi*I/3)) 0.50000000000000000? + 0.866025403784439?*I diff --git a/src/sage/symbolic/relation.py b/src/sage/symbolic/relation.py index 3aff1b09e29..88a2ed2490e 100644 --- a/src/sage/symbolic/relation.py +++ b/src/sage/symbolic/relation.py @@ -279,20 +279,20 @@ When working with the symbolic complex number `I`, notice that comparisons do not automatically simplify even in trivial situations:: - sage: I^2 == -1 + sage: SR(I)^2 == -1 -1 == -1 - sage: I^2 < 0 + sage: SR(I)^2 < 0 -1 < 0 - sage: (I+1)^4 > 0 + sage: (SR(I)+1)^4 > 0 -4 > 0 Nevertheless, if you force the comparison, you get the right answer (:trac:`7160`):: - sage: bool(I^2 == -1) + sage: bool(SR(I)^2 == -1) True - sage: bool(I^2 < 0) + sage: bool(SR(I)^2 < 0) True - sage: bool((I+1)^4 > 0) + sage: bool((SR(I)+1)^4 > 0) False More Examples diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index a7ae134ec48..238414f2b37 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -635,6 +635,20 @@ cdef class SymbolicRing(CommutativeRing): from sage.symbolic.constants import pi return self(pi) + def I(self): + r""" + The imaginary unit, viewed as an element of the symbolic ring. + + EXAMPLES:: + + sage: SR.I()^2 + -1 + sage: SR.I().parent() + Symbolic Ring + """ + from sage.symbolic.constants import I + return I + cpdef Expression symbol(self, name=None, latex_name=None, domain=None): """ EXAMPLES:: diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/domaines_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/domaines_doctest.py index d602c2ab7af..e08cf0fb5bb 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/domaines_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/domaines_doctest.py @@ -246,14 +246,14 @@ Sage example in ./domaines.tex, line 1036:: sage: I.parent() - Symbolic Ring + Number Field in I with defining polynomial x^2 + 1 with I = 1*I Sage example in ./domaines.tex, line 1043:: sage: (1.+2.*I).parent() - Symbolic Ring - sage: CC(1.+2.*I).parent() Complex Field with 53 bits of precision + sage: (1.+2.*SR(I)).parent() + Symbolic Ring Sage example in ./domaines.tex, line 1064:: @@ -340,7 +340,7 @@ Sage example in ./domaines.tex, line 1428:: sage: SR.category() - Category of commutative rings + Category of fields Sage example in ./domaines.tex, line 1482::