text: r"""
  Field of Arbitrary Precision Complex Intervals
  
  AUTHORS:
  
  - William Stein wrote complex_field.py.
  
  - William Stein (2006-01-26): complete rewrite
  
  Then ``complex_field.py`` was copied to ``complex_interval_field.py`` and
  heavily modified:
  
  - Carl Witty (2007-10-24): rewrite for intervals
  
  - Niles Johnson (2010-08): :Trac:`3893`: ``random_element()``
    should pass on ``*args`` and ``**kwds``.
  
  - Travis Scrimshaw (2012-10-18): Added documentation to get full coverage.
  
  .. NOTE::
  
      The :class:`ComplexIntervalField` differs from :class:`ComplexField` in
      that :class:`ComplexIntervalField` only gives the digits with exact
      precision, then a ``?`` signifying that the last digit can have an error of
      ``+/-1``.
  """
  
  # ****************************************************************************
  #       Copyright (C) 2006 William Stein <wstein@gmail.com>
  #
  # This program is free software: you can redistribute it and/or modify
  # it under the terms of the GNU General Public License as published by
  # the Free Software Foundation, either version 2 of the License, or
  # (at your option) any later version.
  #                  https://www.gnu.org/licenses/
  # ****************************************************************************
  
  
  from sage.structure.parent import Parent
  from .integer_ring import ZZ
  from .rational_field import QQ
  from .ring import Field
  import sage.rings.abc
  from . import integer
  from . import complex_interval
  import weakref
  from .real_mpfi import RealIntervalField, RealIntervalField_class
  from .complex_mpfr import ComplexField
  from sage.misc.cachefunc import cached_method
  
  
  def is_ComplexIntervalField(x):
      """
      Check if ``x`` is a :class:`ComplexIntervalField`.
  
      EXAMPLES::
  
          sage: from sage.rings.complex_interval_field import is_ComplexIntervalField as is_CIF
          sage: is_CIF(CIF)
          doctest:warning...
          DeprecationWarning: is_ComplexIntervalField is deprecated;
          use isinstance(..., sage.rings.abc.ComplexIntervalField) instead
          See https://trac.sagemath.org/32612 for details.
          True
          sage: is_CIF(CC)
          False
      """
      from sage.misc.superseded import deprecation
      deprecation(32612, 'is_ComplexIntervalField is deprecated; use isinstance(..., sage.rings.abc.ComplexIntervalField) instead')
      return isinstance(x, ComplexIntervalField_class)
  
  
  cache = {}
  def ComplexIntervalField(prec=53, names=None):
      """
      Return the complex interval field with real and imaginary parts having
      ``prec`` *bits* of precision.
  
      EXAMPLES::
  
          sage: ComplexIntervalField()
          Complex Interval Field with 53 bits of precision
          sage: ComplexIntervalField(100)
          Complex Interval Field with 100 bits of precision
          sage: ComplexIntervalField(100).base_ring()
          Real Interval Field with 100 bits of precision
          sage: i = ComplexIntervalField(200).gen()
          sage: i^2
          -1
          sage: i^i
          0.207879576350761908546955619834978770033877841631769608075136?
      """
      global cache
      if prec in cache:
          X = cache[prec]
          C = X()
          if C is not None:
              return C
      C = ComplexIntervalField_class(prec)
      cache[prec] = weakref.ref(C)
      return C
  
  
  class ComplexIntervalField_class(sage.rings.abc.ComplexIntervalField):
      """
      The field of complex (interval) numbers.
  
      EXAMPLES::
  
          sage: C = ComplexIntervalField(); C
          Complex Interval Field with 53 bits of precision
          sage: Q = RationalField()
          sage: C(1/3)
          0.3333333333333334?
          sage: C(1/3, 2)
          0.3333333333333334? + 2*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.3333333333333334?
          sage: S.<x> = PolynomialRing(Q)
          sage: C(x)
          Traceback (most recent call last):
          ...
          TypeError: cannot convert nonconstant polynomial
  
      This illustrates precision::
  
          sage: CIF = ComplexIntervalField(10); CIF(1/3, 2/3)
          0.334? + 0.667?*I
          sage: CIF
          Complex Interval Field with 10 bits of precision
          sage: CIF = ComplexIntervalField(100); CIF
          Complex Interval Field with 100 bits of precision
          sage: z = CIF(1/3, 2/3); z
          0.333333333333333333333333333334? + 0.666666666666666666666666666667?*I
  
      We can load and save complex numbers and the complex interval field::
  
          sage: saved_z = loads(z.dumps())
          sage: saved_z.endpoints() == z.endpoints()
          True
          sage: loads(CIF.dumps()) == CIF
          True
          sage: k = ComplexIntervalField(100)
          sage: loads(dumps(k)) == k
          True
  
      This illustrates basic properties of a complex (interval) field::
  
          sage: CIF = ComplexIntervalField(200)
          sage: CIF.is_field()
          True
          sage: CIF.characteristic()
          0
          sage: CIF.precision()
          200
          sage: CIF.variable_name()
          'I'
          sage: CIF == ComplexIntervalField(200)
          True
          sage: CIF == ComplexIntervalField(53)
          False
          sage: CIF == 1.1
          False
          sage: CIF = ComplexIntervalField(53)
  
          sage: CIF.category()
          Category of infinite fields
          sage: TestSuite(CIF).run(skip="_test_gcd_vs_xgcd")
  
      TESTS:
  
      This checks that :trac:`15355` is fixed::
  
          sage: x + CIF(RIF(-2,2), 0)
          x + 0.?e1
          sage: x + CIF(RIF(-2,2), RIF(-2,2))
          x + 0.?e1 + 0.?e1*I
          sage: x + RIF(-2,2)
          x + 0.?e1
          sage: x + CIF(RIF(3.14,3.15), RIF(3.14, 3.15))
          x + 3.15? + 3.15?*I
          sage: CIF(RIF(-2,2), RIF(-2,2))
          0.?e1 + 0.?e1*I
          sage: x + CIF(RIF(3.14,3.15), 0)
          x + 3.15?
  
      Methods inherited from categories::
  
          sage: CIF.is_finite()
          False
      """
      Element = complex_interval.ComplexIntervalFieldElement
  
      def __init__(self, prec=53):
          """
          Initialize ``self``.
  
          EXAMPLES::
  
              sage: ComplexIntervalField()
              Complex Interval Field with 53 bits of precision
              sage: ComplexIntervalField(200)
              Complex Interval Field with 200 bits of precision
          """
          self._prec = int(prec)
          from sage.categories.fields import Fields
          Field.__init__(self, self.real_field(), ("I",), False,
                  category=Fields().Infinite())
          self._populate_coercion_lists_(convert_method_name="_complex_mpfi_")
  
      def __reduce__(self):
          """
          Used for pickling.
  
          TESTS::
  
              sage: loads(dumps(CIF)) == CIF
              True
          """
          return ComplexIntervalField, (self._prec, )
  
      def construction(self):
          """
          Returns the functorial construction of this complex interval field,
          namely as the algebraic closure of the real interval field with
          the same precision.
  
          EXAMPLES::
  
              sage: c, S = CIF.construction(); c, S
              (AlgebraicClosureFunctor,
               Real Interval Field with 53 bits of precision)
              sage: CIF == c(S)
              True
  
          TESTS:
  
          Test that :trac:`19922` is fixed::
  
              sage: c = ComplexIntervalField(128).an_element()
              sage: r = RealIntervalField(64).an_element()
              sage: c + r
              1 + 1*I
              sage: r + c
              1 + 1*I
              sage: parent(c+r)
              Complex Interval Field with 64 bits of precision
              sage: R = ComplexIntervalField(128)['x']
              sage: (R.gen() * RIF.one()).parent()
              Univariate Polynomial Ring in x over Complex Interval Field with 53 bits of precision
          """
          from sage.categories.pushout import AlgebraicClosureFunctor
          return (AlgebraicClosureFunctor(), self.real_field())
  
      def is_exact(self):
          """
          The complex interval field is not exact.
  
          EXAMPLES::
  
              sage: CIF.is_exact()
              False
          """
          return False
  
      def prec(self):
          """
          Returns the precision of ``self`` (in bits).
  
          EXAMPLES::
  
              sage: CIF.prec()
              53
              sage: ComplexIntervalField(200).prec()
              200
          """
          return self._prec
  
      def to_prec(self, prec):
          """
          Returns a complex interval field with the given precision.
  
          EXAMPLES::
  
              sage: CIF.to_prec(150)
              Complex Interval Field with 150 bits of precision
              sage: CIF.to_prec(15)
              Complex Interval Field with 15 bits of precision
              sage: CIF.to_prec(53) is CIF
              True
          """
          return ComplexIntervalField(prec)
  
      def _magma_init_(self, magma):
          r"""
          Return a string representation of ``self`` in the Magma language.
  
          EXAMPLES::
  
              sage: magma(ComplexIntervalField(100)) # optional - magma # indirect doctest
              Complex field of precision 30
              sage: floor(RR(log(2**100, 10)))
              30
          """
          return "ComplexField(%s : Bits := true)" % self.prec()
  
      def _sage_input_(self, sib, coerce):
          r"""
          Produce an expression which will reproduce this value when evaluated.
  
          EXAMPLES::
  
              sage: sage_input(CIF, verify=True)
              # Verified
              CIF
              sage: sage_input(ComplexIntervalField(25), verify=True)
              # Verified
              ComplexIntervalField(25)
              sage: k = (CIF, ComplexIntervalField(37), ComplexIntervalField(1024))
              sage: sage_input(k, verify=True)
              # Verified
              (CIF, ComplexIntervalField(37), ComplexIntervalField(1024))
              sage: sage_input((k, k), verify=True)
              # Verified
              CIF37 = ComplexIntervalField(37)
              CIF1024 = ComplexIntervalField(1024)
              ((CIF, CIF37, CIF1024), (CIF, CIF37, CIF1024))
              sage: from sage.misc.sage_input import SageInputBuilder
              sage: ComplexIntervalField(2)._sage_input_(SageInputBuilder(), False)
              {call: {atomic:ComplexIntervalField}({atomic:2})}
          """
          if self.prec() == 53:
              return sib.name('CIF')
  
          v = sib.name('ComplexIntervalField')(sib.int(self.prec()))
          name = 'CIF%d' % self.prec()
          sib.cache(self, v, name)
          return v
  
      precision = prec
  
      @cached_method
      def real_field(self):
          """
          Return the underlying :class:`RealIntervalField`.
  
          EXAMPLES::
  
              sage: R = CIF.real_field(); R
              Real Interval Field with 53 bits of precision
              sage: ComplexIntervalField(200).real_field()
              Real Interval Field with 200 bits of precision
              sage: CIF.real_field() is R
              True
          """
          return RealIntervalField(self._prec)
  
      # For compatibility with with other complex number implementations
      # such as CC.
      _real_field = real_field
  
      @cached_method
      def middle_field(self):
          """
          Return the corresponding :class:`ComplexField` with the same precision
          as ``self``.
  
          EXAMPLES::
  
              sage: CIF.middle_field()
              Complex Field with 53 bits of precision
              sage: ComplexIntervalField(200).middle_field()
              Complex Field with 200 bits of precision
          """
          return ComplexField(self._prec)
  
      def __eq__(self, other):
          """
          Test whether ``self`` is equal to ``other``.
  
          If ``other`` is not a :class:`ComplexIntervalField_class`,
          return ``False``.  Otherwise, return ``True`` if ``self`` and
          ``other`` have the same precision.
  
          EXAMPLES::
  
              sage: CIF == ComplexIntervalField(200)
              False
              sage: CIF == CC
              False
              sage: CIF == CIF
              True
          """
          if not isinstance(other, ComplexIntervalField_class):
              return False
          return self._prec == other._prec
  
      def __hash__(self):
           """
           Return the hash.
  
           EXAMPLES::
  
               sage: C = ComplexIntervalField(200)
               sage: from sage.rings.complex_interval_field import ComplexIntervalField_class
               sage: D = ComplexIntervalField_class(200)
               sage: hash(C) == hash(D)
               True
           """
           return hash((self.__class__, self._prec))
  
      def __ne__(self, other):
          """
          Test whether ``self`` is not equal to ``other``.
  
          EXAMPLES::
  
              sage: CIF != ComplexIntervalField(200)
              True
              sage: CIF != CC
              True
              sage: CIF != CIF
              False
          """
          return not (self == other)
  
      def __call__(self, x=None, im=None, **kwds):
          """
          Construct an element.
  
          EXAMPLES::
  
              sage: CIF(2) # indirect doctest
              2
              sage: CIF(CIF.0)
              1*I
              sage: CIF('1+I')
              Traceback (most recent call last):
              ...
              TypeError: unable to convert '1+I' to real interval
              sage: CIF(2,3)
              2 + 3*I
              sage: CIF(pi, e)
              3.141592653589794? + 2.718281828459046?*I
              sage: ComplexIntervalField(100)(CIF(RIF(2,3)))
              3.?
  
              sage: QQi.<i> = QuadraticField(-1)
              sage: CIF(i)
              1*I
              sage: QQi.<i> = QuadraticField(-1, embedding=CC(0,-1))
              sage: CIF(i)
              -1*I
              sage: QQi.<i> = QuadraticField(-1, embedding=None)
              sage: CIF(i)
              1*I
  
          ::
  
              sage: R.<x> = CIF[]
              sage: a = R(CIF(0,1)); a
              I
              sage: CIF(a)
              1*I
          """
          # Note: we override Parent.__call__ because we want to support
          # CIF(a, b) and that is hard to do using coerce maps.
          if im is not None or kwds:
              return self.element_class(self, x, im, **kwds)
          return Parent.__call__(self, x)
  
      def _coerce_map_from_(self, S):
          """
          Canonical coercion from ``S`` to this complex interval field.
  
          The rings that canonically coerce to the MPFI complex field are:
  
          - this MPFI complex field, or any other of higher precision
  
          - anything that canonically coerces to the real interval field
            with this precision
  
          - some exact or lazy parents representing subsets of the complex
            numbers, such as ``QQbar`` and ``CLF``.
  
          EXAMPLES::
  
              sage: CIF((2,1)) + 2 + I # indirect doctest
              4 + 2*I
              sage: CIF((2,1)) + CC.pi()
              Traceback (most recent call last):
              ...
              TypeError: unsupported operand parent(s) for +: 'Complex Interval Field with 53 bits of precision' and 'Complex Field with 53 bits of precision'
  
              sage: CIF.coerce_map_from(QQ)
              Coercion map:
                From: Rational Field
                To:   Complex Interval Field with 53 bits of precision
              sage: CIF.coerce_map_from(int)
              Coercion map:
                From: Set of Python objects of class 'int'
                To:   Complex Interval Field with 53 bits of precision
              sage: CIF.coerce_map_from(GaussianIntegers())
              Conversion via _complex_mpfi_ method map:
                From: Gaussian Integers in Number Field in I with defining polynomial x^2 + 1 with I = 1*I
                To:   Complex Interval Field with 53 bits of precision
              sage: CIF.coerce_map_from(QQbar)
              Conversion via _complex_mpfi_ method map:
                From: Algebraic Field
                To:   Complex Interval Field with 53 bits of precision
              sage: CIF.coerce_map_from(AA)
              Conversion via _complex_mpfi_ method map:
                From: Algebraic Real Field
                To:   Complex Interval Field with 53 bits of precision
              sage: CIF.coerce_map_from(UniversalCyclotomicField())
              Conversion via _complex_mpfi_ method map:
                From: Universal Cyclotomic Field
                To:   Complex Interval Field with 53 bits of precision
  
          TESTS::
  
              sage: CIF.has_coerce_map_from(RR)
              False
              sage: CIF.has_coerce_map_from(RDF)
              False
              sage: CIF.has_coerce_map_from(float)
              False
          """
          # Direct and efficient conversions
          if S is ZZ or S is QQ or S is int:
              return True
          if isinstance(S, (ComplexIntervalField_class,
                            RealIntervalField_class)):
              return S.precision() >= self._prec
  
          # If coercion to CC is possible and there is a _complex_mpfi_
          # method, assume that it defines a coercion to CIF
          if self.middle_field().has_coerce_map_from(S):
              f = self._convert_method_map(S)
              if f is not None:
                  return f
  
          return self._coerce_map_via( (self.real_field(),), S)
  
      def _repr_(self):
          """
          Return a string representation of ``self``.
  
          EXAMPLES::
  
              sage: ComplexIntervalField() # indirect doctest
              Complex Interval Field with 53 bits of precision
              sage: ComplexIntervalField(100) # indirect doctest
              Complex Interval Field with 100 bits of precision
          """
          return "Complex Interval Field with %s bits of precision"%self._prec
  
      def _latex_(self):
          r"""
          Return a latex representation of ``self``.
  
          EXAMPLES::
  
              sage: latex(ComplexIntervalField()) # indirect doctest
              \Bold{C}
          """
          return "\\Bold{C}"
  
      def characteristic(self):
          """
          Return the characteristic of the complex (interval) field, which is 0.
  
          EXAMPLES::
  
              sage: CIF.characteristic()
              0
          """
          return integer.Integer(0)
  
      def gen(self, n=0):
          """
          Return the generator of the complex (interval) field.
  
          EXAMPLES::
  
              sage: CIF.0
              1*I
              sage: CIF.gen(0)
              1*I
          """
          if n != 0:
              raise IndexError("n must be 0")
          return self.element_class(self, 0, 1)
  
      def random_element(self, *args, **kwds):
          """
          Create a random element of ``self``.
  
          This simply chooses the real and imaginary part randomly, passing
          arguments and keywords to the underlying real interval field.
  
          EXAMPLES::
  
              sage: CIF.random_element().parent() is CIF
              True
              sage: re, im = CIF.random_element(10, 20)
              sage: 10 <= re <= 20
              True
              sage: 10 <= im <= 20
              True
  
          Passes extra positional or keyword arguments through::
  
              sage: re, im = CIF.random_element(max=0, min=-5)
              sage: -5 <= re <= 0
              True
              sage: -5 <= im <= 0
              True
          """
          rand = self.real_field().random_element
          re = rand(*args, **kwds)
          im = rand(*args, **kwds)
          return self.element_class(self, re, im)
  
      def is_field(self, proof = True):
          """
          Return ``True``, since the complex numbers are a field.
  
          EXAMPLES::
  
              sage: CIF.is_field()
              True
          """
          return True
  
      def pi(self):
          r"""
          Returns `\pi` as an element in the complex (interval) field.
  
          EXAMPLES::
  
              sage: ComplexIntervalField(100).pi()
              3.14159265358979323846264338328?
          """
          return self.element_class(self, self.real_field().pi())
  
      def ngens(self):
          r"""
          The number of generators of this complex (interval) field as an
          `\RR`-algebra.
  
          There is one generator, namely ``sqrt(-1)``.
  
          EXAMPLES::
  
              sage: CIF.ngens()
              1
          """
          return 1
  
      def zeta(self, n=2):
          r"""
          Return a primitive `n`-th root of unity.
  
          .. TODO::
  
              Implement :class:`ComplexIntervalFieldElement` multiplicative order
              and set this output to have multiplicative order ``n``.
  
          INPUT:
  
          - ``n`` -- an integer (default: 2)
  
          OUTPUT:
  
          A complex `n`-th root of unity.
  
          EXAMPLES::
  
              sage: CIF.zeta(2)
              -1
              sage: CIF.zeta(5)
              0.309016994374948? + 0.9510565162951536?*I
          """
          from .integer import Integer
          n = Integer(n)
          if n == 1:
              x = self.element_class(self, 1)
          elif n == 2:
              x = self.element_class(self, -1)
          elif n >= 3:
              # Use De Moivre
              # e^(2*pi*i/n) = cos(2pi/n) + i *sin(2pi/n)
              RIF = self.real_field()
              pi = RIF.pi()
              z = 2*pi/n
              x = self.element_class(self, z.cos(), z.sin())
          # Uncomment after implemented
          #x._set_multiplicative_order( n )
          return x
  
      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: CIF((0.025, 2))
              0.025000000000000002? + 2*I
              sage: CIF.scientific_notation(True)
              sage: CIF((0.025, 2))
              2.5000000000000002?e-2 + 2*I
              sage: CIF.scientific_notation(False)
              sage: CIF((0.025, 2))
              0.025000000000000002? + 2*I
          """
          return self.real_field().scientific_notation(status)
  
  
  