Changeset 7427:3fef61943bd8


Ignore:
Timestamp:
11/25/07 14:04:38 (5 years ago)
Author:
Carl Witty <cwitty@…>
Branch:
default
Message:

Change algebraic_real to implement QQbar as well.

Location:
sage
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • sage/calculus/calculus.py

    r7391 r7427  
    28312831        return ring(self) 
    28322832     
     2833    def _algebraic_(self, field): 
     2834        """ 
     2835        EXAMPLES: 
     2836            sage: a = SR(5/6) 
     2837            sage: AA(a) 
     2838            5/6 
     2839            sage: type(AA(a)) 
     2840            <class 'sage.rings.algebraic_real.AlgebraicReal'> 
     2841            sage: QQbar(a) 
     2842            5/6 
     2843            sage: type(QQbar(a)) 
     2844            <class 'sage.rings.algebraic_real.AlgebraicNumber'> 
     2845            sage: from sage.calculus.calculus import SymbolicConstant 
     2846            sage: i = SymbolicConstant(I) 
     2847            sage: AA(i) 
     2848            Traceback (most recent call last): 
     2849            ...     
     2850            TypeError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real 
     2851            sage: QQbar(i) 
     2852            1*I 
     2853            sage: phi = SymbolicConstant(golden_ratio) 
     2854            sage: AA(phi) 
     2855            [1.6180339887498946 .. 1.6180339887498950] 
     2856            sage: QQbar(phi) 
     2857            [1.6180339887498946 .. 1.6180339887498950] 
     2858        """ 
     2859 
     2860        # Out of the many kinds of things that can be in a SymbolicConstant, 
     2861        # we accept only rational numbers (or things that can be coerced 
     2862        # to rational) and a few instances of Constant. 
     2863 
     2864        if isinstance(self._obj, sage.functions.constants.Constant) \ 
     2865               and hasattr(self._obj, '_algebraic_'): 
     2866            return self._obj._algebraic_(field) 
     2867        return field(Rational(self._obj)) 
    28332868 
    28342869 
     
    30733108        rops = [op._real_rqdf_(field) for op in self._operands] 
    30743109        return self._operator(*rops) 
     3110 
     3111    def _algebraic_(self, field): 
     3112        """ 
     3113        Convert a symbolic expression to an algebraic number. 
     3114 
     3115        EXAMPLES: 
     3116            sage: QQbar(sqrt(2) + sqrt(8)) 
     3117            [4.2426406871192847 .. 4.2426406871192857] 
     3118            sage: AA(sqrt(2) ^ 4) == 4 
     3119            True 
     3120            sage: AA(-golden_ratio) 
     3121            [-1.6180339887498950 .. -1.6180339887498946] 
     3122            sage: QQbar((2*I)^(1/2)) 
     3123            [1.0000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 1.0000000000000000]*I 
     3124        """ 
     3125 
     3126        # We try to avoid simplifying, because maxima's simplify command 
     3127        # can change the value of a radical expression (by changing which 
     3128        # root is selected). 
     3129        try: 
     3130            if self._operator is operator.pow: 
     3131                base = field(self._operands[0]) 
     3132                expt = Rational(self._operands[1]) 
     3133                return field(field(base) ** expt) 
     3134            else: 
     3135                rops = [field(op) for op in self._operands] 
     3136                return self._operator(*rops) 
     3137        except TypeError: 
     3138            if self.is_simplified(): 
     3139                raise 
     3140            else: 
     3141                return self.simplify()._algebraic_(field) 
    30753142 
    30763143    def _is_atomic(self): 
     
    40114078        else: 
    40124079            return z 
     4080 
     4081    def _algebraic_(self, field): 
     4082        """ 
     4083        Coerce to an algebraic number. 
     4084 
     4085        EXAMPLES: 
     4086            sage: QQbar(sqrt(2)) 
     4087            [1.4142135623730949 .. 1.4142135623730952] 
     4088            sage: AA(abs(1+I)) 
     4089            [1.4142135623730949 .. 1.4142135623730952] 
     4090        """ 
     4091        # We try to avoid simplifying, because maxima's simplify command 
     4092        # can change the value of a radical expression (by changing which 
     4093        # root is selected). 
     4094        f = self._operands[0] 
     4095        g = self._operands[1] 
     4096        try: 
     4097            return field(f(g._algebraic_(field))) 
     4098        except TypeError: 
     4099            if self.is_simplified(): 
     4100                raise 
     4101            else: 
     4102                return self.simplify()._algebraic_(field) 
     4103         
    40134104 
    40144105class PrimitiveFunction(SymbolicExpression): 
  • sage/functions/constants.py

    r7348 r7427  
    538538        raise TypeError         
    539539 
     540    def _algebraic_(self, field): 
     541        import sage.rings.algebraic_real 
     542        return field(sage.rings.algebraic_real.QQbar_I) 
     543 
    540544    def __abs__(self): 
    541545        return Integer(1) 
     
    692696    def _mpfr_(self,R):  #is this OK for _mpfr_ ? 
    693697        return (R(1)+R(5).sqrt())*R(0.5) 
     698 
     699    def _algebraic_(self, field): 
     700        import sage.rings.algebraic_real 
     701        return field(sage.rings.algebraic_real.get_AA_golden_ratio()) 
    694702 
    695703golden_ratio = GoldenRatio() 
  • sage/rings/algebraic_real.py

    r7156 r7427  
    11""" 
    2 Field of Algebraic Reals 
     2Field of Algebraic Numbers 
    33 
    44AUTHOR: 
    55    -- Carl Witty (2007-01-27): initial version 
    6  
    7 This is an implementation of the algebraic reals (the real numbers which 
    8 are the zero of a polynomial in ZZ[x]).  All computations are exact. 
    9  
    10 As with many other implementations of the algebraic numbers, we avoid 
    11 computing a number field and working in the number field whenever possible. 
     6    -- Carl Witty (2007-10-29): massive rewrite to support complex 
     7         as well as real numbers 
     8 
     9This is an implementation of the algebraic numbers (the complex 
     10numbers which are the zero of a polynomial in ZZ[x]; in other words, 
     11the algebraic closure of QQ, with an embedding into CC).  All 
     12computations are exact.  We also include an implementation of the 
     13algebraic reals (the intersection of the algebraic numbers with RR). 
     14The field of algebraic numbers is available with abbreviation QQbar; 
     15the field of algebraic reals has abbreviation AA. 
     16 
     17As with many other implementations of the algebraic numbers, we try 
     18hard to avoid computing a number field and working in the number 
     19field; instead, we use floating-point interval arithmetic whenever 
     20possible (basically whenever we need to prove disequalities), and 
     21resort to symbolic computation only as needed (basically to prove 
     22equalities). 
    1223 
    1324Algebraic numbers exist in one of the following forms: 
    1425 
    1526* a rational number 
     27* the product of a rational number and an n'th root of unity 
    1628* the sum, difference, product, or quotient of algebraic numbers 
     29* the negation, inverse, absolute value, norm, real part,  
     30imaginary part, or complex conjugate of an algebraic number 
    1731* a particular root of a polynomial, given as a polynomial with 
    1832algebraic coefficients, an isolating interval (given as a  
     
    2337coefficients and the polynomial is given as a NumberFieldElement 
    2438 
    25 An algebraic number can be coerced into RealIntervalField; every algebraic  
    26 number has a cached interval of the highest precision yet calculated. 
     39The multiplicative subgroup of the algebraic numbers generated 
     40by the rational numbers and the roots of unity is handled particularly 
     41efficiently, as long as these roots of unity come from the QQbar.zeta() 
     42method.  Cyclotomic fields in general are fairly efficient, again 
     43as long as they are derived from QQbar.zeta(). 
     44 
     45An algebraic number can be coerced into ComplexIntervalField (or 
     46RealIntervalField, for algebraic reals); every algebraic number has a 
     47cached interval of the highest precision yet calculated. 
    2748 
    2849Everything is done with intervals except for comparisons.  By default, 
     
    4566    sage: sqrt(AA(2)) > 0 
    4667    True 
    47     sage: (sqrt(5 + 2*sqrt(AA(6))) - sqrt(AA(3)))**2 == 2 
     68    sage: (sqrt(5 + 2*sqrt(QQbar(6))) - sqrt(QQbar(3)))^2 == 2 
     69    True 
     70    sage: AA((sqrt(5 + 2*sqrt(6)) - sqrt(3))^2) == 2 
    4871    True 
    4972 
     
    83106    True 
    84107 
     108We can coerce from symbolic expressions: 
     109 
     110    sage: QQbar(sqrt(-5)) 
     111    [2.2360679774997893 .. 2.2360679774997899]*I 
     112    sage: AA(sqrt(2) + sqrt(3)) 
     113    [3.1462643699419721 .. 3.1462643699419726] 
     114    sage: AA(sqrt(2)) + sqrt(3) 
     115    [3.1462643699419721 .. 3.1462643699419726] 
     116    sage: sqrt(2) + QQbar(sqrt(3)) 
     117    [3.1462643699419721 .. 3.1462643699419726] 
     118    sage: QQbar(I) 
     119    1*I 
     120    sage: AA(I) 
     121    Traceback (most recent call last): 
     122    ... 
     123    TypeError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real 
     124    sage: QQbar(I * golden_ratio) 
     125    [1.6180339887498946 .. 1.6180339887498950]*I 
     126    sage: AA(golden_ratio)^2 - AA(golden_ratio) 
     127    1 
     128    sage: QQbar((-8)^(1/3)) 
     129    [0.99999999999999988 .. 1.0000000000000003] + [1.7320508075688771 .. 1.7320508075688775]*I 
     130    sage: AA((-8)^(1/3)) 
     131    -2 
     132    sage: QQbar((-4)^(1/4)) 
     133    [1.0000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 1.0000000000000000]*I 
     134    sage: AA((-4)^(1/4)) 
     135    Traceback (most recent call last): 
     136    ... 
     137    TypeError: Cannot coerce algebraic number with non-zero imaginary part to algebraic real 
     138 
     139We can explicitly coerce from QQ[I].  (Technically, this is not quite 
     140kosher, since QQ[I] doesn't come with an embedding; we don't know 
     141whether the field generator is supposed to map to +I or -I.  We assume 
     142that for any quadratic field with polynomial x^2+1, the generator maps 
     143to +I.) 
     144 
     145    sage: K.<im> = QQ[I] 
     146    sage: pythag = QQbar(3/5 + 4*im/5); pythag 
     147    4/5*I + 3/5 
     148    sage: pythag.abs() == 1 
     149    True 
     150 
     151However, implicit coercion from QQ[I] is not allowed. 
     152 
     153    sage: QQbar(1) + im 
     154    Traceback (most recent call last): 
     155    ... 
     156    TypeError: unsupported operand parent(s) for '+': 'Algebraic Field' and 'Number Field in I with defining polynomial x^2 + 1' 
     157 
     158We can implicitly coerce from algebraic reals to algebraic numbers: 
     159 
     160    sage: a = QQbar(1); print a, a.parent() 
     161    1 Algebraic Field 
     162    sage: b = AA(1); print b, b.parent() 
     163    1 Algebraic Real Field 
     164    sage: c = a + b; print c, c.parent() 
     165    2 Algebraic Field 
     166 
    85167Some computation with radicals: 
    86168 
     
    102184    True 
    103185 
    104 Algebraic reals which are known to be rational print as rationals; otherwise 
    105 they print as intervals (with 53-bit precision). 
     186Algebraic numbers which are known to be rational print as rationals; 
     187otherwise they print as intervals (with 53-bit precision). 
    106188 
    107189    sage: AA(2)/3 
    108190    2/3 
    109     sage: AA(5/7) 
     191    sage: QQbar(5/7) 
    110192    5/7 
    111     sage: two = sqrt(AA(4)); two 
     193    sage: QQbar(1/3 - 1/4*I) 
     194    -1/4*I + 1/3 
     195    sage: two = QQbar(4).nth_root(4)^2; two 
    112196    [1.9999999999999997 .. 2.0000000000000005] 
    113197    sage: two == 2; two 
     
    117201    [1.6180339887498946 .. 1.6180339887498950] 
    118202 
     203We can find the real and imaginary parts of an algebraic number (exactly). 
     204 
     205    sage: r = QQbar.polynomial_root(x^5 - x - 1, CIF(RIF(0.1, 0.2), RIF(1.0, 1.1))); r 
     206    [0.18123244446987538 .. 0.18123244446987541] + [1.0839541013177105 .. 1.0839541013177108]*I 
     207    sage: r.real() 
     208    [0.18123244446987538 .. 0.18123244446987541] 
     209    sage: r.imag() 
     210    [1.0839541013177105 .. 1.0839541013177108] 
     211    sage: r.minpoly() 
     212    x^5 - x - 1 
     213    sage: r.real().minpoly() 
     214    x^10 + 3/16*x^6 + 11/32*x^5 - 1/64*x^2 + 1/128*x - 1/1024 
     215    sage: r.imag().minpoly() # this takes a long time (143s on my laptop) 
     216    x^20 - 5/8*x^16 - 95/256*x^12 - 625/1024*x^10 - 5/512*x^8 - 1875/8192*x^6 + 25/4096*x^4 - 625/32768*x^2 + 2869/1048576 
     217 
     218We can find the absolute value and norm of an algebraic number exactly. 
     219(Note that we define the norm as the product of a number and its 
     220complex conjugate; this is the algebraic definition of norm, if we 
     221view QQbar as AA[I].) 
     222 
     223    sage: r = QQbar((-8)^(1/3)); r 
     224    [0.99999999999999988 .. 1.0000000000000003] + [1.7320508075688771 .. 1.7320508075688775]*I 
     225    sage: r.abs() == 2 
     226    True 
     227    sage: r.norm() == 4 
     228    True     
     229    sage: (r+I).norm().minpoly() 
     230    x^2 - 10*x + 13 
     231    sage: r = AA.polynomial_root(x^2 - x - 1, RIF(-1, 0)); r 
     232    [-0.61803398874989491 .. -0.61803398874989479] 
     233    sage: r.abs().minpoly() 
     234    x^2 + x - 1 
     235 
     236We can compute the multiplicative order of an algebraic number. 
     237 
     238    sage: QQbar(-1/2 + I*sqrt(3)/2).multiplicative_order() 
     239    3 
     240    sage: QQbar(-sqrt(3)/2 + I/2).multiplicative_order() 
     241    12 
     242    sage: QQbar.zeta(12345).multiplicative_order() 
     243    12345 
     244 
     245Cyclotomic fields are very fast as long as we only multiply and divide: 
     246 
     247    sage: z3_3 = QQbar.zeta(3) * 3 
     248    sage: z4_4 = QQbar.zeta(4) * 4 
     249    sage: z5_5 = QQbar.zeta(5) * 5 
     250    sage: z6_6 = QQbar.zeta(6) * 6 
     251    sage: z20_20 = QQbar.zeta(20) * 20 
     252    sage: z3_3 * z4_4 * z5_5 * z6_6 * z20_20 
     253    7200 
     254 
     255And they're still pretty fast even if you add and subtract, and trigger 
     256exact computation: 
     257 
     258    sage: (z3_3 + z4_4 + z5_5 + z6_6 + z20_20)._exact_value() 
     259    4*zeta60^15 + 5*zeta60^12 + 9*zeta60^10 + 20*zeta60^3 - 3 where a^16 + a^14 - a^10 - a^8 - a^6 + a^2 + 1 = 0 and a in [0.99452189536827328 .. 0.99452189536827341] + [0.10452846326765345 .. 0.10452846326765352]*I 
     260 
    119261The paper _ARPREC: An Arbitrary Precision Computation Package_ discusses 
    120262this result.  Evidently it is difficult to find, but we can easily 
    121263verify it. 
    122264 
    123     sage: alpha = AA.polynomial_root(x^10 + x^9 - x^7 - x^6 - x^5 - x^4 - x^3 + x + 1, RIF(1, 1.2)) 
     265    sage: alpha = QQbar.polynomial_root(x^10 + x^9 - x^7 - x^6 - x^5 - x^4 - x^3 + x + 1, RIF(1, 1.2)) 
    124266    sage: lhs = alpha^630 - 1 
    125267    sage: rhs_num = (alpha^315 - 1) * (alpha^210 - 1) * (alpha^126 - 1)^2 * (alpha^90 - 1) * (alpha^3 - 1)^3 * (alpha^2 - 1)^5 * (alpha - 1)^3 
     
    129271    [2.6420403358193507e44 .. 2.6420403358193520e44] 
    130272    sage: rhs 
    131     [2.6420403358193507e44 .. 2.6420403358193520e44] 
     273    [2.6420403358193503e44 .. 2.6420403358193520e44] 
    132274    sage: lhs - rhs 
    133     [-63347712947806569000000000000. .. 65804250213263496000000000000.] 
     275    [-79344219392947342000000000000. .. 81800756658404269000000000000.] 
    134276    sage: lhs == rhs 
    135277    True 
    136278    sage: lhs - rhs 
    137     [0.00000000000000000 .. 0.00000000000000000] 
     279    0 
    138280    sage: lhs._exact_value() 
    139281    -242494609856316402264822833062350847769474540*a^9 + 862295472068289472491654837785947906234680703*a^8 - 829559238431038252116584538075753012193290520*a^7 - 125882239615006638366472766103700441555126185*a^6 + 1399067970863104691667276008776398309383579345*a^5 - 1561176687069361567616835847286958553574223422*a^4 + 761706318888840943058230840550737823821027895*a^3 + 580740464974951394762758666210754821723780266*a^2 - 954587496403409756503464154898858512440951323*a + 546081123623099782018260884934770383777092602 where a^10 - 4*a^9 + 5*a^8 - a^7 - 6*a^6 + 9*a^5 - 6*a^4 - a^3 + 5*a^2 - 4*a + 1 = 0 and a in [0.44406334400909258 .. 0.44406334400909265] 
     
    144286from sage.structure.parent_gens import ParentWithGens 
    145287from sage.rings.real_mpfr import RR 
    146 from sage.rings.real_mpfi import RealIntervalField, RIF, RealIntervalFieldElement 
    147 from sage.rings.polynomial.polynomial_ring import PolynomialRing 
     288from sage.rings.real_mpfi import RealIntervalField, RIF, RealIntervalFieldElement, is_RealIntervalFieldElement 
     289from sage.rings.complex_field import ComplexField 
     290from sage.rings.complex_interval_field import ComplexIntervalField, is_ComplexIntervalField 
     291from sage.rings.complex_interval import ComplexIntervalFieldElement, is_ComplexIntervalFieldElement 
     292from sage.rings.polynomial.all import PolynomialRing, is_Polynomial 
    148293from sage.rings.integer_ring import ZZ 
    149294from sage.rings.rational_field import QQ 
    150 from sage.rings.number_field.number_field import NumberField 
     295from sage.rings.number_field.number_field import NumberField, NumberField_quadratic, QuadraticField, CyclotomicField 
    151296from sage.rings.number_field.number_field_element import is_NumberFieldElement 
     297from sage.rings.number_field.number_field_element_quadratic import NumberFieldElement_quadratic 
    152298from sage.rings.arith import factor 
    153299from sage.libs.pari.gen import pari 
    154300from sage.structure.element import generic_power 
     301import infinity 
     302from sage.misc.functional import cyclotomic_polynomial 
     303 
     304CC = ComplexField() 
     305CIF = ComplexIntervalField() 
    155306 
    156307# Singleton object implementation copied from integer_ring.py 
     
    163314        return _obj 
    164315 
    165 class AlgebraicRealField(_uniq_alg, sage.rings.ring.Field): 
     316_obj_r = None 
     317class _uniq_alg_r(object): 
     318    def __new__(cls): 
     319        global _obj_r 
     320        if _obj_r is None: 
     321            _obj_r = sage.rings.ring.Field.__new__(cls) 
     322        return _obj_r 
     323 
     324is_SymbolicExpressionRing = None 
     325 
     326def late_import(): 
     327    global is_SymbolicExpressionRing 
     328    if is_SymbolicExpressionRing is None: 
     329        import sage.calculus.calculus 
     330        is_SymbolicExpressionRing = sage.calculus.calculus.is_SymbolicExpressionRing 
     331 
     332class AlgebraicField_common(sage.rings.ring.Field): 
     333    def default_interval_prec(self): 
     334        return 64 
     335 
     336    def is_finite(self): 
     337        return False 
     338 
     339    def characteristic(self): 
     340        return sage.rings.integer.Integer(0) 
     341 
     342    def order(self): 
     343        return infinity.infinity 
     344 
     345    def common_polynomial(self, poly): 
     346        """ 
     347        Given a polynomial with algebraic coefficients, returns a 
     348        wrapper that caches high-precision calculations and 
     349        factorizations.  This wrapper can be passed to polynomial_root 
     350        in place of the polynomial. 
     351 
     352        Using common_polynomial makes no semantic difference, but will 
     353        improve efficiency if you are dealing with multiple roots 
     354        of a single polynomial. 
     355 
     356        EXAMPLES: 
     357            sage: x = polygen(ZZ) 
     358            sage: p = AA.common_polynomial(x^2 - x - 1) 
     359            sage: phi = AA.polynomial_root(p, RIF(1, 2)) 
     360            sage: tau = AA.polynomial_root(p, RIF(-1, 0)) 
     361            sage: phi + tau == 1 
     362            True 
     363            sage: phi * tau == -1 
     364            True 
     365 
     366            sage: x = polygen(SR) 
     367            sage: p = (x - sqrt(-5)) * (x - sqrt(3)); p 
     368            x^2 + ((1 - sqrt(3))*(1 - sqrt(5)*I) - sqrt(3)*sqrt(5)*I - 1)*x + sqrt(3)*sqrt(5)*I 
     369            sage: p = QQbar.common_polynomial(p) 
     370            sage: a = QQbar.polynomial_root(p, CIF(RIF(-0.1, 0.1), RIF(2, 3))); a 
     371            [-6.1814409042940318e-19 .. 6.0853195377215860e-19] + [2.2360679774997893 .. 2.2360679774997899]*I 
     372            sage: b = QQbar.polynomial_root(p, RIF(1, 2)); b 
     373            [1.7320508075688771 .. 1.7320508075688775] 
     374             
     375        These "common polynomials" can be shared between real and 
     376        complex roots: 
     377             sage: p = AA.common_polynomial(x^3 - x - 1) 
     378             sage: r1 = AA.polynomial_root(p, RIF(1.3, 1.4)); r1 
     379             [1.3247179572447458 .. 1.3247179572447461] 
     380             sage: r2 = QQbar.polynomial_root(p, CIF(RIF(-0.7, -0.6), RIF(0.5, 0.6))); r2 
     381             [-0.66235897862237303 .. -0.66235897862237291] + [0.56227951206230120 .. 0.56227951206230132]*I 
     382        """ 
     383        return AlgebraicPolynomialTracker(poly) 
     384 
     385class AlgebraicRealField(_uniq_alg_r, AlgebraicField_common): 
    166386    r""" 
    167387    The field of algebraic reals. 
    168  
    169388    """ 
    170389 
    171390    def __init__(self): 
    172391        ParentWithGens.__init__(self, self, ('x',), normalize=False) 
    173         self._default_interval_field = RealIntervalField(64) 
     392 
     393    def __call__(self, x): 
     394        """ 
     395        Coerce x into the field of algebraic real numbers. 
     396 
     397        """ 
     398 
     399        if isinstance(x, AlgebraicReal): 
     400            return x 
     401        elif isinstance(x, AlgebraicNumber): 
     402            if x.imag().is_zero(): 
     403                return x.real() 
     404            else: 
     405                raise TypeError, "Cannot coerce algebraic number with non-zero imaginary part to algebraic real" 
     406        elif hasattr(x, '_algebraic_'): 
     407            return x._algebraic_(AA) 
     408        return AlgebraicReal(x) 
    174409 
    175410    def _repr_(self): 
    176         return "Algebraic Field" 
     411        return "Algebraic Real Field" 
    177412 
    178413    # Is there a standard representation for this? 
    179414    def _latex_(self): 
    180415        return "\\mathbf{A}" 
    181  
    182     def __call__(self, x): 
    183         """ 
    184         Coerce x into the field of algebraic numbers. 
    185  
    186         """ 
    187  
    188         if isinstance(x, AlgebraicRealNumber): 
    189             return x 
    190         return AlgebraicRealNumber(x) 
    191416 
    192417    def _coerce_impl(self, x): 
     
    194419                          sage.rings.rational.Rational)): 
    195420            return self(x) 
     421        elif hasattr(x, '_algebraic_'): 
     422            return x._algebraic_(AA) 
    196423        raise TypeError, 'no implicit coercion of element to the algebraic numbers' 
     424 
     425    def has_coerce_map_from_impl(self, from_par): 
     426        if from_par == ZZ or from_par == QQ or from_par == int or from_par == long: 
     427            return True 
     428        late_import() 
     429        if is_SymbolicExpressionRing(from_par): 
     430            return True 
     431        return False 
    197432 
    198433    def _is_valid_homomorphism_(self, codomain, im_gens): 
     
    202437            return False 
    203438 
    204     def default_interval_field(self): 
    205         return self._default_interval_field 
    206  
    207439    def gens(self): 
    208440        return (self(1), ) 
     
    217449        return 1 
    218450 
    219     def is_finite(self): 
    220         return False 
    221  
    222451    def is_atomic_repr(self): 
    223452        return True 
    224  
    225     def characteristic(self): 
    226         return sage.rings.integer.Integer(0) 
    227  
    228     def order(self): 
    229         return infinity.infinity 
    230453 
    231454    def zeta(self, n=2): 
     
    237460            raise ValueError, "no n-th root of unity in algebraic reals" 
    238461 
    239     def common_polynomial(self, poly): 
    240         """ 
    241         Given a polynomial with algebraic coefficients, returns a 
    242         wrapper that caches high-precision calculations and 
    243         factorizations.  This wrapper can be passed to polynomial_root 
    244         in place of the polynomial. 
    245  
    246         Using common_polynomial makes no semantic difference, but will 
    247         improve efficiency if you are dealing with multiple roots 
    248         of a single polynomial. 
    249  
    250         EXAMPLES: 
    251             sage: x = polygen(AA) 
    252             sage: p = AA.common_polynomial(x^2 - x - 1) 
    253             sage: phi = AA.polynomial_root(p, RIF(0, 2)) 
    254             sage: tau = AA.polynomial_root(p, RIF(-2, 0)) 
    255             sage: phi + tau == 1 
    256             True 
    257             sage: phi * tau == -1 
    258             True 
    259         """ 
    260         return AlgebraicPolynomialTracker(poly) 
    261  
    262462    def polynomial_root(self, poly, interval, multiplicity=1): 
    263463        """ 
     
    280480 
    281481        Note that if you are constructing multiple roots of a single 
    282         polynomial, it is better to use AA.common_polynomial 
    283         to get a shared polynomial. 
     482        polynomial, it is better to use AA.common_polynomial (or 
     483        QQbar.common_polynomial; the two are equivalent) to get a 
     484        shared polynomial. 
    284485 
    285486        EXAMPLES: 
    286487            sage: x = polygen(AA) 
    287             sage: phi = AA.polynomial_root(x^2 - x - 1, RIF(0, 2)); phi 
     488            sage: phi = AA.polynomial_root(x^2 - x - 1, RIF(1, 2)); phi 
    288489            [1.6180339887498946 .. 1.6180339887498950] 
    289490            sage: p = (x-1)^7 * (x-2) 
     
    297498            [1.4142135623730949 .. 1.4142135623730952] 
    298499            True 
    299         """ 
    300         return AlgebraicRealNumber(AlgebraicRealNumberRoot(poly, interval, multiplicity)) 
     500 
     501        We allow complex polynomials, as long as the particular root 
     502        in question is real. 
     503            sage: K.<im> = QQ[I] 
     504            sage: x = polygen(K) 
     505            sage: p = (im + 1) * (x^3 - 2); p 
     506            (I + 1)*x^3 - 2*I - 2 
     507            sage: r = AA.polynomial_root(p, RIF(1, 2)); r^3 
     508            [1.9999999999999997 .. 2.0000000000000005] 
     509        """ 
     510        if not is_RealIntervalFieldElement(interval): 
     511            raise ValueError, "interval argument of .polynomial_root on algebraic real field must be real" 
     512 
     513        return AlgebraicReal(ANRoot(poly, interval, multiplicity)) 
    301514 
    302515def is_AlgebraicRealField(F): 
     
    305518AA = AlgebraicRealField() 
    306519 
    307 def rif_seq(): 
     520class AlgebraicField(_uniq_alg, AlgebraicField_common): 
     521    """ 
     522    The field of algebraic numbers. 
     523    """ 
     524 
     525    def __init__(self): 
     526        ParentWithGens.__init__(self, AA, ('I',), normalize=False) 
     527 
     528    def __call__(self, x): 
     529        """ 
     530        Coerce x into the field of algebraic numbers. 
     531 
     532        """ 
     533 
     534        if isinstance(x, AlgebraicNumber): 
     535            return x 
     536        elif isinstance(x, AlgebraicReal): 
     537            return AlgebraicNumber(x._descr) 
     538        elif hasattr(x, '_algebraic_'): 
     539            return x._algebraic_(QQbar) 
     540        return AlgebraicNumber(x) 
     541 
     542    def _repr_(self): 
     543        return "Algebraic Field" 
     544 
     545    def _coerce_impl(self, x): 
     546        if isinstance(x, (int, long, sage.rings.integer.Integer, 
     547                          sage.rings.rational.Rational)): 
     548            return self(x) 
     549        elif hasattr(x, '_algebraic_'): 
     550            return x._algebraic_(QQbar) 
     551        elif isinstance(x, AlgebraicReal): 
     552            return AlgebraicNumber(x._descr) 
     553        raise TypeError, 'no implicit coercion of element to the algebraic numbers' 
     554 
     555    def has_coerce_map_from_impl(self, from_par): 
     556        if from_par == ZZ or from_par == QQ or from_par == int or from_par == long: 
     557            return True 
     558        if from_par == AA: 
     559            return True 
     560        late_import() 
     561        if is_SymbolicExpressionRing(from_par): 
     562            return True 
     563        return False 
     564 
     565    def gens(self): 
     566        return(QQbar_I, ) 
     567 
     568    def gen(self, n=0): 
     569        if n == 0: 
     570            return QQbar_I 
     571        else: 
     572            raise IndexError, "n must be 0" 
     573 
     574    def ngens(self): 
     575        return 1 
     576 
     577    def is_atomic_repr(self): 
     578        return False 
     579 
     580    def zeta(self, n=4): 
     581        """ 
     582        Returns a primitive n'th root of unity.  (In fact, returns 
     583        exp(2*pi*I/n).) 
     584 
     585        EXAMPLES: 
     586            sage: QQbar.zeta(1) 
     587            1 
     588            sage: QQbar.zeta(2) 
     589            -1 
     590            sage: QQbar.zeta(3) 
     591            [-0.50000000000000012 .. -0.49999999999999994] + [0.86602540378443859 .. 0.86602540378443871]*I 
     592            sage: QQbar.zeta(4) 
     593            1*I 
     594            sage: QQbar.zeta() 
     595            1*I 
     596            sage: QQbar.zeta(5) 
     597            [0.30901699437494739 .. 0.30901699437494746] + [0.95105651629515353 .. 0.95105651629515365]*I 
     598            sage: QQbar.zeta(314159) 
     599            [0.99999999979999965 .. 0.99999999979999977] + [0.000020000016891958231 .. 0.000020000016891958236]*I 
     600        """ 
     601        return AlgebraicNumber(ANRootOfUnity(QQ_1/n, QQ_1)) 
     602 
     603    def polynomial_root(self, poly, interval, multiplicity=1): 
     604        """ 
     605        Given a polynomial with algebraic coefficients and an interval 
     606        enclosing exactly one root of the polynomial, constructs 
     607        an algebraic real representation of that root. 
     608 
     609        The polynomial need not be irreducible, or even squarefree; but 
     610        if the given root is a multiple root, its multiplicity must be 
     611        specified.  (IMPORTANT NOTE: Currently, multiplicity-k roots 
     612        are handled by taking the (k-1)th derivative of the polynomial. 
     613        This means that the interval must enclose exactly one root 
     614        of this derivative.) 
     615 
     616        The conditions on the arguments (that the interval encloses exactly 
     617        one root, and that multiple roots match the given multiplicity) 
     618        are not checked; if they are not satisfied, an error may be 
     619        thrown (possibly later, when the algebraic number is used), 
     620        or wrong answers may result. 
     621 
     622        Note that if you are constructing multiple roots of a single 
     623        polynomial, it is better to use QQbar.common_polynomial 
     624        to get a shared polynomial. 
     625 
     626        EXAMPLES: 
     627            sage: x = polygen(QQbar) 
     628            sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(0, 2)); phi 
     629            [1.6180339887498946 .. 1.6180339887498950] 
     630            sage: p = (x-1)^7 * (x-2) 
     631            sage: r = QQbar.polynomial_root(p, RIF(9/10, 11/10), multiplicity=7) 
     632            sage: r; r == 1 
     633            [1.0000000000000000 .. 1.0000000000000000] 
     634            True 
     635            sage: p = (x-phi)*(x-sqrt(QQbar(2))) 
     636            sage: r = QQbar.polynomial_root(p, RIF(1, 3/2)) 
     637            sage: r; r == sqrt(QQbar(2)) 
     638            [1.4142135623730949 .. 1.4142135623730952] 
     639            True 
     640        """ 
     641        return AlgebraicNumber(ANRoot(poly, interval, multiplicity)) 
     642 
     643def is_AlgebraicField(F): 
     644    return isinstance(F, AlgebraicField) 
     645 
     646QQbar = AlgebraicField() 
     647 
     648def prec_seq(): 
    308649    # XXX Should do some testing to see where the efficiency breaks are 
    309     # in MPFR. 
     650    # in MPFR.  We could also test variants like "bits = bits + bits // 2" 
     651    # (I think this is what MPFR uses internally). 
    310652    bits = 64 
    311653    while True: 
    312         yield RealIntervalField(bits) 
     654        yield bits 
    313655        bits = bits * 2 
    314 #         # XXX temporary debugging: 
    315 #         if bits > 1024: 
    316 #             break 
     656 
     657_short_prec_seq = (64, 128, None) 
     658def short_prec_seq(): return _short_prec_seq 
     659 
     660def tail_prec_seq(): 
     661    bits = 256 
     662    while True: 
     663        yield bits 
     664        bits = bits * 2 
     665 
     666def rational_exact_root(r, d): 
     667    """ 
     668    Checks whether the rational r is an exact d'th power.  If so, returns 
     669    the d'th root of r; otherwise, returns None. 
     670 
     671    EXAMPLES: 
     672        sage: from sage.rings.algebraic_real import rational_exact_root 
     673        sage: rational_exact_root(16/81, 4) 
     674        2/3 
     675        sage: rational_exact_root(8/81, 3) is None 
     676        True 
     677    """ 
     678    num = r.numerator() 
     679    den = r.denominator() 
     680 
     681    (num_rt, num_exact) = num.nth_root(d, report_exact=True) 
     682    if not num_exact: return None 
     683    (den_rt, den_exact) = den.nth_root(d, report_exact=True) 
     684    if not den_exact: return None 
     685    return (num_rt / den_rt) 
    317686 
    318687def clear_denominators(poly): 
     
    328697    (Inspired by Pari's primitive_pol_to_monic().) 
    329698 
     699    We assume that coefficient denominators are "small"; the algorithm 
     700    factors the denominators, to give the smallest possible scale factor. 
     701 
    330702    EXAMPLES: 
    331703        sage: from sage.rings.algebraic_real import clear_denominators 
     
    338710 
    339711    """ 
     712 
     713    # This algorithm factors the polynomial denominators. 
     714    # We should check the size of the denominators and switch to 
     715    # an alternate, less precise algorithm if we decide factoring 
     716    # would be too slow. 
    340717 
    341718    d = poly.denominator() 
     
    402779    assert(best is not None) 
    403780    parent = poly.parent() 
    404     return parent(best_elt), parent(best_elt.Mod(pari_poly).modreverse().lift()), parent(best) 
     781    rev = parent(best_elt.Mod(pari_poly).modreverse().lift()) 
     782    return parent(best_elt), rev, parent(best) 
    405783 
    406784def isolating_interval(intv_fn, pol): 
    407785    """ 
    408     intv_fn is a function that takes a RealIntervalField and returns an 
    409     interval containing some particular root of pol.  (It must return 
    410     better approximations as the RealIntervalField precision increases.) 
     786    intv_fn is a function that takes a precision and returns an 
     787    interval of that precision containing some particular root of pol. 
     788    (It must return better approximations as the precision increases.) 
    411789    pol is an irreducible polynomial with rational coefficients. 
    412790 
     
    417795 
    418796        sage: _.<x> = QQ['x'] 
    419         sage: isolating_interval(lambda rif: sqrt(rif(2)), x^2 - 2) 
     797        sage: isolating_interval(lambda prec: sqrt(RealIntervalField(prec)(2)), x^2 - 2) 
    420798        [1.41421356237309504876 .. 1.41421356237309504888] 
    421799 
     
    423801        sage: delta = 10^(-70) 
    424802        sage: p = (x - 1) * (x - 1 - delta) * (x - 1 + delta) 
    425         sage: isolating_interval(lambda rif: rif(1 + delta), p) 
     803        sage: isolating_interval(lambda prec: RealIntervalField(prec)(1 + delta), p) 
    426804        [1.00000000000000000000000000000000000000000000000000000000000000000000009999999999999999999999999999999999999999999999999999999999999999999999999999999999998 .. 1.00000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000014] 
     805 
     806    The function also works with complex intervals and complex roots: 
     807        sage: p = x^2 - x + 13/36 
     808        sage: isolating_interval(lambda prec: ComplexIntervalField(prec)(1/2, 1/3), p) 
     809        [0.500000000000000000000 .. 0.500000000000000000000] + [0.333333333333333333315 .. 0.333333333333333333343]*I 
    427810    """ 
    428     for rif in rif_seq(): 
    429         intv = intv_fn(rif) 
     811    dpol = pol.derivative() 
     812 
     813    for prec in prec_seq(): 
     814        intv = intv_fn(prec) 
     815        ifld = intv.parent() 
    430816 
    431817        # We need to verify that pol has exactly one root in the 
     
    435821        # root (that the interval is sufficiently narrow). 
    436822 
    437         # Call the root we want alpha, and the bounding interval 
    438         # [bot .. top].  By Budan's theorem, if pol(x+bot) 
    439         # has at most one more sign change than pol(x+top), 
    440         # then pol has at most one root in this interval. 
    441         # This is true if all coefficients in pol(x+bot) 
    442         # except for the constant coefficient have the same 
    443         # sign as the corresponding coefficients in pol(x+top). 
    444  
    445         # We can check this by computing pol(x+new_intv). 
    446         # This gives an "interval polynomial" which represents 
    447         # a set of polynomials, including pol(x+bot) and 
    448         # pol(x+top).  If all coefficients except the constant 
    449         # coefficient of this interval polynomial are bounded away from 
    450         # zero, then pol has at most one root in intv. 
    451          
    452         # This is a sufficient condition, but not a necessary one. 
    453         # It is not obvious that there always exists a bounding 
    454         # interval for alpha with this property.  Fortunately, 
    455         # in the current case with pol irreducible, such 
    456         # a bounding interval does exist. 
    457  
    458         # Consider the polynomial pol(x+alpha), where 
    459         # pol has degree n.  The coefficient of x^k in this 
    460         # polynomial has an exact representation as a polynomial 
    461         # in QQ[alpha] of degree (n-k).  If this coefficient is 
    462         # equal to zero, then that means that alpha is a zero 
    463         # of this degree (n-k) polynomial.  But if k>0, then this 
    464         # is impossible, since alpha is a root of an irreducible 
    465         # degree n polynomial. 
    466  
    467         # Thus, all coefficients of pol(x+alpha) are nonzero, 
    468         # except for the constant coefficient, which is zero.  We 
    469         # are guaranteed that if we select a sufficiently tight bounding 
    470         # interval around alpha, then pol(x+[bot..top]) 
    471         # will have coefficients bounded away from zero, which proves 
    472         # that there is only one root within that bounding interval. 
    473  
    474         zero = rif(0) 
    475         rif_poly_ring = rif['x'] 
    476  
    477         ip = pol(rif_poly_ring.gen() + intv) 
    478         coeffs = ip.list() 
    479         assert(zero in coeffs[0]) 
    480  
    481         ok = True 
    482  
    483         for c in coeffs[1:]: 
    484             if zero in c: 
    485                 ok = False 
    486                 break 
    487         if ok: 
     823        # We do this by computing the derivative of the polynomial 
     824        # over the interval.  If the derivative is bounded away from zero, 
     825        # then we know there can be at most one root. 
     826 
     827        if not dpol(intv).contains_zero(): 
    488828            return intv 
    489829 
    490830def find_zero_result(fn, l): 
    491831    """ 
    492     l is a list of some sort. 
    493     fn is a function which maps an element of l and a RealIntervalField 
    494     into an interval, such that for a sufficiently precise RealIntervalField, 
    495     exactly one element of l results in an interval containing 0. 
    496     Returns that one element of l. 
     832    l is a list of some sort.  fn is a function which maps an element 
     833    of l and a precision into an interval (either real or complex) of 
     834    that precision, such that for sufficient precision, exactly one 
     835    element of l results in an interval containing 0.  Returns that 
     836    one element of l. 
    497837 
    498838    EXAMPLES: 
     
    503843        sage: p2 = x - 1 - delta 
    504844        sage: p3 = x - 1 + delta 
    505         sage: p2 == find_zero_result(lambda p, rif: p(rif(1 + delta)), [p1, p2, p3]) 
     845        sage: p2 == find_zero_result(lambda p, prec: p(RealIntervalField(prec)(1 + delta)), [p1, p2, p3]) 
    506846        True 
    507847    """ 
    508     for rif in rif_seq(): 
     848    for prec in prec_seq(): 
    509849        result = None 
    510850        ambig = False 
    511851        for v in l: 
    512             intv = fn(v, rif) 
    513             if 0 in intv: 
     852            intv = fn(v, prec) 
     853            if intv.contains_zero(): 
    514854                if result is not None: 
    515855                    ambig = True 
     
    521861            raise ValueError, 'find_zero_result could not find any zeroes' 
    522862        return result 
     863 
     864def conjugate_expand(v): 
     865    """ 
     866    If the interval v (which may be real or complex) includes some 
     867    purely real numbers, return v' containing v such that 
     868    v' == v'.conjugate().  Otherwise return v unchanged.  (Note that if 
     869    v' == v'.conjugate(), and v' includes one non-real root of a real 
     870    polynomial, then v' also includes the conjugate of that root. 
     871    Also note that the diameter of the return value is at most twice 
     872    the diameter of the input.) 
     873 
     874    EXAMPLES: 
     875        sage: from sage.rings.algebraic_real import conjugate_expand 
     876        sage: conjugate_expand(CIF(RIF(0, 1), RIF(1, 2))) 
     877        [0.00000000000000000 .. 1.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I 
     878        sage: conjugate_expand(CIF(RIF(0, 1), RIF(0, 1))) 
     879        [0.00000000000000000 .. 1.0000000000000000] + [-1.0000000000000000 .. 1.0000000000000000]*I 
     880        sage: conjugate_expand(CIF(RIF(0, 1), RIF(-2, 1))) 
     881        [0.00000000000000000 .. 1.0000000000000000] + [-2.0000000000000000 .. 2.0000000000000000]*I 
     882        sage: conjugate_expand(RIF(1, 2)) 
     883        [1.0000000000000000 .. 2.0000000000000000] 
     884    """ 
     885    if is_RealIntervalFieldElement(v): 
     886        return v 
     887    im = v.imag() 
     888    if not im.contains_zero(): 
     889        return v 
     890    re = v.real() 
     891    fld = ComplexIntervalField(v.prec()) 
     892    return fld(re, im.union(-im)) 
     893 
     894def conjugate_shrink(v): 
     895    """ 
     896    If the interval v includes some purely real numbers, return 
     897    a real interval containing only those real numbers.  Otherwise 
     898    return v unchanged. 
     899 
     900    If v includes exactly one root of a real polynomial, and v was 
     901    returned by conjugate_expand(), then conjugate_shrink(v) still 
     902    includes that root, and is a RealIntervalFieldElement iff the root 
     903    in question is real. 
     904 
     905    EXAMPLES: 
     906        sage: from sage.rings.algebraic_real import conjugate_shrink 
     907        sage: conjugate_shrink(RIF(3, 4)) 
     908        [3.0000000000000000 .. 4.0000000000000000] 
     909        sage: conjugate_shrink(CIF(RIF(1, 2), RIF(1, 2))) 
     910        [1.0000000000000000 .. 2.0000000000000000] + [1.0000000000000000 .. 2.0000000000000000]*I 
     911        sage: conjugate_shrink(CIF(RIF(1, 2), RIF(0, 1))) 
     912        [1.0000000000000000 .. 2.0000000000000000] 
     913        sage: conjugate_shrink(CIF(RIF(1, 2), RIF(-1, 2))) 
     914        [1.0000000000000000 .. 2.0000000000000000] 
     915    """ 
     916    if is_RealIntervalFieldElement(v): 
     917        return v 
     918    im = v.imag() 
     919    if im.contains_zero(): 
     920        return v.real() 
     921    return v 
    523922 
    524923# Cache some commonly-used polynomial rings 
     
    547946class AlgebraicGenerator(SageObject): 
    548947    """ 
    549     An AlgebraicGenerator represents both an algebraic real alpha and 
     948    An AlgebraicGenerator represents both an algebraic number alpha and 
    550949    the number field QQ[alpha].  There is a single AlgebraicGenerator 
    551     representing QQ (with alpha==1). 
     950    representing QQ (with alpha==0). 
    552951 
    553952    The AlgebraicGenerator class is private, and should not be used 
     
    559958        Construct an AlgebraicGenerator object. 
    560959 
    561         sage: from sage.rings.algebraic_real import AlgebraicRealNumberRoot, AlgebraicGenerator, unit_generator 
     960        sage: from sage.rings.algebraic_real import ANRoot, AlgebraicGenerator, qq_generator 
    562961        sage: _.<y> = QQ['y'] 
    563         sage: x = polygen(AA) 
     962        sage: x = polygen(QQbar) 
    564963        sage: nf = NumberField(y^2 - y - 1, name='a', check=False) 
    565         sage: root = AlgebraicRealNumberRoot(x^2 - x - 1, RIF(1, 2)) 
    566         sage: x = AlgebraicGenerator(nf, root) 
    567         sage: x 
     964        sage: root = ANRoot(x^2 - x - 1, RIF(1, 2)) 
     965        sage: gen = AlgebraicGenerator(nf, root) 
     966        sage: gen 
    568967        Number Field in a with defining polynomial y^2 - y - 1 with a in [1.6180339887498946 .. 1.6180339887498950] 
    569         sage: x.field() 
     968        sage: gen.field() 
    570969        Number Field in a with defining polynomial y^2 - y - 1 
    571         sage: x.is_unit() 
     970        sage: gen.is_trivial() 
    572971        False 
    573         sage: x.union(unit_generator) is x 
     972        sage: gen.union(qq_generator) is gen 
    574973        True 
    575         sage: unit_generator.union(x) is x 
     974        sage: qq_generator.union(gen) is gen 
    576975        True 
     976        sage: nf = NumberField(y^2 + 1, name='a', check=False) 
     977        sage: root = ANRoot(x^2 + 1, CIF(0, 1)) 
     978        sage: x = AlgebraicGenerator(nf, root); x         
     979        Number Field in a with defining polynomial y^2 + 1 with a in [1.0000000000000000 .. 1.0000000000000000]*I 
    577980        """ 
    578981        self._field = field 
    579         self._unit = (field is None) 
     982        self._pari_field = None 
     983        self._trivial = (field is None) 
    580984        self._root = root 
    581985        self._unions = {} 
     986        self._cyclotomic = False 
    582987        global algebraic_generator_counter 
    583988        self._index = algebraic_generator_counter 
     
    590995        return cmp(self._index, other._index) 
    591996 
     997    def set_cyclotomic(self, n): 
     998        self._cyclotomic = True 
     999        self._cyclotomic_order = ZZ(n) 
     1000 
     1001    def is_complex(self): 
     1002        return self._root.is_complex() 
     1003 
    5921004    def _repr_(self): 
    593         if self._unit: 
    594             return 'Unit generator' 
     1005        if self._trivial: 
     1006            return 'Trivial generator' 
    5951007        else: 
    596             return '%s with a in %s'%(self._field, self._root.interval_fast(RIF)) 
    597  
    598     def is_unit(self): 
    599         """ 
    600         Returns true iff this is the unit generator (alpha == 1), which 
     1008            if isinstance(self._root, ANRootOfUnity): 
     1009                return str(self._root) 
     1010            else: 
     1011                return '%s with a in %s'%(self._field, self._root._interval_fast(53)) 
     1012 
     1013    def is_trivial(self): 
     1014        """ 
     1015        Returns true iff this is the trivial generator (alpha == 0), which 
    6011016        does not actually extend the rationals. 
    6021017 
    6031018        EXAMPLES: 
    604             sage: from sage.rings.algebraic_real import unit_generator 
    605             sage: unit_generator.is_unit() 
     1019            sage: from sage.rings.algebraic_real import qq_generator 
     1020            sage: qq_generator.is_trivial() 
    6061021            True 
    6071022        """ 
    608         return self._unit 
     1023        return self._trivial 
    6091024 
    6101025    def field(self): 
    6111026        return self._field 
    6121027 
    613     def interval_fast(self, field): 
     1028    def pari_field(self): 
     1029        if self._pari_field is None: 
     1030            pari_pol = self._field.pari_polynomial().subst('x','y') 
     1031            self._pari_field = pari_pol.nfinit(1) 
     1032        return self._pari_field 
     1033 
     1034    def conjugate(self): 
     1035        """ 
     1036        If this generator is for the algebraic number alpha, return a 
     1037        generator for the complex conjugate of alpha. 
     1038        """ 
     1039        try: 
     1040            return self._conjugate 
     1041        except AttributeError: 
     1042            if not self.is_complex(): 
     1043                self._conjugate = self 
     1044            else: 
     1045                conj = AlgebraicGenerator(self._field, self._root.conjugate(None)) 
     1046                self._conjugate = conj 
     1047                conj._conjugate = self 
     1048            if self._cyclotomic: 
     1049                conj_rel = QQx_x ** (self._cyclotomic_order - 1) 
     1050                rel = AlgebraicGeneratorRelation(self, conj_rel, conj, conj_rel, self) 
     1051                self._unions[conj] = rel 
     1052                conj._unions[self] = rel 
     1053            return self._conjugate 
     1054 
     1055    def _interval_fast(self, prec): 
    6141056        """ 
    6151057        Returns an interval containing this generator, to the specified 
    6161058        precision. 
    6171059        """ 
    618         return self._root.interval_fast(field) 
     1060        return self._root._interval_fast(prec) 
    6191061 
    6201062    def union(self, other): 
     
    6241066 
    6251067        EXAMPLES: 
    626             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRoot, AlgebraicGenerator, unit_generator 
     1068            sage: from sage.rings.algebraic_real import ANRoot, AlgebraicGenerator, qq_generator 
    6271069            sage: _.<y> = QQ['y'] 
    628             sage: x = polygen(AA) 
     1070            sage: x = polygen(QQbar) 
    6291071            sage: nf2 = NumberField(y^2 - 2, name='a', check=False) 
    630             sage: root2 = AlgebraicRealNumberRoot(x^2 - 2, RIF(1, 2)) 
     1072            sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) 
    6311073            sage: gen2 = AlgebraicGenerator(nf2, root2) 
    6321074            sage: gen2 
    6331075            Number Field in a with defining polynomial y^2 - 2 with a in [1.4142135623730949 .. 1.4142135623730952] 
    6341076            sage: nf3 = NumberField(y^2 - 3, name='a', check=False) 
    635             sage: root3 = AlgebraicRealNumberRoot(x^2 - 3, RIF(1, 2)) 
     1077            sage: root3 = ANRoot(x^2 - 3, RIF(1, 2)) 
    6361078            sage: gen3 = AlgebraicGenerator(nf3, root3) 
    6371079            sage: gen3 
    6381080            Number Field in a with defining polynomial y^2 - 3 with a in [1.7320508075688771 .. 1.7320508075688775] 
    639             sage: gen2.union(unit_generator) is gen2 
     1081            sage: gen2.union(qq_generator) is gen2 
    6401082            True 
    641             sage: unit_generator.union(gen3) is gen3 
     1083            sage: qq_generator.union(gen3) is gen3 
    6421084            True 
    6431085            sage: gen2.union(gen3) 
    6441086            Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in [0.51763809020504147 .. 0.51763809020504159] 
    6451087        """ 
    646         if self._unit: 
     1088        if self._trivial: 
    6471089            return other 
    648         if other._unit: 
     1090        if other._trivial: 
    6491091            return self 
    6501092        if self is other: 
     
    6541096        if self._field.polynomial().degree() < other._field.polynomial().degree(): 
    6551097            self, other = other, self 
     1098        elif other._cyclotomic: 
     1099            self, other = other, self 
     1100 
     1101        if self._cyclotomic and other._cyclotomic: 
     1102            parent_order = self._cyclotomic_order.lcm(other._cyclotomic_order) 
     1103            new_gen = cyclotomic_generator(parent_order) 
     1104            rel = AlgebraicGeneratorRelation(self, QQx_x ** (parent_order // self._cyclotomic_order), 
     1105                                             other, QQx_x ** (parent_order // other._cyclotomic_order), 
     1106                                             new_gen) 
     1107            self._unions[other] = rel 
     1108            other._unions[self] = rel 
     1109            return new_gen 
     1110 
    6561111        sp = self._field.polynomial() 
    6571112        op = other._field.polynomial() 
     
    6621117        # print self._field.polynomial().degree() 
    6631118        # pari_nf = self._field.pari_nf() 
    664         pari_nf = pari_nf_hack(self._field) 
     1119        pari_nf = self.pari_field() 
    6651120        # print pari_nf[0] 
    6661121        factors = list(pari_nf.nffactor(op).lift())[0] 
    6671122        # print factors 
    6681123        x, y = QQxy.gens() 
    669         # XXX Go through strings because multivariate polynomial coercion from 
    670         # Pari is not implemented 
    671         factors_sage = [QQxy(str(p)) for p in factors] 
     1124        factors_sage = [QQxy(p) for p in factors] 
    6721125        # print factors_sage 
    673         def find_fn(p, rif): 
    674             rif_poly = rif['x', 'y'] 
    675             ip = rif_poly(p) 
    676             return ip(other._root.interval_fast(rif), self._root.interval_fast(rif)) 
     1126        def find_fn(p, prec): 
     1127            ifield = RealIntervalField(prec) 
     1128            if_poly = ifield['x', 'y'] 
     1129            ip = if_poly(p) 
     1130            return ip(other._root._interval_fast(prec), self._root._interval_fast(prec)) 
    6771131        my_factor = find_zero_result(find_fn, factors_sage) 
    6781132 
     
    7071161        new_nf_a = new_nf.gen() 
    7081162 
    709         def intv_fn(rif): 
    710             return red_elt(self._root.interval_fast(rif) * k + other._root.interval_fast(rif)) 
    711         new_intv = isolating_interval(intv_fn, red_pol) 
    712  
    713         new_gen = AlgebraicGenerator(new_nf, AlgebraicRealNumberRoot(QQx(red_pol), new_intv)) 
     1163        def intv_fn(prec): 
     1164            return conjugate_expand(red_elt(self._root._interval_fast(prec) * k + other._root._interval_fast(prec))) 
     1165        new_intv = conjugate_shrink(isolating_interval(intv_fn, red_pol)) 
     1166 
     1167        new_gen = AlgebraicGenerator(new_nf, ANRoot(QQx(red_pol), new_intv)) 
    7141168        rel = AlgebraicGeneratorRelation(self, self_pol_sage(red_back_x), 
    7151169                                         other, (QQx_x - k*self_pol_sage)(red_back_x), 
     
    7171171        self._unions[other] = rel 
    7181172        other._unions[self] = rel 
    719         return rel.parent 
     1173        return new_gen 
    7201174     
    7211175    def super_poly(self, super, checked=None): 
     
    7251179        leaves is gen, gen.super_poly(super) returns a polynomial 
    7261180        expressing the value of gen in terms of the value of super. 
    727         (Except that if gen is unit_generator, super_poly() always 
     1181        (Except that if gen is qq_generator, super_poly() always 
    7281182        returns None.) 
    7291183 
    7301184        EXAMPLES: 
    731             sage: from sage.rings.algebraic_real import AlgebraicGenerator, AlgebraicRealNumberRoot, unit_generator 
     1185            sage: from sage.rings.algebraic_real import AlgebraicGenerator, ANRoot, qq_generator 
    7321186            sage: _.<y> = QQ['y'] 
    733             sage: x = polygen(AA) 
     1187            sage: x = polygen(QQbar) 
    7341188            sage: nf2 = NumberField(y^2 - 2, name='a', check=False) 
    735             sage: root2 = AlgebraicRealNumberRoot(x^2 - 2, RIF(1, 2)) 
     1189            sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) 
    7361190            sage: gen2 = AlgebraicGenerator(nf2, root2) 
    7371191            sage: gen2 
    7381192            Number Field in a with defining polynomial y^2 - 2 with a in [1.4142135623730949 .. 1.4142135623730952] 
    7391193            sage: nf3 = NumberField(y^2 - 3, name='a', check=False) 
    740             sage: root3 = AlgebraicRealNumberRoot(x^2 - 3, RIF(1, 2)) 
     1194            sage: root3 = ANRoot(x^2 - 3, RIF(1, 2)) 
    7411195            sage: gen3 = AlgebraicGenerator(nf3, root3) 
    7421196            sage: gen3 
     
    7451199            sage: gen2_3 
    7461200            Number Field in a with defining polynomial y^4 - 4*y^2 + 1 with a in [0.51763809020504147 .. 0.51763809020504159] 
    747             sage: unit_generator.super_poly(gen2) is None 
     1201            sage: qq_generator.super_poly(gen2) is None 
    7481202            True 
    7491203            sage: gen2.super_poly(gen2_3) 
     
    7751229    def __call__(self, elt): 
    7761230        """ 
    777         Takes an AlgebraicRealNumber which is represented as either a rational 
     1231        Takes an algebraic number which is represented as either a rational 
    7781232        or a number field element, and which is in a subfield of the 
    7791233        field generated by this generator.  Lifts the number into the 
    7801234        field of this generator, and returns either a Rational or a 
    781         NumberFieldElement depending on whether this is the unit generator. 
    782  
    783         EXAMPLES: 
    784             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRoot, AlgebraicGenerator, AlgebraicRealNumberExtensionElement, AlgebraicRealNumberRational 
     1235        NumberFieldElement depending on whether this is the trivial generator. 
     1236 
     1237        EXAMPLES: 
     1238            sage: from sage.rings.algebraic_real import ANRoot, AlgebraicGenerator, ANExtensionElement, ANRational 
    7851239            sage: _.<y> = QQ['y'] 
    786             sage: x = polygen(AA) 
     1240            sage: x = polygen(QQbar) 
    7871241            sage: nf2 = NumberField(y^2 - 2, name='a', check=False) 
    788             sage: root2 = AlgebraicRealNumberRoot(x^2 - 2, RIF(1, 2)) 
     1242            sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) 
    7891243            sage: gen2 = AlgebraicGenerator(nf2, root2) 
    7901244            sage: gen2 
    7911245            Number Field in a with defining polynomial y^2 - 2 with a in [1.4142135623730949 .. 1.4142135623730952] 
    792             sage: sqrt2 = AlgebraicRealNumberExtensionElement(gen2, nf2.gen()) 
     1246            sage: sqrt2 = ANExtensionElement(gen2, nf2.gen()) 
    7931247            sage: nf3 = NumberField(y^2 - 3, name='a', check=False) 
    794             sage: root3 = AlgebraicRealNumberRoot(x^2 - 3, RIF(1, 2)) 
     1248            sage: root3 = ANRoot(x^2 - 3, RIF(1, 2)) 
    7951249            sage: gen3 = AlgebraicGenerator(nf3, root3) 
    7961250            sage: gen3 
    7971251            Number Field in a with defining polynomial y^2 - 3 with a in [1.7320508075688771 .. 1.7320508075688775] 
    798             sage: sqrt3 = AlgebraicRealNumberExtensionElement(gen3, nf3.gen()) 
     1252            sage: sqrt3 = ANExtensionElement(gen3, nf3.gen()) 
    7991253            sage: gen2_3 = gen2.union(gen3) 
    8001254            sage: gen2_3 
     
    8021256            sage: gen2_3(sqrt2) 
    8031257            -a^3 + 3*a 
    804             sage: gen2_3(AlgebraicRealNumberRational(1/7)) 
     1258            sage: gen2_3(ANRational(1/7)) 
    8051259            1/7 
    8061260            sage: gen2_3(sqrt3) 
    8071261            -a^2 + 2             
    8081262        """ 
    809         if self._unit: 
     1263        if self._trivial: 
    8101264            return elt.rational_value() 
    8111265        if elt.is_rational(): 
     
    8221276        return self._field(elt.field_element_value().polynomial()(sp)) 
    8231277 
    824 class AlgebraicRealNumberDescr(SageObject): 
     1278# These are the functions used to add, subtract, multiply, and divide 
     1279# algebraic numbers.  Basically, we try to compute exactly if the 
     1280# result would be a Gaussian rational, or a rational times a root 
     1281# of unity; or if both arguments are already known to be in the same 
     1282# number field.  Otherwise we fall back to floating-point computation, 
     1283# to be backed up by exact symbolic computation only as required. 
     1284 
     1285# These choices are motivated partly by efficiency considerations 
     1286# (not backed up by benchmarks, so other possibilities might be more 
     1287# efficient), and partly by concerns for the prettiness of output: 
     1288# we want algebraic numbers to print as Gaussian rationals, rather 
     1289# than as intervals, as often as possible. 
     1290 
     1291def an_addsub_rational(a, b, sub): 
     1292    va = a._descr._value 
     1293    vb = b._descr._value 
     1294    if sub: 
     1295        v = va - vb 
     1296    else: 
     1297        v = va + vb 
     1298    return ANRational(v) 
     1299 
     1300def an_muldiv_rational(a, b, div): 
     1301    va = a._descr._value 
     1302    vb = b._descr._value 
     1303    if div: 
     1304        v = va / vb 
     1305    else: 
     1306        v = va * vb 
     1307    return ANRational(v) 
     1308 
     1309def an_addsub_zero(a, b, sub): 
     1310    if b._descr.is_rational() and b._descr.rational_value().is_zero(): 
     1311        return a._descr 
     1312    # we know a is 0 
     1313    if sub: 
     1314        return b._descr.neg(b) 
     1315    else: 
     1316        return b._descr 
     1317 
     1318def an_muldiv_zero(a, b, div): 
     1319    if b._descr.is_rational() and b._descr.rational_value().is_zero(): 
     1320        if div: 
     1321            raise ValueError, "algebraic number division by zero" 
     1322        else: 
     1323            return ANRational(0) 
     1324    # we know a is 0 
     1325    return ANRational(0) 
     1326 
     1327def an_addsub_gaussian(a, b, sub): 
     1328    va = a._descr.gaussian_value() 
     1329    vb = b._descr.gaussian_value() 
     1330    if sub: 
     1331        v = va - vb 
     1332    else: 
     1333        v = va + vb 
     1334    return ANExtensionElement(QQbar_I_generator, v) 
     1335 
     1336def an_muldiv_gaussian(a, b, div): 
     1337    va = a._descr.gaussian_value() 
     1338    vb = b._descr.gaussian_value() 
     1339    if div: 
     1340        v = va / vb 
     1341    else: 
     1342        v = va * vb 
     1343    return ANExtensionElement(QQbar_I_generator, v) 
     1344 
     1345def an_addsub_expr(a, b, sub): 
     1346    return ANBinaryExpr(a, b, ('-' if sub else '+')) 
     1347 
     1348def an_muldiv_expr(a, b, div): 
     1349    return ANBinaryExpr(a, b, ('/' if div else '*')) 
     1350 
     1351def an_muldiv_rootunity(a, b, div): 
     1352    ad = a._descr 
     1353    bd = b._descr 
     1354    if div: 
     1355        return ANRootOfUnity(ad.angle() - bd.angle(), ad.scale() / bd.scale()) 
     1356    else: 
     1357        return ANRootOfUnity(ad.angle() + bd.angle(), ad.scale() * bd.scale()) 
     1358 
     1359def an_addsub_rootunity(a, b, sub): 
     1360    ad = a._descr 
     1361    bd = b._descr 
     1362    if ad._angle == bd._angle: 
     1363        if sub: 
     1364            return ANRootOfUnity(ad.angle(), ad.scale() - bd.scale()) 
     1365        else: 
     1366            return ANRootOfUnity(ad.angle(), ad.scale() + bd.scale()) 
     1367    else: 
     1368        return an_addsub_expr(a, b, sub) 
     1369 
     1370def an_muldiv_element(a, b, div): 
     1371    ad = a._descr 
     1372    bd = b._descr 
     1373    adg = ad.generator() 
     1374    bdg = bd.generator() 
     1375    if adg == qq_generator or adg == bdg: 
     1376        if div: 
     1377            return ANExtensionElement(bdg, ad._value / bd._value) 
     1378        else: 
     1379            return ANExtensionElement(bdg, ad._value * bd._value) 
     1380    if bdg == qq_generator: 
     1381        if div: 
     1382            return ANExtensionElement(adg, ad._value / bd._value) 
     1383        else: 
     1384            return ANExtensionElement(adg, ad._value * bd._value) 
     1385    return ANBinaryExpr(a, b, ('/' if div else '*')) 
     1386 
     1387def an_addsub_element(a, b, sub): 
     1388    ad = a._descr 
     1389    bd = b._descr 
     1390    adg = ad.generator() 
     1391    bdg = bd.generator() 
     1392    if adg == qq_generator or adg == bdg: 
     1393        if sub: 
     1394            return ANExtensionElement(bdg, ad._value - bd._value) 
     1395        else: 
     1396            return ANExtensionElement(bdg, ad._value + bd._value) 
     1397    if bdg == qq_generator: 
     1398        if sub: 
     1399            return ANExtensionElement(adg, ad._value - bd._value) 
     1400        else: 
     1401            return ANExtensionElement(adg, ad._value + bd._value) 
     1402    return ANBinaryExpr(a, b, ('-' if sub else '+')) 
     1403 
     1404# Here we hand-craft a simple multimethod dispatch. 
     1405_mul_algo = {} 
     1406_add_algo = {} 
     1407_descriptors = ('zero', 'rational', 'imaginary', 'gaussian', 'rootunity', 'element', 'other') 
     1408for a in _descriptors: 
     1409    for b in _descriptors: 
     1410        key = (a, b) 
     1411        if a == 'zero' or b == 'zero': 
     1412            _mul_algo[key] = an_muldiv_zero 
     1413            _add_algo[key] = an_addsub_zero 
     1414            continue 
     1415        if a == 'rational' and b == 'rational': 
     1416            _mul_algo[key] = an_muldiv_rational 
     1417            _add_algo[key] = an_addsub_rational 
     1418            continue 
     1419        if b == 'rational': 
     1420            a1, b1 = b, a 
     1421        else: 
     1422            a1, b1 = a, b 
     1423        if a1 == 'rational': 
     1424            if b1 == 'imaginary': 
     1425                _mul_algo[key] = an_muldiv_rootunity 
     1426                _add_algo[key] = an_addsub_gaussian 
     1427                continue 
     1428            if b1 == 'gaussian': 
     1429                _mul_algo[key] = an_muldiv_gaussian 
     1430                _add_algo[key] = an_addsub_gaussian 
     1431                continue 
     1432            if b1 == 'rootunity': 
     1433                _mul_algo[key] = an_muldiv_rootunity 
     1434                _add_algo[key] = an_addsub_expr 
     1435                continue 
     1436            if b1 == 'element': 
     1437                _mul_algo[key] = an_muldiv_element 
     1438                _add_algo[key] = an_addsub_element 
     1439                continue 
     1440        if b1 == 'imaginary': 
     1441            a1, b1 = b1, a1 
     1442        if a1 == 'imaginary': 
     1443            if b1 == 'imaginary' or b1 == 'rootunity': 
     1444                _mul_algo[key] = an_muldiv_rootunity 
     1445                _add_algo[key] = an_addsub_rootunity 
     1446                continue 
     1447            if b1 == 'gaussian': 
     1448                _mul_algo[key] = an_muldiv_gaussian 
     1449                _add_algo[key] = an_addsub_gaussian 
     1450                continue 
     1451        if a1 == 'gaussian' and b1 == 'gaussian': 
     1452            _mul_algo[key] = an_muldiv_gaussian 
     1453            _add_algo[key] = an_addsub_gaussian 
     1454            continue 
     1455        if a1 == 'rootunity' and b1 == 'rootunity': 
     1456            _mul_algo[key] = an_muldiv_rootunity 
     1457            _add_algo[key] = an_addsub_rootunity 
     1458            continue 
     1459        if a1 == 'element' and b1 == 'element': 
     1460            _mul_algo[key] = an_muldiv_element 
     1461            _add_algo[key] = an_addsub_element 
     1462            continue 
     1463        _mul_algo[key] = an_muldiv_expr 
     1464        _add_algo[key] = an_addsub_expr 
     1465 
     1466class ANDescr(SageObject): 
    8251467    """ 
    826     An AlgebraicRealNumber is a wrapper around an AlgebraicRealNumberDescr object. 
    827     AlgebraicRealNumberDescr is an abstract base class, which should never 
     1468    An AlgebraicNumber or AlgebraicReal is a wrapper around an ANDescr object. 
     1469    ANDescr is an abstract base class, which should never 
    8281470    be directly instantiated; its concrete subclasses are 
    829     AlgebraicRealNumberRational, AlgebraicRealNumberExpression, 
    830     AlgebraicRealNumberRoot, and AlgebraicRealNumberExtensionElement. 
    831     AlgebraicRealNumberDescr and all of its subclasses are private, and 
     1471    ANRational, ANBinaryExpr, ANUnaryExpr, ANRootOfUnity, 
     1472    ANRoot, and ANExtensionElement. 
     1473    ANDescr and all of its subclasses are private, and 
    8321474    should not be used directly.     
    8331475    """ 
    8341476    def is_exact(self): 
    8351477        """ 
    836         Returns True if self is an AlgebraicRealNumberRational or an 
    837         AlgebraicRealNumberExtensionElement. 
    838  
    839         EXAMPLES: 
    840             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRational 
    841             sage: AlgebraicRealNumberRational(1/2).is_exact() 
     1478        Returns True if self is an ANRational, ANRootOfUnity, or 
     1479        ANExtensionElement. 
     1480 
     1481        EXAMPLES: 
     1482            sage: from sage.rings.algebraic_real import ANRational 
     1483            sage: ANRational(1/2).is_exact() 
    8421484            True 
     1485            sage: QQbar(3+I)._descr.is_exact() 
     1486            True 
     1487            sage: QQbar.zeta(17)._descr.is_exact() 
     1488            True 
    8431489        """ 
    8441490        return False 
     
    8461492    def is_rational(self): 
    8471493        """ 
    848         Returns True if self is an AlgebraicRealNumberRational or 
    849         an AlgebraicRealNumberExtensionElement which is actually rational. 
    850  
    851         EXAMPLES: 
    852             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRational 
    853             sage: AlgebraicRealNumberRational(3/7).is_rational() 
     1494        Returns True if self is an ANRational object.  (Note that 
     1495        the constructors for ANExtensionElement and ANRootOfUnity 
     1496        will actually return ANRational objects for rational numbers.) 
     1497 
     1498        EXAMPLES: 
     1499            sage: from sage.rings.algebraic_real import ANRational 
     1500            sage: ANRational(3/7).is_rational() 
    8541501            True 
    8551502        """ 
     
    8581505    def is_field_element(self): 
    8591506        """ 
    860         Returns True if self is an AlgebraicRealNumberExtensionElement. 
    861  
    862             sage: from sage.rings.algebraic_real import AlgebraicRealNumberExtensionElement, AlgebraicRealNumberRoot, AlgebraicGenerator 
     1507        Returns True if self is an ANExtensionElement. 
     1508 
     1509            sage: from sage.rings.algebraic_real import ANExtensionElement, ANRoot, AlgebraicGenerator 
    8631510            sage: _.<y> = QQ['y'] 
    864             sage: x = polygen(AA) 
     1511            sage: x = polygen(QQbar) 
    8651512            sage: nf2 = NumberField(y^2 - 2, name='a', check=False) 
    866             sage: root2 = AlgebraicRealNumberRoot(x^2 - 2, RIF(1, 2)) 
     1513            sage: root2 = ANRoot(x^2 - 2, RIF(1, 2)) 
    8671514            sage: gen2 = AlgebraicGenerator(nf2, root2) 
    868             sage: sqrt2 = AlgebraicRealNumberExtensionElement(gen2, nf2.gen()) 
     1515            sage: sqrt2 = ANExtensionElement(gen2, nf2.gen()) 
    8691516            sage: sqrt2.is_field_element() 
    8701517            True 
     
    8721519        return False 
    8731520 
    874 class AlgebraicRealNumberRational(AlgebraicRealNumberDescr): 
     1521    def neg(self, n): 
     1522        return ANUnaryExpr(n, '-') 
     1523 
     1524    def invert(self, n): 
     1525        return ANUnaryExpr(n, '~') 
     1526 
     1527    def abs(self, n): 
     1528        return ANUnaryExpr(n, 'abs') 
     1529 
     1530    def real(self, n): 
     1531        if self.is_complex(): 
     1532            return ANUnaryExpr(n, 'real') 
     1533        else: 
     1534            return self 
     1535 
     1536    def imag(self, n): 
     1537        if self.is_complex(): 
     1538            return ANUnaryExpr(n, 'imag') 
     1539        else: 
     1540            return ANRational(0) 
     1541 
     1542    def conjugate(self, n): 
     1543        if self.is_complex(): 
     1544            return ANUnaryExpr(n, 'conjugate') 
     1545        else: 
     1546            return self 
     1547 
     1548    def norm(self, n): 
     1549        if self.is_complex(): 
     1550            return ANUnaryExpr(n, 'norm') 
     1551        else: 
     1552            return (n*n)._descr 
     1553 
     1554class AlgebraicNumber_base(sage.structure.element.FieldElement): 
    8751555    """ 
    876     The subclass of AlgebraicRealNumberDescr that represents an arbitrary 
    877     rational.  This class is private, and should not be used directly. 
    878     """ 
    879  
    880     def __init__(self, x): 
    881         """ 
    882         TESTS: 
    883             sage: polygen(AA) / int(3) 
    884             1/3*x 
    885             sage: AA(int(7)) / AA(long(2)) 
    886             7/2 
    887         """ 
    888         if isinstance(x, (sage.rings.integer.Integer, 
    889                           sage.rings.rational.Rational)): 
    890             self._value = x 
    891         elif isinstance(x, (int, long)): 
    892             self._value = ZZ(x) 
    893         else: 
    894             raise TypeError, "Illegal initializer for algebraic number rational" 
    895  
    896     def _repr_(self): 
    897         return repr(self._value) 
    898  
    899     def interval_fast(self, rif): 
    900         return rif(self._value) 
    901  
    902     def is_rational(self): 
    903         return True 
    904  
    905     def rational_value(self): 
    906         return self._value 
    907  
    908     def exactify(self): 
    909         return self 
    910  
    911     def is_exact(self): 
    912         return True 
    913  
    914     def minpoly(self): 
    915         return QQx_x - self._value 
    916  
    917 class AlgebraicRealNumberExpression(AlgebraicRealNumberDescr): 
    918     """ 
    919     The subclass of AlgebraicRealNumberDescr that represents the sum, 
    920     difference, product, or quotient of two algebraic numbers. 
    921     This class is private, and should not be used directly. 
    922     """ 
    923  
    924     def __init__(self, left, right, op): 
    925         """ 
    926         op can be '+', '-', '*', or '/'. 
    927         left and right are algebraic numbers. 
    928         If op is '-', then left can be None (in which case it is taken to 
    929         mean 0). 
    930         if op is '/', then left can be None (in which case it is taken to 
    931         mean 1). 
    932  
    933         EXAMPLES: 
    934             sage: from sage.rings.algebraic_real import AlgebraicRealNumberExpression 
    935             sage: AlgebraicRealNumberExpression(AA(1/3), AA(1/2), '+') 
    936             [0.83333333333333325 .. 0.83333333333333338] (1/3 + 1/2) 
    937             sage: AlgebraicRealNumberExpression(AA(1/3), AA(1/2), '-') 
    938             [-0.16666666666666669 .. -0.16666666666666662] (1/3 - 1/2) 
    939             sage: AlgebraicRealNumberExpression(AA(1/3), AA(1/2), '*') 
    940             [0.16666666666666665 .. 0.16666666666666669] (1/3 * 1/2) 
    941             sage: AlgebraicRealNumberExpression(AA(1/3), AA(1/2), '/') 
    942             [0.66666666666666662 .. 0.66666666666666675] (1/3 / 1/2) 
    943             sage: AlgebraicRealNumberExpression(None, AA(1/2), '-') 
    944             [-0.50000000000000000 .. -0.50000000000000000] (None - 1/2) 
    945             sage: AlgebraicRealNumberExpression(None, AA(1/2), '/') 
    946             [2.0000000000000000 .. 2.0000000000000000] (None / 1/2) 
    947         """ 
    948         self._left = left 
    949         self._right = right 
    950         self._op = op 
    951  
    952     def _repr_(self): 
    953         return '%s (%s %s %s)'%(self.interval_fast(RIF), self._left, self._op, self._right) 
    954  
    955     def interval_fast(self, field): 
    956         """ 
    957         Returns an interval containing self with precision given by the 
    958         field argument (which must be a RealIntervalField).  Note that 
    959         the result may not be a minimal-width interval. 
    960  
    961         EXAMPLES: 
    962             sage: from sage.rings.algebraic_real import AlgebraicRealNumberExpression 
    963             sage: five_sixths = AlgebraicRealNumberExpression(AA(1/2), AA(1/3), '+') 
    964             sage: five_sixths.interval_fast(RealIntervalField(4)) 
    965             [0.812 .. 0.875] 
    966             sage: five_sixths.interval_fast(RealIntervalField(70)) 
    967             [0.83333333333333333333305 .. 0.83333333333333333333390] 
    968         """ 
    969         op = self._op 
    970         if op == '+': 
    971             return self._left.interval_fast(field) + self._right.interval_fast(field) 
    972         if op == '-': 
    973             if self._left is None: 
    974                 return -self._right.interval_fast(field) 
    975             else: 
    976                 return self._left.interval_fast(field) - self._right.interval_fast(field) 
    977         if op == '*': 
    978             return self._left.interval_fast(field) * self._right.interval_fast(field) 
    979         if op == '/': 
    980             # Note: this may trigger exact computation 
    981             if self._right.sign() == 0: 
    982                 raise ZeroDivisionError, 'Division by zero in algebraic number field' 
    983             if self._left is None: 
    984                 return ~self._right.interval_fast(field) 
    985             else: 
    986                 return self._left.interval_fast(field) / self._right.interval_fast(field) 
    987         raise ValueError, 'Illegal operation for AlgebraicRealNumberExpression' 
    988  
    989     def exactify(self): 
    990         """ 
    991         Return a new exact AlgebraicRealNumberDescr with the same value as self. 
    992  
    993         EXAMPLES: 
    994             sage: from sage.rings.algebraic_real import AlgebraicRealNumberExpression 
    995             sage: five_sixths = AlgebraicRealNumberExpression(AA(1/2), AA(1/3), '+') 
    996             sage: five_sixths.exactify() 
    997             5/6 
    998         """ 
    999         op = self._op 
    1000         left = self._left 
    1001         if left is None: 
    1002             if op == '-': 
    1003                 left = AA(0) 
    1004             else: 
    1005                 left = AA(1) 
    1006         left.exactify() 
    1007  
    1008         right = self._right 
    1009         right.exactify() 
    1010          
    1011         gen = left._exact_field().union(right._exact_field()) 
    1012  
    1013         # print gen 
    1014         # print left 
    1015         # print right 
    1016  
    1017         left_value = gen(left._exact_value()) 
    1018         right_value = gen(right._exact_value()) 
    1019  
    1020         if op == '+': 
    1021             value = left_value + right_value 
    1022         if op == '-': 
    1023             value = left_value - right_value 
    1024         if op == '*': 
    1025             value = left_value * right_value 
    1026         if op == '/': 
    1027             value = left_value / right_value 
    1028  
    1029         # print gen 
    1030         # print left, left_value 
    1031         # print right, right_value 
    1032  
    1033         if gen.is_unit(): 
    1034             return AlgebraicRealNumberRational(value) 
    1035         else: 
    1036             return AlgebraicRealNumberExtensionElement(gen, value) 
    1037  
    1038  
    1039 class AlgebraicRealNumber(sage.structure.element.FieldElement): 
    1040     """ 
    1041     An algebraic real (a real number which is the zero of a polynomial 
    1042     in ZZ[x]). 
    1043  
    1044     AlgebraicRealNumber objects can be created using AA (== AlgebraicRealNumberField()); 
    1045     either by coercing a rational, or by using the AA.polynomial_root() 
    1046     method to construct a particular root of a polynomial with algebraic 
    1047     coefficients.  Also, AlgebraicRealNumber is closed under addition, 
    1048     subtraction, multiplication, division (except by 0), and rational 
    1049     powers (including roots), except for negative numbers and powers 
    1050     with an even denominator. 
    1051  
    1052     AlgebraicRealNumber objects can be approximated to any desired precision. 
    1053     They can be compared exactly; if the two numbers are very close, 
    1054     this may require exact computation, which can be extremely slow. 
     1556    This is the common base class for algebraic numbers (complex 
     1557    numbers which are the zero of a polynomial in ZZ[x]) and algebraic 
     1558    reals (algebraic numbers which happen to be real). 
     1559 
     1560    AlgebraicNumber objects can be created using QQbar (== 
     1561    AlgebraicNumberField()), and AlgebraicReal objects can be created 
     1562    using AA (== AlgebraicRealField()).  They can be created either by 
     1563    coercing a rational or a symbolic expression, or by using the 
     1564    QQbar.polynomial_root() or AA.polynomial_root() method to 
     1565    construct a particular root of a polynomial with algebraic 
     1566    coefficients.  Also, AlgebraicNumber and AlgebraicReal are closed 
     1567    under addition, subtraction, multiplication, division (except by 
     1568    0), and rational powers (including roots), except that for a 
     1569    negative AlgebraicReal, taking a power with an even denominator returns 
     1570    an AlgebraicNumber instead of an AlgebraicReal. 
     1571 
     1572    AlgebraicNumber and AlgebraicReal objects can be approximated to 
     1573    any desired precision.  They can be compared exactly; if the two 
     1574    numbers are very close, or are equal, this may require exact 
     1575    computation, which can be extremely slow. 
    10551576 
    10561577    As long as exact computation is not triggered, computation with 
    1057     algebraic reals should not be too much slower than computation with 
     1578    algebraic numbers should not be too much slower than computation with 
    10581579    intervals.  As mentioned above, exact computation is triggered 
    1059     when comparing two algebraic reals which are very close together. 
     1580    when comparing two algebraic numbers which are very close together. 
    10601581    This can be an explicit comparison in user code, but the following 
    10611582    list of actions (not necessarily complete) can also trigger exact 
    10621583    computation: 
    1063     Dividing by an algebraic real which is very close to 0. 
    1064     Using an algebraic real which is very close to 0 as the leading coefficient 
    1065     in a polynomial. 
    1066     Taking a root of an alebraic real which is very close to 0. 
     1584    Dividing by an algebraic number which is very close to 0. 
     1585    Using an algebraic number which is very close to 0 as the leading 
     1586    coefficient in a polynomial. 
     1587    Taking a root of an alebraic number which is very close to 0. 
    10671588 
    10681589    The exact definition of "very close" is subject to change; currently, 
    10691590    we compute our best approximation of the two numbers using 128-bit 
    10701591    arithmetic, and see if that's sufficient to decide the comparison. 
    1071     Note that comparing two algebraic reals which are actually equal will 
    1072     always trigger exact computation. 
     1592    Note that comparing two algebraic numbers which are actually equal will 
     1593    always trigger exact computation, unless they are actually the same object. 
    10731594 
    10741595    EXAMPLES: 
    1075         sage: sqrt(AA(2)) 
     1596        sage: sqrt(QQbar(2)) 
    10761597        [1.4142135623730949 .. 1.4142135623730952] 
    1077         sage: sqrt(AA(2))^2 == 2 
     1598        sage: sqrt(QQbar(2))^2 == 2 
    10781599        True 
    1079         sage: x = polygen(AA) 
    1080         sage: phi = AA.polynomial_root(x^2 - x - 1, RIF(0, 2)) 
     1600        sage: x = polygen(QQbar) 
     1601        sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(1, 2)) 
    10811602        sage: phi 
    10821603        [1.6180339887498946 .. 1.6180339887498950] 
    10831604        sage: phi^2 == phi+1 
    10841605        True 
     1606        sage: AA(sqrt(65537)) 
     1607        [256.00195311754941 .. 256.00195311754948] 
    10851608    """ 
    10861609 
    1087     def __init__(self, x): 
     1610    def __init__(self, parent, x): 
    10881611        """ 
    10891612        Initialize an algebraic number.  The argument must be either 
    1090         a rational number or a subclass of AlgebraicRealNumberDescr. 
    1091  
    1092         sage: from sage.rings.algebraic_real import AlgebraicRealNumberExpression 
    1093         sage: AlgebraicRealNumber(22/7) 
     1613        a rational number, a Gaussian rational, or a subclass of ANDescr. 
     1614 
     1615        sage: from sage.rings.algebraic_real import ANRootOfUnity 
     1616        sage: AlgebraicReal(22/7) 
    10941617        22/7 
    1095         sage: AlgebraicRealNumber(AlgebraicRealNumberExpression(AA(1/2), AA(1/5), '+')) 
    1096         [0.69999999999999995 .. 0.70000000000000007] 
    1097         """ 
    1098         sage.structure.element.FieldElement.__init__(self, AA) 
     1618        sage: AlgebraicNumber(ANRootOfUnity(2/5, 1)) 
     1619        [-0.80901699437494746 .. -0.80901699437494734] + [0.58778525229247302 .. 0.58778525229247314]*I 
     1620        """ 
     1621        sage.structure.element.FieldElement.__init__(self, parent) 
    10991622        if isinstance(x, (int, long, sage.rings.integer.Integer, 
    11001623                          sage.rings.rational.Rational)): 
    1101             self._descr = AlgebraicRealNumberRational(x) 
    1102         elif isinstance(x, (AlgebraicRealNumberDescr)): 
     1624            self._descr = ANRational(x) 
     1625        elif isinstance(x, (ANDescr)): 
    11031626            self._descr = x 
     1627        elif parent is QQbar and \ 
     1628                 isinstance(x, NumberFieldElement_quadratic) and \ 
     1629                 list(x.parent().polynomial()) == [1, 0, 1]: 
     1630            self._descr = ANExtensionElement(QQbar_I_generator, QQbar_I_nf(x)) 
    11041631        else: 
    11051632            raise TypeError, "Illegal initializer for algebraic number" 
    11061633 
    1107         self._value = self._descr.interval_fast(AA.default_interval_field()) 
     1634        self._value = self._descr._interval_fast(64) 
    11081635         
    11091636    def _repr_(self): 
     1637        """ 
     1638        Returns the print representation of this number. 
     1639 
     1640        EXAMPLES: 
     1641            sage: AA(22/7) 
     1642            22/7 
     1643            sage: QQbar(1/3 + 2/7*I) 
     1644            2/7*I + 1/3 
     1645            sage: QQbar.zeta(4) + 5 
     1646            I + 5 
     1647            sage: QQbar.zeta(17) 
     1648            [0.93247222940435570 .. 0.93247222940435582] + [0.36124166618715292 .. 0.36124166618715298]*I 
     1649            sage: AA(19).sqrt() 
     1650            [4.3588989435406730 .. 4.3588989435406740] 
     1651        """ 
    11101652        if self._descr.is_rational(): 
    11111653            return repr(self._descr) 
    1112         return repr(RIF(self._value)) 
     1654        if isinstance(self._descr, ANRootOfUnity) and self._descr._angle == QQ_1_4: 
     1655            return '%s*I'%self._descr._scale 
     1656        if isinstance(self._descr, ANExtensionElement) and self._descr._generator is QQbar_I_generator: 
     1657            return repr(self._descr._value) 
     1658        if self.parent() is QQbar: 
     1659            return repr(CIF(self._value)) 
     1660        else: 
     1661            return repr(RIF(self._value)) 
    11131662 
    11141663    def _mul_(self, other): 
     1664        """ 
     1665        TESTS: 
     1666            sage: AA(sqrt(2)) * AA(sqrt(8)) 
     1667            [3.9999999999999995 .. 4.0000000000000009] 
     1668        """ 
    11151669        sd = self._descr 
    11161670        od = other._descr 
    1117         if sd.is_rational() and od.is_rational(): 
    1118             value = sd.rational_value() * od.rational_value() 
    1119             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1120         elif sd.is_field_element() and \ 
    1121                 od.is_field_element() and \ 
    1122                 sd.field_parent() == od.field_parent(): 
    1123             value = sd.field_element_value() * od.field_element_value() 
    1124             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
    1125         else: 
    1126             value = AlgebraicRealNumberExpression(self, other, '*') 
    1127             return AlgebraicRealNumber(value) 
     1671        sdk = sd.kind() 
     1672        odk = od.kind() 
     1673        return type(self)(_mul_algo[sdk, odk](self, other, False)) 
    11281674 
    11291675    def _div_(self, other): 
     1676        """ 
     1677        TESTS: 
     1678            sage: AA(sqrt(2)) / AA(sqrt(8)) 
     1679            [0.49999999999999994 .. 0.50000000000000012] 
     1680        """ 
    11301681        sd = self._descr 
    11311682        od = other._descr 
    1132         if sd.is_rational() and od.is_rational(): 
    1133             value = sd.rational_value() / od.rational_value() 
    1134             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1135         elif sd.is_field_element() and \ 
    1136                 od.is_field_element() and \ 
    1137                 sd.field_parent() == od.field_parent(): 
    1138             value = sd.field_element_value() / od.field_element_value() 
    1139             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
    1140         else: 
    1141             value = AlgebraicRealNumberExpression(self, other, '/') 
    1142             return AlgebraicRealNumber(value) 
     1683        sdk = sd.kind() 
     1684        odk = od.kind() 
     1685        return type(self)(_mul_algo[sdk, odk](self, other, True)) 
    11431686 
    11441687    def __invert__(self): 
     1688        """ 
     1689        TESTS: 
     1690            sage: ~AA(sqrt(~2)) 
     1691            [1.4142135623730949 .. 1.4142135623730952] 
     1692        """ 
    11451693        sd = self._descr 
    1146         if sd.is_rational: 
    1147             value = ~sd.rational_value() 
    1148             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1149         elif sd.is_field_element(): 
    1150             value = ~sd.field_element_value() 
    1151             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
    1152         else: 
    1153             value = AlgebraicRealNumberExpression(None, self, '/') 
    1154             return AlgebraicRealNumber(value) 
     1694        return type(self)(self._descr.invert(self)) 
    11551695 
    11561696    def _add_(self, other): 
     1697        """ 
     1698        TESTS: 
     1699            sage: x = polygen(ZZ) 
     1700            sage: rt1, rt2 = (x^2 - x - 1).roots(ring=AA, multiplicities=False) 
     1701            sage: rt1 + rt2 
     1702            [0.99999999999999988 .. 1.0000000000000003] 
     1703        """ 
    11571704        sd = self._descr 
    11581705        od = other._descr 
    1159         if sd.is_rational() and od.is_rational(): 
    1160             value = sd.rational_value() + od.rational_value() 
    1161             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1162         elif sd.is_field_element() and \ 
    1163                 od.is_field_element() and \ 
    1164                 sd.field_parent() == od.field_parent(): 
    1165             value = sd.field_element_value() + od.field_element_value() 
    1166             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
    1167         else: 
    1168             value = AlgebraicRealNumberExpression(self, other, '+') 
    1169             return AlgebraicRealNumber(value) 
     1706        sdk = sd.kind() 
     1707        odk = od.kind() 
     1708        return type(self)(_add_algo[sdk, odk](self, other, False)) 
    11701709 
    11711710    def _sub_(self, other): 
     1711        """ 
     1712        TESTS: 
     1713            sage: AA(golden_ratio) * 2 - AA(5).sqrt() 
     1714            [0.99999999999999988 .. 1.0000000000000003] 
     1715        """ 
    11721716        sd = self._descr 
    11731717        od = other._descr 
    1174         if sd.is_rational() and od.is_rational(): 
    1175             value = sd.rational_value() - od.rational_value() 
    1176             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1177         elif sd.is_field_element() and \ 
    1178                 od.is_field_element() and \ 
    1179                 sd.field_parent() == od.field_parent(): 
    1180             value = sd.field_element_value() - od.field_element_value() 
    1181             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
     1718        sdk = sd.kind() 
     1719        odk = od.kind() 
     1720        return type(self)(_add_algo[sdk, odk](self, other, True)) 
     1721 
     1722    def _neg_(self): 
     1723        """ 
     1724        TESTS: 
     1725            sage: -QQbar(I) 
     1726            -1*I 
     1727        """ 
     1728        return type(self)(self._descr.neg(self)) 
     1729 
     1730    def __abs__(self): 
     1731        """ 
     1732        TESTS: 
     1733            sage: abs(AA(sqrt(2) - sqrt(3))) 
     1734            [0.31783724519578221 .. 0.31783724519578227] 
     1735            sage: abs(QQbar(3+4*I)) 
     1736            5 
     1737        """ 
     1738        return AlgebraicReal(self._descr.abs(self)) 
     1739 
     1740    def __hash__(self): 
     1741        """ 
     1742        Compute a hash code for this number (equal algebraic numbers will 
     1743        have the same hash code, different algebraic numbers are likely 
     1744        to have different hash codes). 
     1745 
     1746        This may trigger exact computation, but that is very unlikely. 
     1747 
     1748        TESTS: 
     1749        The hash code is stable, even when the representation changes. 
     1750            sage: two = QQbar(4).nth_root(4)^2 
     1751            sage: two 
     1752            [1.9999999999999997 .. 2.0000000000000005] 
     1753            sage: h1 = hash(two) 
     1754            sage: two == 2 
     1755            True 
     1756            sage: two 
     1757            2 
     1758            sage: h2 = hash(two) 
     1759            sage: h1 == h2 
     1760            True 
     1761 
     1762            sage: h1 = hash(QQbar.zeta(6)) 
     1763            sage: h2 = hash(QQbar(1/2 + I*sqrt(3)/2)) 
     1764            sage: h1 == h2             
     1765            True 
     1766 
     1767        Unfortunately, the hash code for algebraic numbers which are close 
     1768        enough to each other are the same.  (This is inevitable, if 
     1769        equal algebraic reals give the same hash code and hashing does 
     1770        not always trigger exact computation.) 
     1771            sage: h1 = hash(QQbar(0)) 
     1772            sage: h2 = hash(QQbar(1/2^100)) 
     1773            sage: hash(h1) == hash(h2) 
     1774            True 
     1775 
     1776        """ 
     1777 
     1778        # The only way I can think of to hash algebraic numbers without 
     1779        # always triggering exact computation is to use interval_exact(). 
     1780        # However, interval_exact() always triggers exact computation 
     1781        # if the number is exactly representable in floating point, which 
     1782        # is presumably not too unlikely (algebraic reals like 0, 1/2, 
     1783        # 1, or 2 are presumably not uncommon). 
     1784 
     1785        # So I modify the algebraic real by adding 1/123456789 to it before 
     1786        # calling interval_exact().  Then, exact computation will be triggered 
     1787        # by algebraic reals which are sufficiently close to 
     1788        # (some floating point number minus 1/123456789).  Hopefully, 
     1789        # -1/123456789 comes up in algebraic real computations far less 
     1790        # often than 0 does.  Algebraic numbers have a similar offset added, 
     1791        # with an additional complex component of 1/987654321*I. 
     1792 
     1793        # All of this effort to avoid exact computation is probably wasted, 
     1794        # anyway... in almost all uses of hash codes, if the hash codes 
     1795        # match, the next step is to compare for equality; and comparing 
     1796        # for equality often requires exact computation.  (If a==b, 
     1797        # then checking a==b requires exact computation unless (a is b).) 
     1798 
     1799        if self.parent() is AA: 
     1800            return hash((self + AA_hash_offset).interval_exact(RIF)) 
    11821801        else: 
    1183             value = AlgebraicRealNumberExpression(self, other, '-') 
    1184             return AlgebraicRealNumber(value) 
    1185  
    1186     def _neg_(self): 
     1802            return hash((self + QQbar_hash_offset).interval_exact(CIF)) 
     1803 
     1804    def sqrt(self): 
     1805        """ 
     1806        Return the square root of this number. 
     1807 
     1808        EXAMPLES: 
     1809            sage: AA(2).sqrt() 
     1810            [1.4142135623730949 .. 1.4142135623730952] 
     1811            sage: QQbar(I).sqrt() 
     1812            [0.70710678118654746 .. 0.70710678118654758] + [0.70710678118654746 .. 0.70710678118654758]*I 
     1813        """ 
     1814        return self.__pow__(~ZZ(2)) 
     1815 
     1816    def nth_root(self, n): 
     1817        """ 
     1818        Return the nth root of this number. 
     1819 
     1820        Note that for odd n and negative real numbers, AlgebraicReal 
     1821        and AlgebraicNumber values give different answers: AlgebraicReal 
     1822        values prefer real results, and AlgebraicNumber values 
     1823        return the principle root. 
     1824 
     1825        EXAMPLES: 
     1826            sage: AA(-8).nth_root(3) 
     1827            -2 
     1828            sage: QQbar(-8).nth_root(3) 
     1829            [0.99999999999999988 .. 1.0000000000000003] + [1.7320508075688771 .. 1.7320508075688775]*I 
     1830            sage: QQbar.zeta(12).nth_root(15) 
     1831            [0.99939082701909565 .. 0.99939082701909577] + [0.034899496702500969 .. 0.034899496702500977]*I 
     1832        """ 
     1833        return self.__pow__(~ZZ(n)) 
     1834 
     1835    def exactify(self): 
     1836        """ 
     1837        Compute an exact representation for this number. 
     1838 
     1839        EXAMPLES: 
     1840            sage: two = QQbar(4).nth_root(4)^2 
     1841            sage: two 
     1842            [1.9999999999999997 .. 2.0000000000000005] 
     1843            sage: two.exactify() 
     1844            sage: two 
     1845            2 
     1846        """ 
     1847        od = self._descr 
     1848        if od.is_exact(): return 
     1849        self._descr = self._descr.exactify() 
     1850        new_val = self._descr._interval_fast(self.parent().default_interval_prec()) 
     1851        if is_RealIntervalFieldElement(new_val) and is_ComplexIntervalFieldElement(self._value): 
     1852            self._value = self._value.real().intersection(new_val) 
     1853        elif is_RealIntervalFieldElement(self._value) and is_ComplexIntervalFieldElement(new_val): 
     1854            self._value = self._value.intersection(new_val.real()) 
     1855        else: 
     1856            self._value = self._value.intersection(new_val) 
     1857 
     1858    def _exact_field(self): 
     1859        """ 
     1860        Returns a generator for a number field that includes this number 
     1861        (not necessarily the smallest such number field). 
     1862 
     1863        EXAMPLES: 
     1864            sage: QQbar(2)._exact_field() 
     1865            Trivial generator 
     1866            sage: (sqrt(QQbar(2)) + sqrt(QQbar(19)))._exact_field() 
     1867            Number Field in a with defining polynomial y^4 - 20*y^2 + 81 with a in [3.7893137826710354 .. 3.7893137826710360] 
     1868            sage: (QQbar(7)^(3/5))._exact_field() 
     1869            Number Field in a with defining polynomial y^5 - 7 with a in [1.4757731615945519 .. 1.4757731615945522] 
     1870        """ 
     1871 
    11871872        sd = self._descr 
    1188         if sd.is_rational(): 
    1189             value = -sd.rational_value() 
    1190             return AlgebraicRealNumber(AlgebraicRealNumberRational(value)) 
    1191         elif sd.is_field_element(): 
    1192             value = -sd.field_element_value() 
    1193             return AlgebraicRealNumber(AlgebraicRealNumberExtensionElement(sd.field_parent(), value)) 
     1873        if sd.is_exact(): 
     1874            return sd.generator() 
     1875        self.exactify() 
     1876        return self._exact_field() 
     1877 
     1878    def _exact_value(self): 
     1879        """ 
     1880        Returns an ANRational, an ANRootOfUnity, or an 
     1881        ANExtensionElement representing this value. 
     1882 
     1883        EXAMPLES: 
     1884            sage: QQbar(2)._exact_value() 
     1885            2 
     1886            sage: (sqrt(QQbar(2)) + sqrt(QQbar(19)))._exact_value() 
     1887            1/9*a^3 + a^2 - 11/9*a - 10 where a^4 - 20*a^2 + 81 = 0 and a in [3.7893137826710354 .. 3.7893137826710360] 
     1888            sage: (QQbar(7)^(3/5))._exact_value() 
     1889            a^3 where a^5 - 7 = 0 and a in [1.4757731615945519 .. 1.4757731615945522] 
     1890        """ 
     1891        sd = self._descr 
     1892        if sd.is_exact(): 
     1893            return sd 
     1894        self.exactify() 
     1895        return self._descr 
     1896 
     1897    def _more_precision(self): 
     1898        """ 
     1899        Recompute the interval bounding this number with higher-precision 
     1900        interval arithmetic. 
     1901 
     1902        EXAMPLES: 
     1903            sage: rt2 = sqrt(QQbar(2)) 
     1904            sage: rt2._value 
     1905            [1.41421356237309504876 .. 1.41421356237309504888] 
     1906            sage: rt2._more_precision() 
     1907            sage: rt2._value 
     1908            [1.414213562373095048801688724209698078568 .. 1.414213562373095048801688724209698078575] 
     1909            sage: rt2._more_precision() 
     1910            sage: rt2._value 
     1911            [1.414213562373095048801688724209698078569671875376948073176679737990732478462101 .. 1.414213562373095048801688724209698078569671875376948073176679737990732478462120] 
     1912        """ 
     1913        prec = self._value.prec() 
     1914        self._value = self._descr._interval_fast(prec*2) 
     1915 
     1916    def minpoly(self): 
     1917        """ 
     1918        Compute the minimal polynomial of this algebraic number. 
     1919        The minimal polynomial is the monic polynomial of least degree 
     1920        having this number as a root; it is unique. 
     1921 
     1922        EXAMPLES: 
     1923            sage: QQbar(4).sqrt().minpoly() 
     1924            x - 2 
     1925            sage: ((QQbar(2).nth_root(4))^2).minpoly() 
     1926            x^2 - 2 
     1927            sage: v = sqrt(QQbar(2)) + sqrt(QQbar(3)); v 
     1928            [3.1462643699419721 .. 3.1462643699419726] 
     1929            sage: p = v.minpoly(); p 
     1930            x^4 - 10*x^2 + 1 
     1931            sage: p(RR(v.real())) 
     1932            0.0000000000000131006316905768 
     1933        """ 
     1934        try: 
     1935            return self._minimal_polynomial 
     1936        except AttributeError: 
     1937            self.exactify() 
     1938            self._minimal_polynomial = self._descr.minpoly() 
     1939            return self._minimal_polynomial 
     1940 
     1941    def degree(self): 
     1942        """ 
     1943        Return the degree of this algebraic number (the degree of its 
     1944        minimal polynomial, or equivalently, the degree of the smallest 
     1945        algebraic extension of the rationals containing this number). 
     1946 
     1947        EXAMPLES: 
     1948            sage: QQbar(5/3).degree() 
     1949            1 
     1950            sage: sqrt(QQbar(2)).degree() 
     1951            2 
     1952            sage: QQbar(17).nth_root(5).degree() 
     1953            5 
     1954            sage: sqrt(3+sqrt(QQbar(8))).degree() 
     1955            2 
     1956        """ 
     1957        return self.minpoly().degree() 
     1958 
     1959    def interval_fast(self, field): 
     1960        """ 
     1961        Given a RealIntervalField, compute the value of this number 
     1962        using interval arithmetic of at least the precision of the field, 
     1963        and return the value in that field.  (More precision may be used 
     1964        in the computation.)  The returned interval may be arbitrarily 
     1965        imprecise, if this number is the result of a sufficiently long 
     1966        computation chain. 
     1967 
     1968        EXAMPLES: 
     1969            sage: x = AA(2).sqrt() 
     1970            sage: x.interval_fast(RIF) 
     1971            [1.4142135623730949 .. 1.4142135623730952] 
     1972            sage: x.interval_fast(RealIntervalField(200)) 
     1973            [1.4142135623730950488016887242096980785696718753769480731766796 .. 1.4142135623730950488016887242096980785696718753769480731766809] 
     1974            sage: x = QQbar(I).sqrt() 
     1975            sage: x.interval_fast(CIF) 
     1976            [0.70710678118654746 .. 0.70710678118654758] + [0.70710678118654746 .. 0.70710678118654758]*I 
     1977            sage: x.interval_fast(RIF) 
     1978            Traceback (most recent call last): 
     1979            ... 
     1980            TypeError: Unable to convert number to real interval. 
     1981        """ 
     1982        if field.prec() == self._value.prec(): 
     1983            return field(self._value) 
     1984        elif field.prec() > self._value.prec(): 
     1985            self._more_precision() 
     1986            return self.interval_fast(field) 
    11941987        else: 
    1195             value = AlgebraicRealNumberExpression(None, self, '-') 
    1196             return AlgebraicRealNumber(value) 
     1988            return field(self._value) 
     1989 
     1990    def interval_diameter(self, diam): 
     1991        """ 
     1992        Compute an interval representation of self with diameter() at 
     1993        most diam.  The precision of the returned value is unpredictable. 
     1994 
     1995        EXAMPLES: 
     1996            sage: AA(2).sqrt().interval_diameter(1e-10) 
     1997            [1.41421356237309504876 .. 1.41421356237309504888] 
     1998            sage: AA(2).sqrt().interval_diameter(1e-30) 
     1999            [1.414213562373095048801688724209698078568 .. 1.414213562373095048801688724209698078575] 
     2000            sage: QQbar(2).sqrt().interval_diameter(1e-10) 
     2001            [1.41421356237309504876 .. 1.41421356237309504888] 
     2002            sage: QQbar(2).sqrt().interval_diameter(1e-30) 
     2003            [1.414213562373095048801688724209698078568 .. 1.414213562373095048801688724209698078575] 
     2004        """ 
     2005        if diam <= 0: 
     2006            raise ValueError, 'diameter must be positive in interval_diameter' 
     2007 
     2008        while self._value.diameter() > diam: 
     2009            self._more_precision() 
     2010 
     2011        return self._value 
     2012 
     2013    def interval(self, field): 
     2014        """ 
     2015        Given an interval field (real or complex, as appropriate) of 
     2016        precision p, compute an interval representation of self with 
     2017        diameter() at most 2^-p; then round that representation into 
     2018        the given field.  Here diameter() is relative diameter for 
     2019        intervals not containing 0, and absolute diameter for 
     2020        intervals that do contain 0; thus, if the returned interval 
     2021        does not contain 0, it has at least p-1 good bits. 
     2022 
     2023        EXAMPLES: 
     2024            sage: RIF64 = RealIntervalField(64) 
     2025            sage: x = AA(2).sqrt() 
     2026            sage: y = x*x 
     2027            sage: y = 1000 * y - 999 * y 
     2028            sage: y.interval_fast(RIF64) 
     2029            [1.99999999999999966693 .. 2.00000000000000033307] 
     2030            sage: y.interval(RIF64) 
     2031            [1.99999999999999999989 .. 2.00000000000000000022] 
     2032            sage: CIF64 = ComplexIntervalField(64) 
     2033            sage: x = QQbar.zeta(11) 
     2034            sage: x.interval_fast(CIF64) 
     2035            [0.841253532831181168808 .. 0.841253532831181168918] + [0.540640817455597581992 .. 0.540640817455597582210]*I 
     2036            sage: x.interval(CIF64) 
     2037            [0.841253532831181168808 .. 0.841253532831181168864] + [0.540640817455597582101 .. 0.540640817455597582156]*I 
     2038        """ 
     2039        target = RR(1.0) >> field.prec() 
     2040        val = self.interval_diameter(target) 
     2041        return field(val) 
     2042 
     2043class AlgebraicNumber(AlgebraicNumber_base): 
     2044    """ 
     2045    The class for algebraic numbers (complex numbers which are the roots 
     2046    of a polynomial with integer coefficients).  Much of its functionality 
     2047    is inherited from AlgebraicNumber_base. 
     2048    """ 
     2049    def __init__(self, x): 
     2050        AlgebraicNumber_base.__init__(self, QQbar, x) 
    11972051 
    11982052    def __cmp__(self, other): 
     2053        """ 
     2054        Compare two algebraic numbers, lexicographically.  (That is, 
     2055        first compare the real components; if the real componetns are 
     2056        equal, compare the imaginary components.) 
     2057 
     2058        EXAMPLES: 
     2059            sage: x = QQbar.zeta(3); x 
     2060            [-0.50000000000000012 .. -0.49999999999999994] + [0.86602540378443859 .. 0.86602540378443871]*I 
     2061            sage: cmp(QQbar(-1), x) 
     2062            -1 
     2063            sage: cmp(QQbar(-1/2), x) 
     2064            -1 
     2065            sage: cmp(QQbar(0), x) 
     2066            1 
     2067        """ 
     2068        if self is other: return 0 
     2069        rcmp = cmp(self.real(), other.real()) 
     2070        if rcmp != 0: 
     2071            return rcmp 
     2072        return cmp(self.imag(), other.imag()) 
     2073 
     2074    def __eq__(self, other): 
     2075        """ 
     2076        Test two algebraic numbers for equality. 
     2077 
     2078        EXAMPLES: 
     2079            sage: QQbar.zeta(6) == QQbar(1/2 + I*sqrt(3)/2) 
     2080            True 
     2081            sage: QQbar(I) == QQbar(I * (2^100+1)/(2^100)) 
     2082            False 
     2083        """ 
     2084        if not isinstance(other, AlgebraicNumber): 
     2085            other = self.parent()(other) 
     2086        if self is other: return True 
     2087        if other._descr.is_rational() and other._descr.rational_value() == 0: 
     2088            return not self.__nonzero__() 
     2089        if self._descr.is_rational() and self._descr.rational_value() == 0: 
     2090            return not other.__nonzero__() 
     2091        return not self._sub_(other).__nonzero__() 
     2092 
     2093    def __ne__(self, other): 
     2094        return not self.__eq__(other) 
     2095 
     2096    def __nonzero__(self): 
     2097        """ 
     2098        Check whether self is equal is nonzero.  This is fast if 
     2099        interval arithmetic proves that self is nonzero, but may be 
     2100        slow if the number actually is very close to zero. 
     2101 
     2102        EXAMPLES: 
     2103            sage: (QQbar.zeta(2) + 1).__nonzero__() 
     2104            False 
     2105            sage: (QQbar.zeta(7) / (2^500)).__nonzero__() 
     2106            True 
     2107        """ 
     2108        val = self._value 
     2109        if not val.contains_zero(): 
     2110            return True 
     2111        if self._descr.is_field_element(): 
     2112            # The ANExtensionElement constructor returns an ANRational 
     2113            # instead, if the number is zero. 
     2114            return True 
     2115        if self._descr.is_rational(): 
     2116            return self._descr.rational_value().__nonzero__() 
     2117        if self._value.prec() < 128: 
     2118            self._more_precision() 
     2119            return self.__nonzero__() 
     2120 
     2121        # Sigh... 
     2122        self.exactify() 
     2123        return self.__nonzero__() 
     2124 
     2125    def __pow__(self, e): 
     2126        """ 
     2127        self^p returns the p'th power of self (where p can be an arbitrary 
     2128        rational).  If p is (a/b), takes the principle b'th root of self, 
     2129        then takes that to the a'th power.  (Note that this differs 
     2130        from __pow__ on algebraic reals, where real roots are preferred 
     2131        over principle roots if they exist.) 
     2132 
     2133        EXAMPLES: 
     2134            sage: QQbar(2)^(1/2) 
     2135            [1.4142135623730949 .. 1.4142135623730952] 
     2136            sage: QQbar(8)^(2/3) 
     2137            4 
     2138            sage: QQbar(8)^(2/3) == 4 
     2139            True 
     2140            sage: x = polygen(QQbar) 
     2141            sage: phi = QQbar.polynomial_root(x^2 - x - 1, RIF(1, 2)) 
     2142            sage: tau = QQbar.polynomial_root(x^2 - x - 1, RIF(-1, 0)) 
     2143            sage: rt5 = QQbar(5)^(1/2) 
     2144            sage: phi^10 / rt5 
     2145            [55.003636123247410 .. 55.003636123247418] 
     2146            sage: tau^10 / rt5 
     2147            [0.0036361232474132654 .. 0.0036361232474132659] 
     2148            sage: (phi^10 - tau^10) / rt5 
     2149            [54.999999999999992 .. 55.000000000000008] 
     2150            sage: (phi^10 - tau^10) / rt5 == fibonacci(10) 
     2151            True 
     2152            sage: (phi^50 - tau^50) / rt5 == fibonacci(50) 
     2153            True 
     2154            sage: QQbar(-8)^(1/3) 
     2155            [0.99999999999999988 .. 1.0000000000000003] + [1.7320508075688771 .. 1.7320508075688775]*I 
     2156            sage: (QQbar(-8)^(1/3))^3 
     2157            -8 
     2158            sage: QQbar(32)^(1/5) 
     2159            2 
     2160            sage: a = QQbar.zeta(7)^(1/3); a 
     2161            [0.95557280578614067 .. 0.95557280578614079] + [0.29475517441090420 .. 0.29475517441090427]*I 
     2162            sage: a == QQbar.zeta(21)             
     2163            True 
     2164            sage: QQbar.zeta(7)^6 
     2165            [0.62348980185873348 .. 0.62348980185873360] - [0.78183148246802980 .. 0.78183148246802992]*I 
     2166            sage: (QQbar.zeta(7)^6)^(1/3) * QQbar.zeta(21) 
     2167            1 
     2168        """ 
     2169        e = QQ._coerce_(e) 
     2170        n = e.numerator() 
     2171        d = e.denominator() 
     2172        if d == 1: 
     2173            return generic_power(self, n) 
     2174 
     2175        # First, check for exact roots. 
     2176        if isinstance(self._descr, ANRational): 
     2177            rt = rational_exact_root(abs(self._descr._value), d) 
     2178            if rt is not None: 
     2179                if self._descr._value < 0: 
     2180                    return AlgebraicNumber(ANRootOfUnity(~(2*d), rt))**n 
     2181                else: 
     2182                    return AlgebraicNumber(ANRational(rt))**n 
     2183        elif isinstance(self._descr, ANRootOfUnity): 
     2184            rt = rational_exact_root(abs(self._descr._scale), d) 
     2185            if rt is not None: 
     2186                if self._descr._scale < 0: 
     2187                    return AlgebraicNumber(ANRootOfUnity((self._descr._angle - QQ_1_2)/d, rt))**n 
     2188                else: 
     2189                    return AlgebraicNumber(ANRootOfUnity(self._descr._angle/d, rt))**n 
     2190 
     2191        # Without this special case, we don't know the multiplicity 
     2192        # of the desired root 
     2193        if self.is_zero(): 
     2194            return AlgebriacNumber(0) 
     2195        argument_is_pi = False 
     2196        for prec in short_prec_seq(): 
     2197            if prec is None: 
     2198                # We know that self.real() < 0, since self._value 
     2199                # crosses the negative real line and self._value 
     2200                # is known to be non-zero. 
     2201                isgn = self.imag().sign() 
     2202                val = self._value 
     2203                argument = val.argument() 
     2204                if isgn == 0: 
     2205                    argument = argument.parent().pi() 
     2206                    argument_is_pi = True 
     2207                elif isgn > 0: 
     2208                    if argument < 0: 
     2209                        argument = argument + 2 * argument.parent().pi() 
     2210                else: 
     2211                    if argument > 0: 
     2212                        argument = argument - 2 * argument.parent().pi() 
     2213            else: 
     2214                val = self._interval_fast(prec) 
     2215                if not val.crosses_log_branch_cut(): 
     2216                    argument = val.argument() 
     2217                    if val.imag().is_zero() and val.real() < 0: 
     2218                        argument_is_pi = True 
     2219                    break 
     2220         
     2221        target_abs = abs(val) ** e 
     2222        target_arg = argument * e 
     2223 
     2224        for prec in tail_prec_seq(): 
     2225            if target_abs.relative_diameter() < RR_1_10 and (target_arg * d).absolute_diameter() < RR_1_10: 
     2226                break 
     2227 
     2228            val = self._interval_fast(prec) 
     2229 
     2230            target_abs = abs(val) ** e 
     2231            argument = val.argument() 
     2232            if argument_is_pi: 
     2233                argument = argument.parent().pi() 
     2234            target_arg = argument * e 
     2235 
     2236        pow_n = self**n 
     2237        poly = QQbarPoly.gen()**d - pow_n 
     2238 
     2239        prec = target_abs.prec() 
     2240        if argument_is_pi and d == 2: 
     2241            target_real = 0 
     2242        else: 
     2243            target_real = target_arg.cos() * target_abs 
     2244        target = ComplexIntervalField(prec)(target_real, 
     2245                                            target_arg.sin() * target_abs) 
     2246 
     2247        return AlgebraicNumber(ANRoot(poly, target)) 
     2248 
     2249    def _interval_fast(self, prec): 
     2250        return self.interval_fast(ComplexIntervalField(prec)) 
     2251 
     2252    def real(self): 
     2253        return AlgebraicReal(self._descr.real(self)) 
     2254 
     2255    def imag(self): 
     2256        return AlgebraicReal(self._descr.imag(self)) 
     2257 
     2258    def conjugate(self): 
     2259        """ 
     2260        Returns the complex conjugate of self. 
     2261 
     2262        EXAMPLES: 
     2263            sage: QQbar(3 + 4*I).conjugate() 
     2264            [3.0000000000000000 .. 3.0000000000000000] - [4.0000000000000000 .. 4.0000000000000000]*I 
     2265            sage: QQbar.zeta(7).conjugate() 
     2266            [0.62348980185873348 .. 0.62348980185873360] - [0.78183148246802980 .. 0.78183148246802992]*I 
     2267            sage: QQbar.zeta(7) + QQbar.zeta(7).conjugate() 
     2268            [1.2469796037174669 .. 1.2469796037174672] + [-3.2526065174565134e-19 .. 3.7947076036992656e-19]*I 
     2269        """ 
     2270        return AlgebraicNumber(self._descr.conjugate(self)) 
     2271 
     2272    def norm(self): 
     2273        """ 
     2274        Returns self * self.conjugate().  This is the algebraic 
     2275        definition of norm, if we view QQbar as AA[I]. 
     2276 
     2277        EXAMPLES: 
     2278            sage: QQbar(3 + 4*I).norm() 
     2279            25 
     2280            sage: type(QQbar(I).norm()) 
     2281            <class 'sage.rings.algebraic_real.AlgebraicReal'> 
     2282            sage: QQbar.zeta(1007).norm() 
     2283            1 
     2284        """ 
     2285        return AlgebraicReal(self._descr.norm(self)) 
     2286 
     2287    def interval_exact(self, field): 
     2288        """ 
     2289        Given a ComplexIntervalField, compute the best possible 
     2290        approximation of this number in that field.  Note that if 
     2291        either the real or imaginary parts of this number are 
     2292        sufficiently close to some floating-point number (and, in 
     2293        particular, if either is exactly representable in floating-point), 
     2294        then this will trigger exact computation, which may be very slow. 
     2295 
     2296        EXAMPLES: 
     2297            sage: a = QQbar(I).sqrt(); a 
     2298            [0.70710678118654746 .. 0.70710678118654758] + [0.70710678118654746 .. 0.70710678118654758]*I 
     2299            sage: a.interval_exact(CIF) 
     2300            [0.70710678118654746 .. 0.70710678118654758] + [0.70710678118654746 .. 0.70710678118654758]*I 
     2301            sage: b = QQbar((1+I)*sqrt(2)/2) 
     2302            sage: (a - b).interval(CIF) 
     2303            [-5.4210108624275222e-20 .. 5.4210108624275222e-20] + [-1.0842021724855045e-19 .. 5.4210108624275222e-20]*I 
     2304            sage: (a - b).interval_exact(CIF) 
     2305            0 
     2306        """ 
     2307        if not is_ComplexIntervalField(field): 
     2308            raise ValueError, "AlgebraicNumber interval_exact requires a ComplexIntervalField" 
     2309        rfld = field._real_field() 
     2310        re = self.real().interval_exact(rfld) 
     2311        im = self.imag().interval_exact(rfld) 
     2312        return field(re, im) 
     2313 
     2314    def _complex_mpfr_field_(self, field): 
     2315        if is_ComplexIntervalField(field): 
     2316            return self.interval(field) 
     2317        else: 
     2318            return self.complex_number(field) 
     2319 
     2320 
     2321    def complex_number(self, field): 
     2322        """ 
     2323        Given a ComplexField, compute a good approximation to self in that 
     2324        field.  The approximation will be off by at most two ulp's in 
     2325        each component, except for components which are very close to 
     2326        zero, which will have an abolute error at most 2^(-(field.prec()-1)). 
     2327 
     2328        EXAMPLES: 
     2329            sage: a = QQbar.zeta(5) 
     2330            sage: a.complex_number(CIF) 
     2331            0.309016994374947 + 0.951056516295154*I 
     2332            sage: (a + a.conjugate()).complex_number(CIF) 
     2333            0.618033988749895 - 5.42101086242752e-20*I 
     2334        """ 
     2335        v = self.interval(ComplexIntervalField(field.prec())) 
     2336        return v.center() 
     2337 
     2338    def complex_exact(self, field): 
     2339        """ 
     2340        Given a ComplexField, return the best possible approximation of 
     2341        this number in that field.  Note that if either component is 
     2342        sufficiently close to the halfway point between two floating-point 
     2343        numbers in the corresponding RealField, then this will trigger 
     2344        exact computation, which may be very slow. 
     2345 
     2346        EXAMPLES: 
     2347            sage: a = QQbar.zeta(9) + I + QQbar.zeta(9).conjugate(); a 
     2348            [1.5320888862379560 .. 1.5320888862379563] + [0.99999999999999988 .. 1.0000000000000003]*I 
     2349            sage: a.complex_exact(CIF) 
     2350            [1.5320888862379560 .. 1.5320888862379563] + [1.0000000000000000 .. 1.0000000000000000]*I 
     2351        """ 
     2352        rfld = field._real_field() 
     2353        re = self.real().real_exact(rfld) 
     2354        im = self.imag().real_exact(rfld) 
     2355        return field(re, im)         
     2356 
     2357    def multiplicative_order(self): 
     2358        """ 
     2359        Compute the multiplicative order of this algebraic real 
     2360        number.  That is, find the smallest positive integer n such 
     2361        that x^n == 1.  If there is no such n, returns +Infinity. 
     2362 
     2363        We first check that abs(x) is very close to 1.  If so, we compute 
     2364        x exactly and examine its argument. 
     2365 
     2366        EXAMPLES: 
     2367            sage: QQbar(-sqrt(3)/2 - I/2).multiplicative_order() 
     2368            12 
     2369            sage: QQbar(1).multiplicative_order() 
     2370            1 
     2371            sage: QQbar(-I).multiplicative_order() 
     2372            4 
     2373            sage: QQbar(707/1000 + 707/1000*I).multiplicative_order() 
     2374            +Infinity 
     2375            sage: QQbar(3/5 + 4/5*I).multiplicative_order() 
     2376            +Infinity 
     2377        """ 
     2378        if not (1 in CIF(self).norm()): 
     2379            return infinity.infinity 
     2380        if self.norm() != 1: 
     2381            return infinity.infinity 
     2382        ra = self.rational_argument() 
     2383        if ra is None: 
     2384            return infinity.infinity 
     2385        return ra.denominator() 
     2386 
     2387    def rational_argument(self): 
     2388        """ 
     2389        Returns the argument of self, divided by 2*pi, as long as this 
     2390        result is rational.  Otherwise returns None.  Always triggers 
     2391        exact computation. 
     2392 
     2393        EXAMPLES: 
     2394            sage: QQbar((1+I)*(sqrt(2)+sqrt(5))).rational_argument() 
     2395            1/8 
     2396            sage: QQbar(-1 + I*sqrt(3)).rational_argument() 
     2397            1/3 
     2398            sage: QQbar(-1 - I*sqrt(3)).rational_argument() 
     2399            -1/3 
     2400            sage: QQbar(3+4*I).rational_argument() is None 
     2401            True 
     2402            sage: (QQbar.zeta(7654321)^65536).rational_argument() 
     2403            65536/7654321 
     2404            sage: (QQbar.zeta(3)^65536).rational_argument() 
     2405            1/3 
     2406        """ 
     2407        # This always triggers exact computation.  An alternate method 
     2408        # could almost always avoid exact computation when the result 
     2409        # is None: if we can compute an upper bound on the degree of 
     2410        # this algebraic number without exact computation, we can use 
     2411        # the method of ANExtensionElement.rational_argument(). 
     2412 
     2413        # Even a very loose upper bound would suffice; for instance, 
     2414        # an upper bound of 2^100, when the true degree was 8, would 
     2415        # still be efficient. 
     2416 
     2417        self.exactify() 
     2418        return self._descr.rational_argument(self) 
     2419 
     2420class AlgebraicReal(AlgebraicNumber_base): 
     2421    def __init__(self, x): 
     2422        AlgebraicNumber_base.__init__(self, AA, x) 
     2423 
     2424    def __cmp__(self, other): 
     2425        """ 
     2426        Compare two algebraic reals. 
     2427 
     2428        EXAMPLES: 
     2429            sage: cmp(AA(golden_ratio), AA(sqrt(5))) 
     2430            -1 
     2431            sage: cmp(AA(golden_ratio), AA((sqrt(5)+1)/2)) 
     2432            0 
     2433            sage: cmp(AA(7), AA(50/7)) 
     2434            -1 
     2435        """ 
     2436        if self is other: return 0 
    11992437        if other._descr.is_rational() and other._descr.rational_value() == 0: 
    12002438            return self.sign() 
     
    12062444    def __pow__(self, e): 
    12072445        """ 
    1208         self^p returns the p'th power of self (where p can be an arbitrary 
    1209         rational). 
     2446        self^p returns the p'th power of self (where p can be an 
     2447        arbitrary rational).  If p is (a/b), takes the b'th root of 
     2448        self, then takes that to the a'th power.  If self is negative 
     2449        and b is odd, it takes the real b'th root; if self is odd and 
     2450        b is even, this takes a complex root.  Note that the behavior 
     2451        when self is negative and b is odd differs from the complex 
     2452        case; algebraic numbers select the principle complex b'th 
     2453        root, but algebraic reals select the real root. 
    12102454 
    12112455        EXAMPLES: 
     
    12132457            [1.4142135623730949 .. 1.4142135623730952] 
    12142458            sage: AA(8)^(2/3) 
    1215             [3.9999999999999995 .. 4.0000000000000009] 
     2459            4 
    12162460            sage: AA(8)^(2/3) == 4 
    12172461            True 
     
    12302474            sage: (phi^50 - tau^50) / rt5 == fibonacci(50) 
    12312475            True 
     2476 
     2477        TESTS: 
     2478            sage: AA(-8)^(1/3) 
     2479            -2 
     2480            sage: AA(-8)^(2/3) 
     2481            4 
     2482            sage: AA(32)^(3/5) 
     2483            8 
     2484            sage: AA(-16)^(1/2) 
     2485            4*I 
     2486            sage: AA(-16)^(1/4) 
     2487            [1.4142135623730949 .. 1.4142135623730952] + [1.4142135623730949 .. 1.4142135623730952]*I 
     2488            sage: AA(-16)^(1/4)/QQbar.zeta(8) 
     2489            2 
    12322490        """ 
    12332491        e = QQ._coerce_(e) 
     
    12362494        if d == 1: 
    12372495            return generic_power(self, n) 
     2496 
     2497        # First, check for exact roots. 
     2498        if isinstance(self._descr, ANRational): 
     2499            rt = rational_exact_root(abs(self._descr._value), d) 
     2500            if rt is not None: 
     2501                if self._descr._value < 0: 
     2502                    if d % 2 == 0: 
     2503                        return AlgebraicNumber(ANRootOfUnity(~(2*d), rt))**n 
     2504                    else: 
     2505                        return AlgebraicReal(ANRational(-rt))**n 
     2506                else: 
     2507                    return AlgebraicReal(ANRational(rt))**n 
     2508 
    12382509        # Without this special case, we don't know the multiplicity 
    12392510        # of the desired root 
     
    12422513        if d % 2 == 0: 
    12432514            if self.sign() < 0: 
    1244                 raise ValueError, 'complex algebraics not implemented' 
     2515                return QQbar(self).__pow__(e) 
    12452516        pow_n = self**n 
    12462517        poly = AAPoly.gen()**d - pow_n 
     
    12512522            result_min = min(range.lower(), -1) 
    12522523        result_max = max(range.upper(), 1) 
    1253         return AlgebraicRealNumber(AlgebraicRealNumberRoot(poly, RIF(result_min, result_max))) 
    1254  
    1255     def __hash__(self): 
    1256         """ 
    1257         Compute a hash code for this number (equal algebraic reals will 
    1258         have the same hash code, different algebraic reals are likely 
    1259         to have different hash codes). 
    1260  
    1261         This may trigger exact computation, but that is very unlikely. 
    1262  
    1263         TESTS: 
    1264         The hash code is stable, even when the representation changes. 
    1265             sage: two = sqrt(AA(4)) 
    1266             sage: two 
    1267             [1.9999999999999997 .. 2.0000000000000005] 
    1268             sage: h1 = hash(two) 
    1269             sage: two == 2 
    1270             True 
    1271             sage: two 
    1272             2 
    1273             sage: h2 = hash(two) 
    1274             sage: h1 == h2 
    1275             True 
    1276  
    1277         Unfortunately, the hash code for algebraic reals which are close 
    1278         enough to each other are the same.  (This is inevitable, if 
    1279         equal algebraic reals give the same hash code and hashing does 
    1280         not trigger exact computation.) 
    1281             sage: h1 = hash(AA(0)) 
    1282             sage: h2 = hash(AA(1/2^100)) 
    1283             sage: hash(h1) == hash(h2) 
    1284             True 
    1285         """ 
    1286  
    1287         # The only way I can think of to hash algebraic reals without 
    1288         # always triggering exact computation is to use interval_exact(). 
    1289         # However, interval_exact() always triggers exact computation 
    1290         # if the number is exactly representable in floating point, which 
    1291         # is presumably not too unlikely (algebraic reals like 0, 1/2, 
    1292         # 1, or 2 are presumably not uncommon). 
    1293  
    1294         # So I modify the algebraic real by adding 1/123456789 to it before 
    1295         # calling interval_exact().  Then, exact computation will be triggered 
    1296         # by algebraic reals which are sufficiently close to 
    1297         # (some floating point number minus 1/123456789).  Hopefully, 
    1298         # -1/123456789 comes up in algebraic real computations far less 
    1299         # often than 0 does. 
    1300  
    1301         # All of this effort to avoid exact computation is probably wasted, 
    1302         # anyway... in almost all uses of hash codes, if the hash codes 
    1303         # match, the next step is to compare for equality; and comparing 
    1304         # for equality always triggers exact computation. 
    1305  
    1306         return hash((self + AA_1_123456789).interval_exact(RIF)) 
    1307  
    1308     def sqrt(self): 
    1309         return self.__pow__(~ZZ(2)) 
    1310  
    1311     def nth_root(self, n): 
    1312         return self.__pow__(~ZZ(n)) 
    1313  
    1314     def exactify(self): 
    1315         """ 
    1316         Compute an exact representation for this number. 
    1317  
    1318         EXAMPLES: 
    1319             sage: two = sqrt(AA(4))             
    1320             sage: two 
    1321             [1.9999999999999997 .. 2.0000000000000005] 
    1322             sage: two.exactify() 
    1323             sage: two 
    1324             2 
    1325         """ 
    1326         od = self._descr 
    1327         if od.is_exact(): return 
    1328         self._descr = self._descr.exactify() 
    1329         new_val = self._descr.interval_fast(self.parent().default_interval_field()) 
    1330         self._value = self._value.intersection(new_val) 
    1331 #         if self._value != self._descr.interval_fast(RIF): 
    1332 #             v1 = self._value 
    1333 #             v2 = self._descr.interval_fast(RIF) 
    1334 #             # print (v1 != v2) 
    1335 #             # print v1 - v2 
    1336 #             # print v1, v2 
    1337 #             # print 'try1', self._descr.interval_fast(RIF), 'done' 
    1338 #             global od2 
    1339 #             od2 = od 
    1340 #             # print 'a', od.interval_fast(RIF), self._value 
    1341 #             # print 'b', self._descr.interval_fast(RIF), v2 
    1342 #             # print 'try2', self._descr.interval_fast(RIF), 'done' 
    1343 #             raise ValueError 
    1344  
    1345     def _exact_field(self): 
    1346         """ 
    1347         Returns a generator for a number field that includes this number 
    1348         (not necessarily the smallest such number field). 
    1349  
    1350         EXAMPLES: 
    1351             sage: AA(2)._exact_field() 
    1352             Unit generator 
    1353             sage: (sqrt(AA(2)) + sqrt(AA(19)))._exact_field() 
    1354             Number Field in a with defining polynomial y^4 - 20*y^2 + 81 with a in [3.7893137826710354 .. 3.7893137826710360] 
    1355             sage: (AA(7)^(3/5))._exact_field() 
    1356             Number Field in a with defining polynomial y^5 - 7 with a in [1.4757731615945519 .. 1.4757731615945522] 
    1357         """ 
    1358  
    1359         sd = self._descr 
    1360         if sd.is_rational(): 
    1361             return unit_generator 
    1362         if sd.is_field_element(): 
    1363             return sd.field_parent() 
    1364         self.exactify() 
    1365         return self._exact_field() 
    1366  
    1367     def _exact_value(self): 
    1368         """ 
    1369         Returns either an AlgebraicRealNumberRational or an 
    1370         AlgebraicRealNumberExtensionElement representing this value. 
    1371  
    1372         EXAMPLES: 
    1373             sage: AA(2)._exact_value() 
    1374             2 
    1375             sage: (sqrt(AA(2)) + sqrt(AA(19)))._exact_value() 
    1376             1/9*a^3 + a^2 - 11/9*a - 10 where a^4 - 20*a^2 + 81 = 0 and a in [3.7893137826710354 .. 3.7893137826710360] 
    1377             sage: (AA(7)^(3/5))._exact_value() 
    1378             a^3 where a^5 - 7 = 0 and a in [1.4757731615945519 .. 1.4757731615945522] 
    1379         """ 
    1380         sd = self._descr 
    1381         if sd.is_exact(): 
    1382             return sd 
    1383         self.exactify() 
    1384         return self._exact_value() 
    1385  
    1386     def _more_precision(self): 
    1387         """ 
    1388         Recompute the interval bounding this number with higher-precision 
    1389         interval arithmetic. 
    1390  
    1391         EXAMPLES: 
    1392             sage: rt2 = sqrt(AA(2)) 
    1393             sage: rt2._value 
    1394             [1.41421356237309504876 .. 1.41421356237309504888] 
    1395             sage: rt2._more_precision() 
    1396             sage: rt2._value 
    1397             [1.414213562373095048801688724209698078568 .. 1.414213562373095048801688724209698078575] 
    1398             sage: rt2._more_precision() 
    1399             sage: rt2._value 
    1400             [1.414213562373095048801688724209698078569671875376948073176679737990732478462101 .. 1.414213562373095048801688724209698078569671875376948073176679737990732478462120] 
    1401         """ 
    1402         prec = self._value.prec() 
    1403         field = RealIntervalField(prec * 2) 
    1404         self._value = self._descr.interval_fast(field) 
    1405  
    1406     def minpoly(self): 
    1407         """ 
    1408         Compute the minimal polynomial of this algebraic number. 
    1409         The minimal polynomial is the monic polynomial of least degree 
    1410         having this number as a root; it is unique. 
    1411  
    1412         EXAMPLES: 
    1413             sage: AA(4).sqrt().minpoly() 
    1414             x - 2 
    1415             sage: ((AA(2).nth_root(4))^2).minpoly() 
    1416             x^2 - 2 
    1417             sage: v = sqrt(AA(2)) + sqrt(AA(3)); v 
    1418             [3.1462643699419721 .. 3.1462643699419726] 
    1419             sage: p = v.minpoly(); p 
    1420             x^4 - 10*x^2 + 1 
    1421             sage: p(RR(v)) 
    1422             0.0000000000000131006316905768 
    1423         """ 
    1424         try: 
    1425             return self._minimal_polynomial 
    1426         except AttributeError: 
    1427             self.exactify() 
    1428             self._minimal_polynomial = self._descr.minpoly() 
    1429             return self._minimal_polynomial 
    1430  
    1431     def degree(self): 
    1432         """ 
    1433         Return the degree of this algebraic number (the degree of its 
    1434         minimal polynomial, or equivalently, the degree of the smallest 
    1435         algebraic extension of the rationals containing this number). 
    1436  
    1437         EXAMPLES: 
    1438             sage: AA(5/3).degree() 
    1439             1 
    1440             sage: sqrt(AA(2)).degree() 
    1441             2 
    1442             sage: AA(17).nth_root(5).degree() 
    1443             5 
    1444             sage: sqrt(3+sqrt(AA(8))).degree() 
    1445             2 
    1446         """ 
    1447         return self.minpoly().degree() 
     2524        return AlgebraicReal(ANRoot(poly, RIF(result_min, result_max))) 
    14482525 
    14492526    def sign(self): 
     
    14752552                return 0 
    14762553        elif self._descr.is_field_element(): 
    1477             if not self._descr.is_irrational(): 
    1478                 self._descr = AlgebraicRealNumberRational(self._descr.rational_value()) 
    1479                 return self.sign() 
     2554            # All field elements are irrational by construction 
     2555            # (the ANExtensionElement constructor will return an ANRational 
     2556            # instead, if the number is actually rational). 
    14802557            # An irrational number must eventually be different from 0 
    14812558            self._more_precision() 
     
    14912568            return self.sign() 
    14922569 
    1493     def interval_fast(self, field): 
    1494         """ 
    1495         Given a RealIntervalField, compute the value of this number 
    1496         using interval arithmetic of at least the precision of the field, 
    1497         and return the value in that field.  (More precision may be used 
    1498         in the computation.)  The returned interval may be arbitrarily 
    1499         imprecise, if this number is the result of a sufficiently long 
    1500         computation chain. 
    1501  
    1502         EXAMPLES: 
    1503             sage: x = AA(2).sqrt() 
    1504             sage: x.interval_fast(RIF) 
    1505             [1.4142135623730949 .. 1.4142135623730952] 
    1506             sage: x.interval_fast(RealIntervalField(200)) 
    1507             [1.4142135623730950488016887242096980785696718753769480731766796 .. 1.4142135623730950488016887242096980785696718753769480731766809] 
    1508             sage: x = AA(4).sqrt() 
    1509             sage: (x-2).interval_fast(RIF) 
    1510             [-1.0842021724855045e-19 .. 2.1684043449710089e-19] 
    1511         """ 
    1512         if field.prec() == self._value.prec(): 
    1513             return self._value 
    1514         elif field.prec() > self._value.prec(): 
    1515             self._more_precision() 
    1516             return self.interval_fast(field) 
    1517         else: 
    1518             return field(self._value) 
    1519  
    1520     def interval_diameter(self, diam): 
    1521         """ 
    1522         Compute an interval representation of self with diameter() at 
    1523         most diam.  The precision of the returned value is unpredictable. 
    1524  
    1525         EXAMPLES: 
    1526             sage: AA(2).sqrt().interval_diameter(1e-10) 
    1527             [1.41421356237309504876 .. 1.41421356237309504888] 
    1528             sage: AA(2).sqrt().interval_diameter(1e-30) 
    1529             [1.414213562373095048801688724209698078568 .. 1.414213562373095048801688724209698078575] 
    1530         """ 
    1531         if diam <= 0: 
    1532             raise ValueError, 'diameter must be positive in interval_diameter' 
    1533  
    1534         while self._value.diameter() > diam: 
    1535             self._more_precision() 
    1536  
    1537         return self._value 
    1538  
    1539     def interval(self, field): 
    1540         """ 
    1541         Given a RealIntervalField of precision p, compute an interval 
    1542         representation of self with diameter() at most 2^-p; then round 
    1543         that representation into the given field.  Here diameter() is 
    1544         relative diameter for intervals not containing 0, and absolute 
    1545         diameter for intervals that do contain 0; thus, if the returned 
    1546         interval does not contain 0, it has at least p-1 good bits. 
    1547  
    1548         EXAMPLES: 
    1549             sage: RIF64 = RealIntervalField(64) 
    1550             sage: x = AA(2).sqrt() 
    1551             sage: y = x*x 
    1552             sage: y = 1000 * y - 999 * y 
    1553             sage: y.interval_fast(RIF64) 
    1554             [1.99999999999999966693 .. 2.00000000000000033307] 
    1555             sage: y.interval(RIF64) 
    1556             [1.99999999999999999989 .. 2.00000000000000000022] 
    1557         """ 
    1558         target = RR(1.0) >> field.prec() 
    1559         val = self.interval_diameter(target) 
    1560         return field(val) 
     2570    def _interval_fast(self, prec): 
     2571        return self.interval_fast(RealIntervalField(prec)) 
    15612572 
    15622573    def interval_exact(self, field): 
     
    16202631            self._more_precision() 
    16212632 
    1622     def real(self, field): 
     2633    def real_number(self, field): 
    16232634        """ 
    16242635        Given a RealField, compute a good approximation to self in that field. 
     
    16302641        EXAMPLES: 
    16312642            sage: x = AA(2).sqrt()^2 
    1632             sage: x.real(RR) 
     2643            sage: x.real_number(RR) 
    16332644            2.00000000000000 
    1634             sage: x.real(RealField(53, rnd='RNDD')) 
     2645            sage: x.real_number(RealField(53, rnd='RNDD')) 
    16352646            1.99999999999999 
    1636             sage: x.real(RealField(53, rnd='RNDU')) 
     2647            sage: x.real_number(RealField(53, rnd='RNDU')) 
    16372648            2.00000000000001 
    1638             sage: x.real(RealField(53, rnd='RNDZ')) 
     2649            sage: x.real_number(RealField(53, rnd='RNDZ')) 
    16392650            1.99999999999999 
    1640             sage: (-x).real(RR) 
     2651            sage: (-x).real_number(RR) 
    16412652            -2.00000000000000 
    1642             sage: (-x).real(RealField(53, rnd='RNDD')) 
     2653            sage: (-x).real_number(RealField(53, rnd='RNDD')) 
    16432654            -2.00000000000001 
    1644             sage: (-x).real(RealField(53, rnd='RNDU')) 
     2655            sage: (-x).real_number(RealField(53, rnd='RNDU')) 
    16452656            -1.99999999999999 
    1646             sage: (-x).real(RealField(53, rnd='RNDZ')) 
     2657            sage: (-x).real_number(RealField(53, rnd='RNDZ')) 
    16472658            -1.99999999999999 
    1648             sage: (x-2).real(RR) 
     2659            sage: (x-2).real_number(RR) 
    16492660            5.42101086242752e-20 
    1650             sage: (x-2).real(RealField(53, rnd='RNDD')) 
     2661            sage: (x-2).real_number(RealField(53, rnd='RNDD')) 
    16512662            -1.08420217248551e-19 
    1652             sage: (x-2).real(RealField(53, rnd='RNDU')) 
     2663            sage: (x-2).real_number(RealField(53, rnd='RNDU')) 
    16532664            2.16840434497101e-19 
    1654             sage: (x-2).real(RealField(53, rnd='RNDZ')) 
     2665            sage: (x-2).real_number(RealField(53, rnd='RNDZ')) 
    16552666            0.000000000000000 
    16562667            sage: y = AA(2).sqrt() 
    1657             sage: y.real(RR) 
     2668            sage: y.real_number(RR) 
    16582669            1.41421356237309 
    1659             sage: y.real(RealField(53, rnd='RNDD')) 
     2670            sage: y.real_number(RealField(53, rnd='RNDD')) 
    16602671            1.41421356237309 
    1661             sage: y.real(RealField(53, rnd='RNDU')) 
     2672            sage: y.real_number(RealField(53, rnd='RNDU')) 
    16622673            1.41421356237310 
    1663             sage: y.real(RealField(53, rnd='RNDZ')) 
     2674            sage: y.real_number(RealField(53, rnd='RNDZ')) 
    16642675            1.41421356237309 
    16652676        """ 
     
    16812692                return field(0) 
    16822693 
     2694    _mpfr_ = real_number 
     2695 
     2696    def _complex_mpfr_field_(self, field): 
     2697        if is_ComplexIntervalField(field): 
     2698            return field(self.interval(field._real_field())) 
     2699        else: 
     2700            return field(self.real_number(field._real_field())) 
     2701 
    16832702    def real_exact(self, field): 
    16842703        """ 
    16852704        Given a RealField, compute the best possible approximation of 
    1686         this number in that field.  Note that if this number is sufficiently 
    1687         close to some floating-point number in the field (and, in particular, 
    1688         if this number is exactly representable in the field), then 
    1689         this will trigger exact computation, which may be very slow. 
     2705        this number in that field.  Note that if this number is 
     2706        sufficiently close to the halfway point between two 
     2707        floating-point numbers in the field (for the default 
     2708        round-to-nearest mode) or if the number is sufficiently close 
     2709        to a floating-point number in the field (for directed rounding 
     2710        modes), then this will trigger exact computation, which may be 
     2711        very slow. 
    16902712 
    16912713        The rounding mode of the field is respected. 
     
    17602782        return field(mid) 
    17612783 
    1762 def is_AlgebraicRealNumber(x): 
    1763     return isinstance(x, AlgebraicRealNumber) 
    1764  
     2784class ANRational(ANDescr): 
     2785    """ 
     2786    The subclass of ANDescr that represents an arbitrary 
     2787    rational.  This class is private, and should not be used directly. 
     2788    """ 
     2789 
     2790    def __init__(self, x): 
     2791        """ 
     2792        TESTS: 
     2793            sage: polygen(QQbar) / int(3) 
     2794            1/3*x 
     2795            sage: QQbar(int(7)) / QQbar(long(2)) 
     2796            7/2 
     2797        """ 
     2798        if isinstance(x, (sage.rings.integer.Integer, 
     2799                          sage.rings.rational.Rational)): 
     2800            self._value = x 
     2801        elif isinstance(x, (int, long)): 
     2802            self._value = ZZ(x) 
     2803        else: 
     2804            raise TypeError, "Illegal initializer for algebraic number rational" 
     2805 
     2806    def _repr_(self): 
     2807        return repr(self._value) 
     2808 
     2809    def kind(self): 
     2810        if self._value.is_zero(): 
     2811            return 'zero' 
     2812        else: 
     2813            return 'rational' 
     2814 
     2815    def _interval_fast(self, prec): 
     2816        return RealIntervalField(prec)(self._value) 
     2817 
     2818    def generator(self): 
     2819        return qq_generator 
     2820 
     2821    def is_complex(self): 
     2822        return False 
     2823 
     2824    def is_rational(self): 
     2825        return True 
     2826 
     2827    def rational_value(self): 
     2828        return self._value 
     2829 
     2830    def exactify(self): 
     2831        return self 
     2832 
     2833    def is_exact(self): 
     2834        return True 
     2835 
     2836    def minpoly(self): 
     2837        return QQx_x - self._value 
     2838 
     2839    def neg(self, n): 
     2840        return ANRational(-self._value) 
     2841 
     2842    def invert(self, n): 
     2843        return ANRational(~self._value) 
     2844 
     2845    def abs(self, n): 
     2846        return ANRational(abs(self._value)) 
     2847 
     2848    def rational_argument(self, n): 
     2849        if self._value > 0: 
     2850            return QQ(0) 
     2851        if self._value < 0: 
     2852            return QQ(1)/2 
     2853        return None 
     2854 
     2855    def gaussian_value(self): 
     2856        return QQbar_I_nf(self._value) 
     2857 
     2858    def angle(self): 
     2859        return QQ_0 
     2860 
     2861    def scale(self): 
     2862        return self._value 
     2863 
     2864class ANRootOfUnity(ANDescr): 
     2865    """ 
     2866    The subclass of ANDescr that represents a rational multiplied 
     2867    by a root of unity.  This class is private, and should not be 
     2868    used directly. 
     2869 
     2870    Such numbers are represented by a "rational angle" and a rational 
     2871    scale.  The "rational angle" is the argument of the number, divided by 
     2872    2*pi; so given angle and scale, the number is: 
     2873    scale*(cos(2*pi*angle) + sin(2*pi*angle)*I); or equivalently 
     2874    scale*(e^(2*pi*angle*I)). 
     2875 
     2876    We normalize so that 0<angle<1/2; this requires allowing both positive 
     2877    and negative scales.  (Attempts to create an ANRootOfUnity with an 
     2878    angle which is a multiple of 1/2 end up creating an ANRational instead.) 
     2879    """ 
     2880 
     2881    def __new__(self, angle, scale): 
     2882        """ 
     2883        Construct an ANRootOfUnity from a rational angle and a rational 
     2884        scale.  If the number is actually a real rational, returns an 
     2885        ANRational instead. 
     2886        """ 
     2887        if scale.is_zero(): 
     2888            return ANRational(0) 
     2889        try: 
     2890            int_angle = ZZ(angle*2) 
     2891        except TypeError: 
     2892            return ANDescr.__new__(self) 
     2893 
     2894        if int_angle & 1: 
     2895            # int_angle is odd 
     2896            return ANRational(-scale) 
     2897        else: 
     2898            # int_angle is even 
     2899            return ANRational(scale) 
     2900         
     2901    def __init__(self, angle, scale): 
     2902        """ 
     2903        Construct an ANRootOfUnity from a rational angle and a rational 
     2904        scale. 
     2905        """ 
     2906 
     2907        angle2 = angle * 2 
     2908        fl2 = angle2.floor() 
     2909        angle2 = angle2 - fl2 
     2910        angle = angle2 / 2 
     2911        if fl2 & 1: 
     2912            scale = -scale 
     2913        self._angle = angle 
     2914        self._scale = scale 
     2915 
     2916    def _repr_(self): 
     2917        return "%s*e^(2*pi*I*%s)"%(self._scale, self._angle) 
     2918 
     2919    def kind(self): 
     2920        if self._angle == QQ_1_4: 
     2921            return 'imaginary' 
     2922        else: 
     2923            return 'rootunity' 
     2924 
     2925    def _interval_fast(self, prec): 
     2926        argument = self._angle * RealIntervalField(prec).pi() * 2 
     2927        if self._angle == QQ_1_4: 
     2928            return ComplexIntervalField(prec)(0, self._scale) 
     2929        else: 
     2930            return ComplexIntervalField(prec)(argument.cos(), argument.sin()) * self._scale 
     2931 
     2932    def generator(self): 
     2933        return cyclotomic_generator(self._angle.denominator()) 
     2934 
     2935    def field_element_value(self): 
     2936        gen = self.generator() 
     2937        f = gen._field 
     2938        a = f.gen() 
     2939        return self._scale * a ** self._angle.numerator() 
     2940 
     2941    def is_complex(self): 
     2942        return True 
     2943 
     2944    def exactify(self): 
     2945        return self 
     2946 
     2947    def is_exact(self): 
     2948        return True 
     2949 
     2950    def minpoly(self): 
     2951        """ 
     2952        EXAMPLES: 
     2953            sage: a = QQbar.zeta(7) * 2; a 
     2954            [1.2469796037174669 .. 1.2469796037174672] + [1.5636629649360596 .. 1.5636629649360599]*I 
     2955            sage: a.minpoly() 
     2956            x^6 + 2*x^5 + 4*x^4 + 8*x^3 + 16*x^2 + 32*x + 64 
     2957            sage: a.minpoly()(a) 
     2958            [-0.00000000000000031918911957973251 .. 0.00000000000000034694469519536142] + [-0.00000000000000033133218391157016 .. 0.00000000000000032786273695961655]*I 
     2959            sage: a.minpoly()(a) == 0 
     2960            True 
     2961        """ 
     2962        # This could be more efficient... 
     2963        p = cyclotomic_polynomial(self._angle.denominator()) 
     2964        p = p(p.parent().gen() / self._scale) 
     2965        p = p / p.leading_coefficient() 
     2966        return p 
     2967 
     2968    def neg(self, n): 
     2969        return ANRootOfUnity(self._angle, -self._scale) 
     2970 
     2971    def invert(self, n): 
     2972        # We want ANRootOfUnity(-self._angle, ~self._scale); 
     2973        # but that's not normalized, so we pre-normalize it to: 
     2974        return ANRootOfUnity(QQ_1_2 - self._angle, -~self._scale) 
     2975 
     2976    def conjugate(self, n): 
     2977        # We want ANRootOfUnity(-self._angle, self._scale); 
     2978        # but that's not normalized, so we pre-normalize it to: 
     2979        return ANRootOfUnity(QQ_1_2 - self._angle, -self._scale) 
     2980 
     2981    def abs(self, n): 
     2982        return ANRational(abs(self._scale)) 
     2983 
     2984    def norm(self, n): 
     2985        return ANRational(self._scale * self._scale) 
     2986 
     2987    def rational_argument(self, n): 
     2988        if self._scale > 0: 
     2989            return self._angle 
     2990        else: 
     2991            return self._angle - QQ_1_2 
     2992     
     2993    def gaussian_value(self): 
     2994        assert(self._angle == QQ_1_4) 
     2995        return QQbar_I_nf(self._scale * QQbar_I_nf.gen()) 
     2996 
     2997    def angle(self): 
     2998        return self._angle 
     2999 
     3000    def scale(self): 
     3001        return self._scale 
     3002 
     3003def is_AlgebraicReal(x): 
     3004    return isinstance(x, AlgebraicReal) 
     3005 
     3006def is_AlgebraicNumber(x): 
     3007    return isinstance(x, AlgebraicNumber) 
     3008 
     3009QQbarPoly = PolynomialRing(QQbar, 'x') 
    17653010AAPoly = PolynomialRing(AA, 'x') 
    17663011 
     
    17723017    polynomial, this allows the polynomial and information about 
    17733018    the polynomial to be shared.  This reduces work if the polynomial 
    1774     must be recomputed at higher precision, or if it must be made 
    1775     exact. 
     3019    must be recomputed at higher precision, or if it must be factored. 
    17763020 
    17773021    This class is private, and should only be constructed by 
    1778     AlgebraicRealField.common_polynomial(), and should only be used as 
    1779     an argument to AlgebraicRealField.polynomial_root(). 
     3022    AA.common_polynomial() or QQbar.common_polynomial(), and should 
     3023    only be used as an argument to AA.polynomial_root() or 
     3024    QQbar.polynomial_root().  (It doesn't matter whether you create 
     3025    the common polynomial with AA.common_polynomial() or 
     3026    QQbar.common_polynomial().) 
    17803027 
    17813028    EXAMPLES: 
    1782         sage: x = polygen(AA) 
    1783         sage: P = AA.common_polynomial(x^2 - x - 1) 
     3029        sage: x = polygen(QQbar) 
     3030        sage: P = QQbar.common_polynomial(x^2 - x - 1) 
    17843031        sage: P 
    1785         x^2 - x - 1 
    1786         sage: AA.polynomial_root(P, RIF(0, 2)) 
     3032        x^2 + (-1)*x - 1 
     3033        sage: QQbar.polynomial_root(P, RIF(1, 2)) 
    17873034        [1.6180339887498946 .. 1.6180339887498950] 
    17883035    """ 
    17893036 
    17903037    def __init__(self, poly): 
    1791         poly = AAPoly._coerce_(poly) 
     3038        if not is_Polynomial(poly): 
     3039            raise ValueError, "Trying to create AlgebraicPolynomialTracker on non-Polynomial" 
     3040        if isinstance(poly.base_ring(), AlgebraicField_common): 
     3041            complex = is_AlgebraicField(poly.base_ring()) 
     3042        else: 
     3043            try: 
     3044                poly = poly.change_ring(AA) 
     3045                complex = False 
     3046            except TypeError: 
     3047                poly = poly.change_ring(QQbar) 
     3048                complex = True 
    17923049        self._poly = poly 
     3050        self._complex = complex 
    17933051        self._exact = False 
     3052        self._roots_cache = {} 
    17943053 
    17953054    def _repr_(self): 
     
    17983057    def poly(self): 
    17993058        return self._poly 
     3059 
     3060    def is_complex(self): 
     3061        return self._complex 
     3062 
     3063    def complex_roots(self, prec, multiplicity): 
     3064        """ 
     3065        EXAMPLES: 
     3066            sage: x = polygen(ZZ) 
     3067            sage: cp = AA.common_polynomial(x^4 - 1) 
     3068            sage: cp.complex_roots(30, 1) 
     3069            [[1.0000000000000000 .. 1.0000000000000000], [-1.0000000000000000 .. -1.0000000000000000], [1.0000000000000000 .. 1.0000000000000000]*I, [-1.0000000000000000 .. -1.0000000000000000]*I] 
     3070        """ 
     3071        if self._roots_cache.has_key(multiplicity): 
     3072            roots = self._roots_cache[multiplicity] 
     3073            if roots[0] >= prec: 
     3074                return roots[1] 
     3075 
     3076        p = self._poly 
     3077        for i in range(multiplicity - 1): 
     3078            p = p.derivative() 
     3079 
     3080        from sage.rings.polynomial.complex_roots import complex_roots 
     3081        roots_mult = complex_roots(p, min_prec=prec) 
     3082        roots = [rt for (rt, mult) in roots_mult if mult == 1] 
     3083        self._roots_cache[multiplicity] = (prec, roots) 
     3084        return roots 
    18003085 
    18013086    def exactify(self): 
     
    18103095        self._exact = True 
    18113096 
    1812         gen = unit_generator 
     3097        gen = qq_generator 
    18133098 
    18143099        for c in self._poly.list(): 
     
    18203105        coeffs = [gen(c._exact_value()) for c in self._poly.list()] 
    18213106 
    1822         if gen.is_unit(): 
     3107        if gen.is_trivial(): 
    18233108            qp = QQy(coeffs) 
    18243109            self._factors = [fac_exp[0] for fac_exp in qp.factor()] 
     
    18393124        return self._gen 
    18403125 
    1841 class AlgebraicRealNumberRoot(AlgebraicRealNumberDescr): 
     3126class ANRoot(ANDescr): 
    18423127    """ 
    1843     The subclass of AlgebraicRealNumberDescr that represents a particular 
     3128    The subclass of ANDescr that represents a particular 
    18443129    root of a polynomial with algebraic coefficients. 
    18453130    This class is private, and should not be used directly. 
     
    18493134            poly = AlgebraicPolynomialTracker(poly) 
    18503135        self._poly = poly 
    1851         # Rethink precision control...integer bitcounts vs. 
    1852         # RealIntervalField values 
    18533136        self._multiplicity = multiplicity 
     3137        self._complex = is_ComplexIntervalFieldElement(interval) 
     3138        self._complex_poly = poly.is_complex() 
    18543139        self._interval = self.refine_interval(interval, 64) 
    18553140         
     
    18573142        return 'Root %s of %s'%(self._interval, self._poly) 
    18583143 
    1859     def refine_interval(self, interval, precision): 
     3144    def kind(self): 
     3145        return 'other' 
     3146 
     3147    def is_complex(self): 
     3148        return self._complex 
     3149 
     3150    def conjugate(self, n): 
     3151        if not self._complex: 
     3152            return self 
     3153        if not self._complex_poly: 
     3154            return ANRoot(self._poly, self._interval.conjugate(), self._multiplicity) 
     3155 
     3156        raise NotImplementedError 
     3157 
     3158    def refine_interval(self, interval, prec): 
     3159        if self._complex or self._complex_poly: 
     3160            v = self._complex_refine_interval(interval, prec) 
     3161            if self._complex: 
     3162                return v 
     3163            else: 
     3164                return v.real() 
     3165        else: 
     3166            return self._real_refine_interval(interval, prec) 
     3167 
     3168    def _real_refine_interval(self, interval, prec): 
    18603169        """ 
    18613170        Takes an interval which is assumed to enclose exactly one root 
     
    18723181 
    18733182        EXAMPLES: 
    1874             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRoot 
     3183            sage: from sage.rings.algebraic_real import ANRoot 
    18753184            sage: x = polygen(AA) 
    1876             sage: rt2 = AlgebraicRealNumberRoot(x^2 - 2, RIF(0, 2)) 
     3185            sage: rt2 = ANRoot(x^2 - 2, RIF(0, 2)) 
    18773186            sage: rt2.refine_interval(RIF(0, 2), 75) 
    18783187            [1.41421356237309504880163 .. 1.41421356237309504880175] 
    18793188        """ 
     3189        # Don't throw away bits in the original interval; doing so might 
     3190        # invalidate it (include an extra root) 
     3191 
     3192        field = RealIntervalField(max(prec, interval.prec())) 
     3193        interval = field(interval) 
     3194        if interval.is_exact(): 
     3195            return interval 
     3196 
    18803197        p = self._poly.poly() 
    18813198        dp = p.derivative() 
     
    18843201            dp = p.derivative() 
    18853202 
    1886         # Don't throw away bits in the original interval; doing so might 
    1887         # invalidate it (include an extra root) 
    1888         field = RealIntervalField(max(precision, interval.prec())) 
    18893203        zero = field(0) 
    1890         interval = field(interval) 
     3204 
    18913205        poly_ring = field['x'] 
    18923206 
    1893         # XXX Once this is properly integrated into SAGE, 
    1894         # then the following should be replaced with: 
    18953207        # interval_p = poly_ring(p) 
    1896         # (and similarly for interval_dp) 
    1897         coeffs = [c.interval_fast(field) for c in p.list()] 
     3208        coeffs = [c._interval_fast(prec) for c in p.list()] 
    18983209        interval_p = poly_ring(coeffs) 
    18993210 
     
    19033214        # this case here means we don't have to worry about iterating too  
    19043215        # many times later 
    1905         if coeffs[0].is_zero() and zero in interval: 
     3216        if coeffs[0].is_zero() and interval.contains_zero(): 
    19063217            return zero 
    19073218 
     3219        # interval_dp = poly_ring(dp) 
    19083220        dcoeffs = [c.interval_fast(field) for c in dp.list()] 
    19093221        interval_dp = poly_ring(dcoeffs) 
     
    19113223        linfo = {} 
    19123224        uinfo = {} 
    1913  
    1914         # print coeffs 
    1915         # print p 
    19163225 
    19173226        def update_info(info, x): 
     
    19413250                return interval 
    19423251 
    1943             # print interval 
    1944  
    19453252            if linfo['sign'] == uinfo['sign']: 
    19463253                # Oops... 
    1947                 print self._poly.poly() 
    1948                 print interval_p 
    1949                 print linfo['endpoint'], linfo['value'], linfo['sign'] 
    1950                 print uinfo['endpoint'], uinfo['value'], uinfo['sign'] 
     3254                # print self._poly.poly() 
     3255                # print interval_p 
     3256                # print linfo['endpoint'], linfo['value'], linfo['sign'] 
     3257                # print uinfo['endpoint'], uinfo['value'], uinfo['sign'] 
    19513258                raise ValueError, "Refining interval that does not bound unique root!" 
    19523259 
     
    20353342                    return interval 
    20363343         
     3344    def _complex_refine_interval(self, interval, prec): 
     3345        """ 
     3346        Takes an interval which is assumed to enclose exactly one root 
     3347        of the polynomial (or, with multiplicity=k, exactly one root 
     3348        of the k-1'th derivative); and a precision, in bits. 
     3349 
     3350        Tries to find a narrow interval enclosing the root using 
     3351        interval arithmetic of the given precision.  (No particular 
     3352        number of resulting bits of precision is guaranteed.) 
     3353 
     3354        Uses Newton's method (adapted for interval arithmetic).  The 
     3355        algorithm will converge very quickly if started with a 
     3356        sufficiently narrow interval.  If Newton's method fails, then 
     3357        we falls back on computing all the roots of the polynomial 
     3358        numerically, and select the appropriate root. 
     3359 
     3360        EXAMPLES: 
     3361            sage: from sage.rings.algebraic_real import ANRoot 
     3362            sage: x = polygen(QQbar) 
     3363            sage: intv = CIF(RIF(0, 1), RIF(0.1, 1)) 
     3364            sage: rt = ANRoot(x^5 - 1, intv) 
     3365            sage: new_intv = rt.refine_interval(intv, 53); new_intv 
     3366            [0.309016994374947424022 .. 0.309016994374947424185] + [0.951056516295153572002 .. 0.951056516295153572219]*I 
     3367            sage: rt.refine_interval(new_intv, 70) 
     3368            [0.30901699437494742410148 .. 0.30901699437494742410319] + [0.95105651629515357211565 .. 0.95105651629515357211735]*I 
     3369        """ 
     3370        # Don't throw away bits in the original interval; doing so might 
     3371        # invalidate it (include an extra root) 
     3372 
     3373        field = ComplexIntervalField(max(prec, interval.prec())) 
     3374        interval = field(interval) 
     3375        if interval.is_exact(): 
     3376            return interval 
     3377 
     3378        p = self._poly.poly() 
     3379        dp = p.derivative() 
     3380        for i in xrange(0, self._multiplicity - 1): 
     3381            p = dp 
     3382            dp = p.derivative() 
     3383 
     3384        zero = field(0) 
     3385 
     3386        poly_ring = field['x'] 
     3387 
     3388        # interval_p = poly_ring(p) 
     3389        coeffs = [c.interval_fast(field) for c in p.list()] 
     3390        interval_p = poly_ring(coeffs) 
     3391 
     3392        # This special case is important: this is the only way we could 
     3393        # refine "infinitely deep" (we could get an interval of diameter 
     3394        # about 2^{-2^31}, and then hit floating-point underflow); avoiding 
     3395        # this case here means we don't have to worry about iterating too  
     3396        # many times later 
     3397        if coeffs[0].is_zero() and zero in interval: 
     3398            return zero 
     3399 
     3400        # interval_dp = poly_ring(dp) 
     3401        dcoeffs = [c.interval_fast(field) for c in dp.list()] 
     3402        interval_dp = poly_ring(dcoeffs) 
     3403         
     3404        while True: 
     3405            center = field(interval.center()) 
     3406            val = interval_p(center) 
     3407 
     3408            slope = interval_dp(interval) 
     3409 
     3410            diam = interval.diameter() 
     3411 
     3412            if zero in slope: 
     3413                # Give up and fall back on root isolation. 
     3414                return self._complex_isolate_interval(interval, prec) 
     3415 
     3416            if not (zero in slope): 
     3417                new_range = center - val / slope 
     3418                interval = interval.intersection(new_range) 
     3419 
     3420                new_diam = interval.diameter() 
     3421 
     3422                if new_diam == 0: 
     3423                    # Wow; we nailed it exactly.  (This may happen 
     3424                    # whenever the root is exactly equal to some 
     3425                    # floating-point number, and cannot happen 
     3426                    # if the root is not equal to a floating-point 
     3427                    # number.)  We just return the perfect answer. 
     3428                    return interval 
     3429 
     3430                if new_diam == diam: 
     3431                    # We're not getting any better.  There are two 
     3432                    # possible reasons for this.  Either we have 
     3433                    # refined as much as possible given the imprecision 
     3434                    # of our interval polynomial, and we have the best 
     3435                    # answer we're going to get at this precision; 
     3436                    # or we started with a poor approximation to the 
     3437                    # root, resulting in a broad range of possible 
     3438                    # slopes in this interval, and Newton-Raphson refining 
     3439                    # is not going to help. 
     3440 
     3441                    # I don't have a formal proof, but I believe the 
     3442                    # following test differentiates between these two 
     3443                    # behaviors.  (If I'm wrong, we might get bad behavior 
     3444                    # like infinite loops, but we still won't actually 
     3445                    # return a wrong answer.) 
     3446 
     3447                    if val.contains_zero(): 
     3448                        # OK, center must be a good approximation 
     3449                        # to the root (in the current precision, anyway). 
     3450                        # And the expression "center - val / slope" 
     3451                        # above means that we have a pretty good interval, 
     3452                        # even if slope is a poor estimate. 
     3453                        return interval 
     3454 
     3455                    # The center of the current interval is known 
     3456                    # not to be a root.  This should let us divide 
     3457                    # the interval in half, and improve on our previous 
     3458                    # estimates.  I can only think of two reasons why 
     3459                    # it might not: 
     3460                    # 1) the "center" of the interval is actually 
     3461                    # on one of the edges of the interval (because the 
     3462                    # interval is only one ulp wide), or 
     3463                    # 2) the slope estimate is so bad that 
     3464                    # "center - val / slope" doesn't give us information. 
     3465 
     3466                    # With complex intervals implemented as 
     3467                    # rectangular regions of the complex plane, it's 
     3468                    # possible that "val / slope" includes zero even 
     3469                    # if both "val" and "slope" are bounded away from 
     3470                    # zero, if the diameter of the (interval) argument 
     3471                    # of val or slope is large enough. 
     3472 
     3473                    # So we test the diameter of the argument of 
     3474                    # slope; if it's small, we decide that we must 
     3475                    # have a good interval, but if it's big, we decide 
     3476                    # that we probably can't make progress with 
     3477                    # Newton-Raphson. 
     3478 
     3479                    # I think the relevant measure of "small" is 
     3480                    # whether the diameter is less than pi/2; in that 
     3481                    # case, no matter the value of "val" (as long as 
     3482                    # "val" is fairly precise), "val / slope" should 
     3483                    # be bounded away from zero.  But we compare 
     3484                    # against 1 instead, in the hopes that this might 
     3485                    # be slightly faster. 
     3486 
     3487                    if slope.argument().absolute_diameter() < 1: 
     3488                        return interval 
     3489 
     3490                    # And now it's time to give up. 
     3491                    return self._complex_isolate_interval(interval, prec) 
     3492 
     3493    def _complex_isolate_interval(self, interval, prec): 
     3494        """ 
     3495        Find a precise approximation to the unique root in interval, 
     3496        by finding a precise approximation to all roots of the 
     3497        polynomial, and checking which one is in interval.  Slow but sure. 
     3498 
     3499        EXAMPLES: 
     3500            sage: from sage.rings.algebraic_real import ANRoot 
     3501            sage: x = polygen(QQbar) 
     3502            sage: intv = CIF(RIF(0, 1), RIF(0.1, 1)) 
     3503            sage: rt = ANRoot(x^5 - 1, intv) 
     3504            sage: rt._complex_isolate_interval(intv, 53) 
     3505            [0.309016994374947424022 .. 0.309016994374947424185] + [0.951056516295153572002 .. 0.951056516295153572219]*I 
     3506        """ 
     3507        rts = self._poly.complex_roots(prec, self._multiplicity) 
     3508 
     3509        # Find all the roots that overlap interval. 
     3510        our_root = [rt for rt in rts if rt.overlaps(interval)] 
     3511 
     3512        if len(our_root) == 1: 
     3513            return our_root[0] 
     3514 
     3515        if len(our_root) == 0: 
     3516            raise ValueError, "Complex root interval does not include any roots" 
     3517 
     3518        # We have more than one root that overlap the current interval. 
     3519        # Technically, this might not be an error; perhaps the actual 
     3520        # root is just outside our interval, even though the (presumably 
     3521        # tight) interval containing that root touches our interval. 
     3522 
     3523        # But it seems far more likely that the provided interval is 
     3524        # just too big. 
     3525 
     3526        raise ValueError, "Complex root interval probably includes multiple roots" 
    20373527 
    20383528    def exactify(self): 
    20393529        """ 
    2040         Returns either an AlgebraicRealNumberRational or an 
    2041         AlgebraicRealNumberExtensionElement with the same value as this number. 
    2042  
    2043         EXAMPLES: 
    2044             sage: from sage.rings.algebraic_real import AlgebraicRealNumberRoot 
    2045             sage: x = polygen(AA) 
    2046             sage: two = AlgebraicRealNumberRoot((x-2)*(x-sqrt(AA(2))), RIF(1.5, 3)) 
     3530        Returns either an ANRational or an 
     3531        ANExtensionElement with the same value as this number. 
     3532 
     3533        EXAMPLES: 
     3534            sage: from sage.rings.algebraic_real import ANRoot 
     3535            sage: x = polygen(QQbar) 
     3536            sage: two = ANRoot((x-2)*(x-sqrt(QQbar(2))), RIF(1.9, 2.1)) 
    20473537            sage: two.exactify() 
    2048             2 where a^2 - 2 = 0 and a in [1.4142135623730949 .. 1.4142135623730952] 
     3538            2 
    20493539            sage: two.exactify().rational_value() 
    20503540            2 
    2051             sage: strange = AlgebraicRealNumberRoot(x^2 + sqrt(AA(3))*x - sqrt(AA(2)), RIF(-1, 3)) 
     3541            sage: strange = ANRoot(x^2 + sqrt(QQbar(3))*x - sqrt(QQbar(2)), RIF(-0, 1)) 
    20523542            sage: strange.exactify() 
    20533543            a where a^8 - 6*a^6 + 5*a^4 - 12*a^2 + 4 = 0 and a in [0.60510122651395104 .. 0.60510122651395116] 
     
    20553545        gen = self._poly.generator() 
    20563546 
    2057         if gen.is_unit(): 
     3547        if gen.is_trivial(): 
    20583548            qpf = self._poly.factors() 
    2059             def find_fn(factor, rif): 
    2060                 return factor(self.interval_fast(rif)) 
     3549            def find_fn(factor, prec): 
     3550                return factor(self._interval_fast(prec)) 
    20613551            my_factor = find_zero_result(find_fn, qpf) 
    20623552 
     
    20653555 
    20663556            if my_factor.degree() == 1: 
    2067                 return AlgebraicRealNumberRational(-my_factor[0]) 
     3557                return ANRational(-my_factor[0]) 
    20683558 
    20693559            den, my_factor = clear_denominators(my_factor) 
     
    20743564             
    20753565            def intv_fn(rif): 
    2076                 return red_elt(self.interval_fast(rif) * den) 
    2077             new_intv = isolating_interval(intv_fn, red_pol) 
    2078             root = AlgebraicRealNumberRoot(AAPoly(red_pol), new_intv) 
     3566                return conjugate_expand(red_elt(self._interval_fast(rif) * den)) 
     3567            new_intv = conjugate_shrink(isolating_interval(intv_fn, red_pol)) 
     3568            root = ANRoot(QQx(red_pol), new_intv) 
    20793569            new_gen = AlgebraicGenerator(field, root) 
    20803570             
    2081             return AlgebraicRealNumberExtensionElement(new_gen, red_back(field.gen())/den) 
     3571            return ANExtensionElement(new_gen, red_back(field.gen())/den) 
    20823572        else: 
    20833573            fld = gen.field() 
     
    20853575            fpf = self._poly.factors() 
    20863576            # print fpf 
    2087             def find_fn(factor, rif): 
    2088                 rif_poly = rif['x'] 
    2089                 gen_val = gen.interval_fast(rif) 
    2090                 self_val = self.interval_fast(rif) 
    2091                 ip = rif_poly([c.polynomial()(gen_val) for c in factor]) 
     3577            def find_fn(factor, prec): 
     3578                # XXX 
     3579                ifield = (ComplexIntervalField if self.is_complex() else RealIntervalField)(prec) 
     3580                if_poly = ifield['x'] 
     3581                gen_val = gen._interval_fast(prec) 
     3582                self_val = self._interval_fast(prec) 
     3583                ip = if_poly([c.polynomial()(gen_val) for c in factor]) 
    20923584                return ip(self_val) 
    20933585            my_factor = find_zero_result(find_fn, fpf) 
     
    20973589 
    20983590            if my_factor.degree() == 1: 
    2099                 return AlgebraicRealNumberExtensionElement(gen, -my_factor[0]) 
     3591                return ANExtensionElement(gen, -my_factor[0]) 
    21003592 
    21013593            # rnfequation needs a monic polynomial with integral coefficients. 
     
    21053597 
    21063598 
    2107             pari_nf = pari_nf_hack(gen.field()) 
     3599            pari_nf = gen.pari_field() 
    21083600             
    21093601            # print pari_nf[0] 
     
    21323624            new_nf_a = new_nf.gen() 
    21333625             
    2134             def intv_fn(rif): 
    2135                 return red_elt(gen.interval_fast(rif) * k + self.interval_fast(rif) * den) 
    2136             new_intv = isolating_interval(intv_fn, red_pol) 
    2137  
    2138             root = AlgebraicRealNumberRoot(QQx(red_pol), new_intv) 
     3626            def intv_fn(prec): 
     3627                return conjugate_expand(red_elt(gen._interval_fast(prec) * k + self._interval_fast(prec) * den)) 
     3628            new_intv = conjugate_shrink(isolating_interval(intv_fn, red_pol)) 
     3629 
     3630            root = ANRoot(QQx(red_pol), new_intv) 
    21393631            new_gen = AlgebraicGenerator(new_nf, root) 
    21403632            red_back_a = red_back(new_nf.gen()) 
    21413633            new_poly = ((QQx_x - k * self_pol_sage)(red_back_a)/den) 
    2142             return AlgebraicRealNumberExtensionElement(new_gen, new_poly) 
     3634            return ANExtensionElement(new_gen, new_poly) 
    21433635         
    21443636    def _more_precision(self): 
     
    21503642        self._interval = self.refine_interval(self._interval, prec*2) 
    21513643 
    2152     def interval_fast(self, field): 
     3644    def _interval_fast(self, prec): 
    21533645        """ 
    21543646        Given a RealIntervalField, compute the value of this number 
     
    21573649        in the computation.) 
    21583650        """ 
    2159         if field.prec() == self._interval.prec(): 
     3651        if prec == self._interval.prec(): 
    21603652            return self._interval 
    2161         if field.prec() < self._interval.prec(): 
    2162             return field(self._interval) 
     3653        if prec < self._interval.prec(): 
     3654            return type(self._interval.parent())(prec)(self._interval) 
    21633655        self._more_precision() 
    2164         return self.interval_fast(field) 
    2165  
    2166 unit_generator = AlgebraicGenerator(None, AlgebraicRealNumberRoot(AAPoly.gen() - 1, RIF(1))) 
    2167  
    2168 class AlgebraicRealNumberExtensionElement(AlgebraicRealNumberDescr): 
     3656        return self._interval_fast(prec) 
     3657 
     3658qq_generator = AlgebraicGenerator(None, ANRoot(AAPoly.gen(), RIF(0))) 
     3659 
     3660_cyclotomic_gen_cache = {} 
     3661def cyclotomic_generator(n): 
     3662    try: 
     3663        return _cyclotomic_gen_cache[n] 
     3664    except KeyError: 
     3665        assert(n > 2 and n != 4) 
     3666        n = ZZ(n) 
     3667        f = CyclotomicField(n) 
     3668        v = ANRootOfUnity(~n, QQ_1) 
     3669        g = AlgebraicGenerator(f, v) 
     3670        g.set_cyclotomic(n) 
     3671        _cyclotomic_gen_cache[n] = g 
     3672        return g 
     3673 
     3674class ANExtensionElement(ANDescr): 
    21693675    """ 
    2170     The subclass of AlgebraicRealNumberDescr that represents a number field 
     3676    The subclass of ANDescr that represents a number field 
    21713677    element in terms of a specific generator.  Consists of a polynomial 
    21723678    with rational coefficients in terms of the generator, and the 
     
    21743680    """ 
    21753681 
    2176     # XXX Should override __new__, and return an AlgebraicRealNumberRational 
    2177     # if the value is rational. 
     3682    def __new__(self, generator, value): 
     3683        try: 
     3684            return ANRational(value._rational_()) 
     3685        except TypeError: 
     3686            if generator is QQbar_I_generator and value[0].is_zero(): 
     3687                return ANRootOfUnity(QQ_1_4, value[1]) 
     3688            return ANDescr.__new__(self)             
    21783689 
    21793690    def __init__(self, generator, value): 
    21803691        self._generator = generator 
    21813692        self._value = value 
     3693        self._exactly_real = not generator.is_complex() 
    21823694     
    21833695    def _repr_(self): 
    21843696        return '%s where %s = 0 and a in %s'%(self._value, 
    21853697                                              self._generator.field().polynomial()._repr(name='a'), 
    2186                                               self._generator.interval_fast(RIF)) 
     3698                                              self._generator._interval_fast(53)) 
     3699 
     3700    def kind(self): 
     3701        if self._generator is QQbar_I_generator: 
     3702            return 'gaussian' 
     3703        else: 
     3704            return 'element' 
     3705 
     3706    def is_complex(self): 
     3707        return not self._exactly_real 
     3708 
     3709    def is_exact(self): 
     3710        return True 
     3711 
     3712    def is_field_element(self): 
     3713        return True 
    21873714 
    21883715    def generator(self): 
    21893716        return self._generator 
    21903717 
    2191     def is_exact(self): 
    2192         return True 
    2193  
    2194     def is_field_element(self): 
    2195         return True 
    2196  
    2197     def field_parent(self): 
    2198         return self._generator 
    2199  
    22003718    def exactify(self): 
    22013719        return self 
    22023720 
    2203     def rational_value(self): 
    2204         poly = self._value.polynomial() 
    2205         assert(poly.is_constant()) 
    2206         return poly[0] 
    2207  
    2208     def is_irrational(self): 
    2209         return self._value.polynomial().degree() >= 1 
    2210  
    22113721    def field_element_value(self): 
    22123722        return self._value 
     
    22153725        return self._value.minpoly() 
    22163726 
    2217     def interval_fast(self, field): 
    2218         gen_val = self._generator.interval_fast(field) 
    2219         # XXX Coercion to field() below is necessary in case this is 
    2220         # a constant polynomial (that is, this is a rational number). 
    2221         # If we maintain the invariant that AlgebraicRealNumberExtensionElement 
    2222         # values are never rational, then the coercion is redundant. 
    2223         return field(self._value.polynomial()(gen_val)) 
    2224  
    2225 ax = AAPoly.gen() 
     3727    def _interval_fast(self, prec): 
     3728        gen_val = self._generator._interval_fast(prec) 
     3729        v = self._value.polynomial()(gen_val) 
     3730        if self._exactly_real and is_ComplexIntervalFieldElement(v): 
     3731            return v.real() 
     3732        return v 
     3733 
     3734    def neg(self, n): 
     3735        return ANExtensionElement(self._generator, -self._value) 
     3736 
     3737    def invert(self, n): 
     3738        return ANExtensionElement(self._generator, ~self._value) 
     3739 
     3740    def conjugate(self, n): 
     3741        if self._exactly_real: 
     3742            return self 
     3743        else: 
     3744            return ANExtensionElement(self._generator.conjugate(), self._value) 
     3745 
     3746    def norm(self, n): 
     3747        if self._exactly_real: 
     3748            return (n*n)._descr 
     3749        elif self._generator is QQbar_I_generator: 
     3750            return ANRational(self._value.norm()) 
     3751        else: 
     3752            return ANUnaryExpr(n, 'norm') 
     3753 
     3754    def abs(self, n): 
     3755        return AlgebraicReal(self.norm(self)).sqrt()._descr 
     3756 
     3757    def rational_argument(self, n): 
     3758        """ 
     3759        If the argument of self is 2*pi times some rational number, 
     3760        return that rational; otherwise, return None. 
     3761        """ 
     3762 
     3763        # If the argument of self is 2*pi times some rational number a/b, 
     3764        # then self/abs(self) is a root of the b'th cyclotomic polynomial. 
     3765        # This implies that the algebraic degree of self is at least 
     3766        # phi(b).  Working backward, we know that the algebraic degree 
     3767        # of self is at most the degree of the generator, so that gives 
     3768        # an upper bound on phi(b).  According to 
     3769        # http://mathworld.wolfram.com/TotientFunction.html, 
     3770        # phi(b) >= sqrt(b) for b > 6; this gives us an upper bound on b. 
     3771        # We then check to see if this is possible; if so, we test 
     3772        # to see if it actually holds. 
     3773 
     3774        if self._exactly_real: 
     3775            if n > 0: 
     3776                return 0 
     3777            else: 
     3778                return QQ(1)/2 
     3779 
     3780        gen_degree = self._generator._field.degree() 
     3781        if gen_degree <= 2: 
     3782            max_b = 6 
     3783        else: 
     3784            max_b = gen_degree*gen_degree 
     3785        rat_arg_fl = ComplexIntervalField(100)(n).argument() / RealIntervalField(100).pi() / 2 
     3786        rat_arg = rat_arg_fl.simplest_rational() 
     3787        if rat_arg.denominator() > max_b: 
     3788            return None 
     3789        n_exp = n ** rat_arg.denominator() 
     3790        if n_exp.real() > 0 and n_exp.imag() == 0: 
     3791            return rat_arg 
     3792        # Strictly speaking, we need to look for the second-simplest 
     3793        # rational in rat_arg_fl and make sure its denominator is > max_b. 
     3794        # For now, we just punt. 
     3795        raise NotImplementedError 
     3796 
     3797    def gaussian_value(self): 
     3798        assert(self._generator is QQbar_I_generator) 
     3799        return self._value 
     3800 
     3801class ANUnaryExpr(ANDescr): 
     3802    def __init__(self, arg, op): 
     3803        self._arg = arg 
     3804        self._op = op 
     3805 
     3806    def kind(self): 
     3807        return 'other' 
     3808 
     3809    def _interval_fast(self, prec): 
     3810        op = self._op 
     3811 
     3812        if op == '-': 
     3813            return -self._arg._interval_fast(prec) 
     3814 
     3815        if op == '~': 
     3816            return ~self._arg._interval_fast(prec) 
     3817 
     3818        if op == 'real': 
     3819            v = self._arg._interval_fast(prec) 
     3820            if is_ComplexIntervalFieldElement(v): 
     3821                return v.real() 
     3822            else: 
     3823                return v 
     3824 
     3825        if op == 'imag': 
     3826            v = self._arg._interval_fast(prec) 
     3827            if is_ComplexIntervalFieldElement(v): 
     3828                return v.imag() 
     3829            else: 
     3830                return RealIntervalField(prec)(0) 
     3831 
     3832        if op == 'abs': 
     3833            return abs(self._arg._interval_fast(prec)) 
     3834 
     3835        if op == 'norm': 
     3836            v = self._arg._interval_fast(prec) 
     3837            if is_ComplexIntervalFieldElement(v): 
     3838                return v.norm() 
     3839            else: 
     3840                return v.square() 
     3841 
     3842        if op == 'conjugate': 
     3843            v = self._arg._interval_fast(prec) 
     3844            if is_ComplexIntervalFieldElement(v): 
     3845                return v.conjugate() 
     3846            else: 
     3847                return v 
     3848 
     3849        raise NotImplementedError 
     3850 
     3851    def exactify(self): 
     3852        op = self._op 
     3853        arg = self._arg 
     3854 
     3855        if op == '-': 
     3856            arg.exactify() 
     3857            return arg._descr.neg(None) 
     3858 
     3859        if op == '~': 
     3860            arg.exactify() 
     3861            return arg._descr.invert(None) 
     3862 
     3863        if op == 'real': 
     3864            arg.exactify() 
     3865            rv = (arg + arg.conjugate()) / 2 
     3866            rv.exactify() 
     3867            rvd = rv._descr 
     3868            rvd._exactly_real = True 
     3869            return rvd 
     3870 
     3871        if op == 'imag': 
     3872            arg.exactify() 
     3873            iv = QQbar_I * (arg.conjugate() - arg) / 2 
     3874            iv.exactify() 
     3875            ivd = iv._descr 
     3876            ivd._exactly_real = True 
     3877            return ivd 
     3878 
     3879        if op == 'abs': 
     3880            arg.exactify() 
     3881            if arg.parent() is AA: 
     3882                if arg.sign() > 0: 
     3883                    return arg._descr 
     3884                else: 
     3885                    return arg._descr.neg(None) 
     3886 
     3887            v = (arg * arg.conjugate()).sqrt() 
     3888            v.exactify() 
     3889            vd = v._descr 
     3890            vd._exactly_real = True 
     3891            return vd 
     3892             
     3893        if op == 'norm': 
     3894            arg.exactify() 
     3895            v = arg * arg.conjugate() 
     3896            v.exactify() 
     3897            vd = v._descr 
     3898            vd._exactly_real = True 
     3899            return vd 
     3900 
     3901        if op == 'conjugate': 
     3902            arg.exactify() 
     3903            return arg._descr.conjugate(None) 
     3904 
     3905class ANBinaryExpr(ANDescr): 
     3906    def __init__(self, left, right, op): 
     3907        self._left = left 
     3908        self._right = right 
     3909        self._op = op 
     3910        self._complex = True 
     3911 
     3912    def kind(self): 
     3913        return 'other' 
     3914 
     3915    def is_complex(self): 
     3916        return self._complex 
     3917 
     3918    def _interval_fast(self, prec): 
     3919        op = self._op 
     3920 
     3921        lv = self._left._interval_fast(prec) 
     3922        rv = self._right._interval_fast(prec) 
     3923 
     3924        if not (is_ComplexIntervalFieldElement(lv) or is_ComplexIntervalFieldElement(rv)): 
     3925            self._complex = False 
     3926 
     3927        if op == '-': 
     3928            return lv - rv 
     3929 
     3930        if op == '+': 
     3931            return lv + rv 
     3932 
     3933        if op == '/': 
     3934            return lv / rv 
     3935 
     3936        if op == '*': 
     3937            return lv * rv 
     3938 
     3939        raise NotImplementedError 
     3940 
     3941    def exactify(self): 
     3942        left = self._left 
     3943        right = self._right 
     3944        left.exactify() 
     3945        right.exactify() 
     3946        gen = left._exact_field().union(right._exact_field()) 
     3947        left_value = gen(left._exact_value()) 
     3948        right_value = gen(right._exact_value()) 
     3949 
     3950        op = self._op 
     3951 
     3952        if op == '+': 
     3953            value = left_value + right_value 
     3954        if op == '-': 
     3955            value = left_value - right_value 
     3956        if op == '*': 
     3957            value = left_value * right_value 
     3958        if op == '/': 
     3959            value = left_value / right_value 
     3960 
     3961        if gen.is_trivial(): 
     3962            return ANRational(value) 
     3963        else: 
     3964            return ANExtensionElement(gen, value) 
     3965 
     3966ax = QQbarPoly.gen() 
    22263967# def heptadecagon(): 
    22273968#     # Compute the exact (x,y) coordinates of the vertices of a 34-gon. 
     
    22744015 
    22754016 
    2276 def pari_nf_hack(k): 
    2277     f = k.pari_polynomial().subst('x','y') 
    2278     return f.nfinit(1) 
    2279  
    2280 AA_1_123456789 = AA(~ZZ(123456789)) 
    2281  
     4017RR_1_10 = RR(ZZ(1)/10) 
     4018QQ_0 = QQ(0) 
     4019QQ_1 = QQ(1) 
     4020QQ_1_2 = QQ(1)/2 
     4021QQ_1_4 = QQ(1)/4 
     4022 
     4023QQbar_I_nf = QuadraticField(-1, 'I') 
     4024# XXX change ANRoot to ANRootOfUnity below 
     4025QQbar_I_generator = AlgebraicGenerator(QQbar_I_nf, ANRoot(AAPoly.gen()**2 + 1, CIF(0, 1))) 
     4026QQbar_I = AlgebraicNumber(ANExtensionElement(QQbar_I_generator, QQbar_I_nf.gen())) 
     4027_cyclotomic_gen_cache[4] = QQbar_I_generator 
     4028QQbar_I_generator.set_cyclotomic(4) 
     4029 
     4030AA_hash_offset = AA(~ZZ(123456789)) 
     4031 
     4032QQbar_hash_offset = AlgebraicNumber(ANExtensionElement(QQbar_I_generator, ~ZZ(123456789) + QQbar_I_nf.gen()/ZZ(987654321))) 
     4033 
     4034ZZX_x = ZZ['x'].gen() 
     4035 
     4036# This is used in the _algebraic_ method of the golden_ratio constant, 
     4037# in sage/functions/constants.py 
     4038AA_golden_ratio = None 
     4039 
     4040def get_AA_golden_ratio(): 
     4041    global AA_golden_ratio 
     4042    if AA_golden_ratio is None: 
     4043        AA_golden_ratio_nf = NumberField(ZZX_x**2 - ZZX_x - 1, 'phi') 
     4044        AA_golden_ratio_generator = AlgebraicGenerator(AA_golden_ratio_nf, ANRoot(AAPoly.gen()**2 - AAPoly.gen() - 1, RIF(1.618, 1.6181))) 
     4045        AA_golden_ratio = AlgebraicReal(ANExtensionElement(AA_golden_ratio_generator, AA_golden_ratio_nf.gen())) 
     4046    return AA_golden_ratio 
  • sage/rings/all.py

    r7425 r7427  
    9292# with the reals) 
    9393from algebraic_real import (AlgebraicRealField, is_AlgebraicRealField, AA, 
    94                             AlgebraicRealNumber, is_AlgebraicRealNumber) 
     94                            AlgebraicReal, is_AlgebraicReal, 
     95                            AlgebraicField, is_AlgebraicField, QQbar, 
     96                            AlgebraicNumber, is_AlgebraicNumber) 
    9597 
    9698# Intervals 
  • sage/rings/complex_field.py

    r7425 r7427  
    2727 
    2828NumberFieldElement_quadratic = None 
     29AlgebraicNumber_base = None 
     30AlgebraicNumber = None 
     31AlgebraicReal = None 
    2932def late_import(): 
    3033    global NumberFieldElement_quadratic 
     34    global AlgebraicNumber_base 
     35    global AlgebraicNumber 
     36    global AlgebraicReal 
    3137    if NumberFieldElement_quadratic is None: 
    3238        import sage.rings.number_field.number_field_element_quadratic as nfeq 
    3339        NumberFieldElement_quadratic = nfeq.NumberFieldElement_quadratic 
     40        import sage.rings.algebraic_real 
     41        AlgebraicNumber_base = sage.rings.algebraic_real.AlgebraicNumber_base 
     42        AlgebraicNumber = sage.rings.algebraic_real.AlgebraicNumber 
     43        AlgebraicReal = sage.rings.algebraic_real.AlgebraicReal 
    3444 
    3545def is_ComplexField(x): 
     
    210220        except AttributeError: 
    211221            pass 
     222        late_import() 
     223        if isinstance(x, AlgebraicNumber_base): 
     224            return self(x) 
    212225        return self._coerce_try(x, self._real_field()) 
    213226 
  • sage/rings/real_mpfi.pyx

    r7425 r7427  
    405405        be adjacent floating-point numbers that surround the given value. 
    406406        """ 
    407         import sage.rings.algebraic_real 
    408  
    409407        if isinstance(x, real_mpfr.RealNumber): 
    410408            P = x.parent() 
     
    747745                mpfi_interv_fr(self.value, <mpfr_t> rn.value, <mpfr_t> rn1.value) 
    748746                 
    749         elif isinstance(x, sage.rings.algebraic_real.AlgebraicRealNumber): 
     747        elif isinstance(x, sage.rings.algebraic_real.AlgebraicReal): 
    750748            d = x.interval(self._parent) 
    751749            mpfi_set(self.value, d.value) 
  • sage/rings/real_mpfr.pyx

    r7385 r7427  
    256256             * the field of algebraic reals 
    257257        """ 
    258         import sage.rings.algebraic_real 
    259  
    260258        if isinstance(x, RealNumber): 
    261259            P = x.parent() 
     
    264262            else: 
    265263                raise TypeError, "Canonical coercion from lower to higher precision not defined" 
    266         elif isinstance(x, (Integer, Rational, sage.rings.algebraic_real.AlgebraicRealNumber)): 
     264        elif isinstance(x, (Integer, Rational)): 
    267265            return self(x) 
    268266        elif isinstance(x,QuadDoubleElement) and self.__prec <=212: 
    269267            return self(x) 
    270268        elif is_RealDoubleElement(x) and self.__prec <= 53: 
     269            return self(x) 
     270        import sage.rings.algebraic_real 
     271        if isinstance(x, sage.rings.algebraic_real.AlgebraicReal): 
    271272            return self(x) 
    272273        raise TypeError 
     
    622623 
    623624    cdef _set(self, x, int base): 
    624         import sage.rings.algebraic_real 
    625  
    626625        # This should not be called except when the number is being created. 
    627626        # Real Numbers are supposed to be immutable.  
     
    653652            qd = x 
    654653            self._set_from_qd(qd) 
    655         elif isinstance(x, sage.rings.algebraic_real.AlgebraicRealNumber): 
    656             d = x.real(parent) 
    657             mpfr_set(self.value, d.value, parent.rnd) 
    658654        elif hasattr(x, '_mpfr_'): 
    659655            return x._mpfr_(self) 
Note: See TracChangeset for help on using the changeset viewer.