Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Field of Arbitrary Precision Complex Numbers
AUTHORS:
- William Stein (2006-01-26): complete rewrite
- Niles Johnson (2010-08): :trac:`3893`: ``random_element()`` should pass on ``*args`` and ``**kwds``.
- Travis Scrimshaw (2012-10-18): Added documentation for full coverage. """
################################################################################# # Copyright (C) 2006 William Stein <wstein@gmail.com> # # Distributed under the terms of the GNU General Public License (GPL) # # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import
from .complex_number import ComplexNumber, RRtoCC from .complex_double import ComplexDoubleElement from . import ring from .real_mpfr import RealNumber import weakref from sage.misc.sage_eval import sage_eval
from sage.structure.parent import Parent from sage.structure.parent_gens import ParentWithGens
NumberField_quadratic = None NumberFieldElement_quadratic = None AlgebraicNumber_base = None AlgebraicNumber = None AlgebraicReal = None AA = None QQbar = None SR = None CDF = CLF = RLF = None
def late_import(): """ Import the objects/modules after build (when needed).
TESTS::
sage: sage.rings.complex_field.late_import() """ global NumberField_quadratic global NumberFieldElement_quadratic global AlgebraicNumber_base global AlgebraicNumber global AlgebraicReal global AA, QQbar, SR global CLF, RLF, CDF import sage.rings.number_field.number_field import sage.rings.number_field.number_field_element_quadratic as nfeq NumberField_quadratic = sage.rings.number_field.number_field.NumberField_quadratic NumberFieldElement_quadratic = nfeq.NumberFieldElement_quadratic import sage.rings.qqbar AlgebraicNumber_base = sage.rings.qqbar.AlgebraicNumber_base AlgebraicNumber = sage.rings.qqbar.AlgebraicNumber AlgebraicReal = sage.rings.qqbar.AlgebraicReal AA = sage.rings.qqbar.AA QQbar = sage.rings.qqbar.QQbar import sage.symbolic.ring SR = sage.symbolic.ring.SR from .real_lazy import CLF, RLF from .complex_double import CDF
def is_ComplexField(x): """ Check if ``x`` is a :class:`complex field <ComplexField_class>`.
EXAMPLES::
sage: from sage.rings.complex_field import is_ComplexField as is_CF sage: is_CF(ComplexField()) True sage: is_CF(ComplexField(12)) True sage: is_CF(CC) True """
cache = {} def ComplexField(prec=53, names=None): """ Return the complex field with real and imaginary parts having prec *bits* of precision.
EXAMPLES::
sage: ComplexField() Complex Field with 53 bits of precision sage: ComplexField(100) Complex Field with 100 bits of precision sage: ComplexField(100).base_ring() Real Field with 100 bits of precision sage: i = ComplexField(200).gen() sage: i^2 -1.0000000000000000000000000000000000000000000000000000000000 """ global cache
class ComplexField_class(ring.Field): """ An approximation to the field of complex numbers using floating point numbers with any specified precision. Answers derived from calculations in this approximation may differ from what they would be if those calculations were performed in the true field of complex numbers. This is due to the rounding errors inherent to finite precision calculations.
EXAMPLES::
sage: C = ComplexField(); C Complex Field with 53 bits of precision sage: Q = RationalField() sage: C(1/3) 0.333333333333333 sage: C(1/3, 2) 0.333333333333333 + 2.00000000000000*I sage: C(RR.pi()) 3.14159265358979 sage: C(RR.log2(), RR.pi()) 0.693147180559945 + 3.14159265358979*I
We can also coerce rational numbers and integers into C, but coercing a polynomial will raise an exception::
sage: Q = RationalField() sage: C(1/3) 0.333333333333333 sage: S = PolynomialRing(Q, 'x') sage: C(S.gen()) Traceback (most recent call last): ... TypeError: unable to coerce to a ComplexNumber: <type 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint'>
This illustrates precision::
sage: CC = ComplexField(10); CC(1/3, 2/3) 0.33 + 0.67*I sage: CC Complex Field with 10 bits of precision sage: CC = ComplexField(100); CC Complex Field with 100 bits of precision sage: z = CC(1/3, 2/3); z 0.33333333333333333333333333333 + 0.66666666666666666666666666667*I
We can load and save complex numbers and the complex field::
sage: loads(z.dumps()) == z True sage: loads(CC.dumps()) == CC True sage: k = ComplexField(100) sage: loads(dumps(k)) == k True
This illustrates basic properties of a complex field::
sage: CC = ComplexField(200) sage: CC.is_field() True sage: CC.characteristic() 0 sage: CC.precision() 200 sage: CC.variable_name() 'I' sage: CC == ComplexField(200) True sage: CC == ComplexField(53) False sage: CC == 1.1 False """ def __init__(self, prec=53): """ Initialize ``self``.
TESTS::
sage: C = ComplexField(200) sage: C.category() Join of Category of fields and Category of complete metric spaces sage: TestSuite(C).run() """ # self._populate_coercion_lists_()
def __reduce__(self): """ For pickling.
EXAMPLES::
sage: loads(dumps(ComplexField())) == ComplexField() True """
def is_exact(self): """ Return whether or not this field is exact, which is always ``False``.
EXAMPLES::
sage: ComplexField().is_exact() False """
def prec(self): """ Return the precision of this complex field.
EXAMPLES::
sage: ComplexField().prec() 53 sage: ComplexField(15).prec() 15 """
def _magma_init_(self, magma): r""" Return a string representation of ``self`` in the Magma language.
EXAMPLES::
sage: ComplexField()._magma_init_(magma) # optional - magma 'ComplexField(53 : Bits := true)' sage: magma(ComplexField(200)) # optional - magma Complex field of precision 60 sage: 10^60 < 2^200 < 10^61 True sage: s = magma(ComplexField(200)).sage(); s # optional - magma Complex Field with 200 bits of precision sage: 2^199 < 10^60 < 2^200 True sage: s is ComplexField(200) # optional - magma True """ return "ComplexField(%s : Bits := true)" % self.prec()
precision = prec
def to_prec(self, prec): """ Returns the complex field to the specified precision.
EXAMPLES::
sage: CC.to_prec(10) Complex Field with 10 bits of precision sage: CC.to_prec(100) Complex Field with 100 bits of precision """
# very useful to cache this. def _real_field(self): """ Return the underlying real field with the same precision.
EXAMPLES::
sage: RF = ComplexField(10)._real_field(); RF Real Field with 10 bits of precision sage: ComplexField(10)._real_field() is RF True """
def __eq__(self, other): """ Check whether ``self`` is not equal to ``other``.
If ``other`` is not a :class:`ComplexField_class`, then this return ``False``. Otherwise it compares their precision.
EXAMPLES::
sage: ComplexField() == ComplexField() True sage: ComplexField(10) == ComplexField(15) False """
def __hash__(self): """ Return the hash.
EXAMPLES::
sage: C = ComplexField(200) sage: from sage.rings.complex_field import ComplexField_class sage: D = ComplexField_class(200) sage: hash(C) == hash(D) True """
def __ne__(self, other): """ Check whether ``self`` is not equal to ``other``.
EXAMPLES::
sage: ComplexField() != ComplexField() False sage: ComplexField(10) != ComplexField(15) True """
def __call__(self, x=None, im=None): """ Create a complex number.
EXAMPLES::
sage: CC(2) # indirect doctest 2.00000000000000 sage: CC(CC.0) 1.00000000000000*I sage: CC('1+I') 1.00000000000000 + 1.00000000000000*I sage: CC(2,3) 2.00000000000000 + 3.00000000000000*I sage: CC(QQ[I].gen()) 1.00000000000000*I sage: CC.gen() + QQ[I].gen() 2.00000000000000*I sage: CC.gen() + QQ.extension(x^2 + 1, 'I', embedding=None).gen() Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: 'Complex Field with 53 bits of precision' and 'Number Field in I with defining polynomial x^2 + 1'
In the absence of arguments we return zero::
sage: a = CC(); a 0.000000000000000 sage: a.parent() Complex Field with 53 bits of precision """ # we leave this here to handle the imaginary parameter
def _element_constructor_(self, x): """ Construct a complex number.
EXAMPLES::
sage: CC((1,2)) # indirect doctest 1.00000000000000 + 2.00000000000000*I
Check that :trac:`14989` is fixed::
sage: QQi = NumberField(x^2+1, 'i', embedding=CC(0,1)) sage: i = QQi.order(QQi.gen()).gen(1) sage: CC(i) 1.00000000000000*I
""" # TODO: this is probably not the best and most # efficient way to do this. -- Martin Albrecht sage_eval(x.replace(' ',''), locals={"I":self.gen(),"i":self.gen()}))
def _coerce_map_from_(self, S): """ The rings that canonically coerce to the MPFR complex field are:
- This MPFR complex field, or any other of higher precision
- Anything that canonically coerces to the mpfr real field with this prec
EXAMPLES::
sage: ComplexField(200)(1) + RealField(90)(1) # indirect doctest 2.0000000000000000000000000 sage: parent(ComplexField(200)(1) + RealField(90)(1)) # indirect doctest Complex Field with 90 bits of precision sage: CC.0 + RLF(1/3) # indirect doctest 0.333333333333333 + 1.00000000000000*I sage: ComplexField(20).has_coerce_map_from(CDF) True sage: ComplexField(200).has_coerce_map_from(CDF) False sage: ComplexField(53).has_coerce_map_from(complex) True sage: ComplexField(200).has_coerce_map_from(complex) False """ else: else: else:
def _repr_(self): """ Return a string representation of ``self``.
EXAMPLES::
sage: ComplexField() # indirect doctest Complex Field with 53 bits of precision sage: ComplexField(15) # indirect doctest Complex Field with 15 bits of precision """
def _latex_(self): r""" Return a latex representation of ``self``.
EXAMPLES::
sage: latex(ComplexField()) # indirect doctest \Bold{C} sage: latex(ComplexField(15)) # indirect doctest \Bold{C} """
def _sage_input_(self, sib, coerce): r""" Produce an expression which will reproduce this value when evaluated.
EXAMPLES::
sage: sage_input(CC, verify=True) # Verified CC sage: sage_input(ComplexField(25), verify=True) # Verified ComplexField(25) sage: k = (CC, ComplexField(75)) sage: sage_input(k, verify=True) # Verified (CC, ComplexField(75)) sage: sage_input((k, k), verify=True) # Verified CC75 = ComplexField(75) ((CC, CC75), (CC, CC75)) sage: from sage.misc.sage_input import SageInputBuilder sage: ComplexField(99)._sage_input_(SageInputBuilder(), False) {call: {atomic:ComplexField}({atomic:99})} """
def characteristic(self): r""" Return the characteristic of `\CC`, which is 0.
EXAMPLES::
sage: ComplexField().characteristic() 0 """
def gen(self, n=0): """ Return the generator of the complex field.
EXAMPLES::
sage: ComplexField().gen(0) 1.00000000000000*I """ raise IndexError("n must be 0")
def is_field(self, proof = True): """ Return ``True`` since the complex numbers are a field.
EXAMPLES::
sage: CC.is_field() True """
def is_finite(self): """ Return ``False`` since there are infinite number of complex numbers.
EXAMPLES::
sage: CC.is_finite() False """
def construction(self): """ Returns the functorial construction of ``self``, namely the algebraic closure of the real field with the same precision.
EXAMPLES::
sage: c, S = CC.construction(); S Real Field with 53 bits of precision sage: CC == c(S) True """
def random_element(self, component_max=1, *args, **kwds): r""" Returns a uniformly distributed random number inside a square centered on the origin (by default, the square `[-1,1] \times [-1,1]`).
Passes additional arguments and keywords to underlying real field.
EXAMPLES::
sage: [CC.random_element() for _ in range(5)] [0.153636193785613 - 0.502987375247518*I, 0.609589964322241 - 0.948854594338216*I, 0.968393085385764 - 0.148483595843485*I, -0.908976099636549 + 0.126219184235123*I, 0.461226845462901 - 0.0420335212948924*I] sage: CC6 = ComplexField(6) sage: [CC6.random_element(2^-20) for _ in range(5)] [-5.4e-7 - 3.3e-7*I, 2.1e-7 + 8.0e-7*I, -4.8e-7 - 8.6e-7*I, -6.0e-8 + 2.7e-7*I, 6.0e-8 + 1.8e-7*I] sage: [CC6.random_element(pi^20) for _ in range(5)] [6.7e8 - 5.4e8*I, -9.4e8 + 5.0e9*I, 1.2e9 - 2.7e8*I, -2.3e9 - 4.0e9*I, 7.7e9 + 1.2e9*I]
Passes extra positional or keyword arguments through::
sage: [CC.random_element(distribution='1/n') for _ in range(5)] [-0.900931453455899 - 0.932172283929307*I, 0.327862582226912 + 0.828104487111727*I, 0.246299162813240 + 0.588214960163442*I, 0.892970599589521 - 0.266744694790704*I, 0.878458776600692 - 0.905641181799996*I] """
def pi(self): r""" Returns `\pi` as a complex number.
EXAMPLES::
sage: ComplexField().pi() 3.14159265358979 sage: ComplexField(100).pi() 3.1415926535897932384626433833 """
def ngens(self): r""" The number of generators of this complex field as an `\RR`-algebra.
There is one generator, namely ``sqrt(-1)``.
EXAMPLES::
sage: ComplexField().ngens() 1 """
def zeta(self, n=2): """ Return a primitive `n`-th root of unity.
INPUT:
- ``n`` - an integer (default: 2)
OUTPUT: a complex `n`-th root of unity.
EXAMPLES::
sage: C = ComplexField() sage: C.zeta(2) -1.00000000000000 sage: C.zeta(5) 0.309016994374947 + 0.951056516295154*I """ # Use De Moivre # e^(2*pi*i/n) = cos(2pi/n) + i *sin(2pi/n)
def scientific_notation(self, status=None): """ Set or return the scientific notation printing flag.
If this flag is ``True`` then complex numbers with this space as parent print using scientific notation.
EXAMPLES::
sage: C = ComplexField() sage: C((0.025, 2)) 0.0250000000000000 + 2.00000000000000*I sage: C.scientific_notation(True) sage: C((0.025, 2)) 2.50000000000000e-2 + 2.00000000000000e0*I sage: C.scientific_notation(False) sage: C((0.025, 2)) 0.0250000000000000 + 2.00000000000000*I """
def algebraic_closure(self): """ Return the algebraic closure of ``self`` (which is itself).
EXAMPLES::
sage: CC Complex Field with 53 bits of precision sage: CC.algebraic_closure() Complex Field with 53 bits of precision sage: CC = ComplexField(1000) sage: CC.algebraic_closure() is CC True """
def _factor_univariate_polynomial(self, f): """ Factor the univariate polynomial ``f``.
INPUT:
- ``f`` -- a univariate polynomial defined over the complex numbers
OUTPUT:
- A factorization of ``f`` over the complex numbers into a unit and monic irreducible factors
.. NOTE::
This is a helper method for :meth:`sage.rings.polynomial.polynomial_element.Polynomial.factor`.
This method calls PARI to compute the factorization.
TESTS::
sage: k = ComplexField(100) sage: R.<x> = k[] sage: k._factor_univariate_polynomial( x ) x sage: k._factor_univariate_polynomial( 2*x ) (2.0000000000000000000000000000) * x sage: k._factor_univariate_polynomial( x^2 ) x^2 sage: k._factor_univariate_polynomial( x^2 + 3 ) (x - 1.7320508075688772935274463415*I) * (x + 1.7320508075688772935274463415*I) sage: k._factor_univariate_polynomial( x^2 + 1 ) (x - I) * (x + I) sage: k._factor_univariate_polynomial( k(I) * (x^2 + 1) ) (1.0000000000000000000000000000*I) * (x - I) * (x + I)
"""
# if the polynomial does not have complex coefficients, PARI will # factor it over the reals. To make sure it has complex coefficients we # multiply with I.
|