Ticket #1275: 7427-for-review.patch

File 7427-for-review.patch, 178.1 kB (added by cwitty, 1 year ago)
  • a/sage/calculus/calculus.py

    old new  
    28302830    def _recursive_sub_over_ring(self, kwds, ring): 
    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 
    28352870class SymbolicPolynomial(Symbolic_object): 
     
    30733108        rops = [op._real_rqdf_(field) for op in self._operands] 
    30743109        return self._operator(*rops) 
    30753110 
     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) 
     3142 
    30763143    def _is_atomic(self): 
    30773144        try: 
    30783145            return self._atomic 
     
    40114078        else: 
    40124079            return z 
    40134080 
     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         
     4104 
    40144105class PrimitiveFunction(SymbolicExpression): 
    40154106    def __init__(self, needs_braces=False): 
    40164107        SymbolicExpression.__init__(self) 
  • a/sage/functions/constants.py

    old new  
    537537    def _real_double_(self, R): 
    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) 
    542546 
     
    691695     
    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() 
    696704     
  • a/sage/rings/algebraic_real.py

    old new  
    11""" 
    2 Field of Algebraic Real
     2Field of Algebraic Number
    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  
    1933RealIntervalFieldElement) which encloses exactly one root, and 
     
    2236number given as the root of an irreducible polynomial with integral 
    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, 
    2950comparisons compute the two algebraic numbers with 128-bit precision 
     
    4465EXAMPLES: 
    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 
    5073For a monic cubic polynomial x^3 + b*x^2 + c*x + d with roots 
     
    82105    sage: disc1(b, c, d) == disc2(s1, s2, s3) 
    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 
    87169    sage: phi = (1 + sqrt(AA(5))) / 2 
     
    101183    sage: rt23 * rt35 == rt25 
    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 
    114198    True 
     
    116200    sage: phi 
    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 
    126268    sage: rhs_den = (alpha^35 - 1) * (alpha^15 - 1)^2 * (alpha^14 - 1)^2 * (alpha^5 - 1)^6 * alpha^68 
     
    128270    sage: lhs 
    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] 
    140282""" 
     
    143285from sage.structure.sage_object import SageObject 
    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 
    157308_obj = None 
     
    162313            _obj = sage.rings.ring.Field.__new__(cls) 
    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) 
    174  
    175     def _repr_(self): 
    176         return "Algebraic Field" 
     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) 
     409 
     410    def _repr_(self): 
     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): 
    193418        if isinstance(x, (int, long, sage.rings.integer.Integer, 
    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): 
    199434        try: 
     
    201436        except TypeError: 
    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), ) 
    209441 
     
    216448    def ngens(self): 
    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): 
    232455        if n == 1: 
     
    235458            return self(-1) 
    236459        else: 
    237460            raise ValueError, "no n-th root of unity in algebraic reals" 
    238  
    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) 
    261461 
    262462    def polynomial_root(self, poly, interval, multiplicity=1): 
    263463        """ 
     
    279479        or wrong answers may result. 
    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) 
    290491            sage: r = AA.polynomial_root(p, RIF(9/10, 11/10), multiplicity=7) 
     
    296497            sage: r; r == sqrt(AA(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): 
    303516    return isinstance(F, AlgebraicRealField) 
    304517 
    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): 
    319688    """ 
     
    327696 
    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 
    332704 
     
    337709        (2, x^2 + x + 1) 
    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() 
    342719    if d == 1: 
     
    401778 
    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 
    413791    Returns an interval containing at most one root of pol. 
     
    416794        sage: from sage.rings.algebraic_real import isolating_interval 
    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 
    422800    And an example that requires more precision: 
    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] 
    427     """ 
    428     for rif in rif_seq(): 
    429         intv = intv_fn(rif) 
     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 
     810    """ 
     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 
    432818        # interval intv.  We know (because it is a precondition of 
     
    434820        # interval, so we only need to verify that it has at most one 
    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: 
    499839        sage: from sage.rings.algebraic_real import find_zero_result 
     
    502842        sage: p1 = x - 1 
    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]) 
    506         True 
    507     """ 
    508     for rif in rif_seq(): 
     845        sage: p2 == find_zero_result(lambda p, prec: p(RealIntervalField(prec)(1 + delta)), [p1, p2, p3]) 
     846        True 
     847    """ 
     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 
    516856                    break 
     
    520860        if result is None: 
    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.