Changeset 7426:40eaefca4b52


Ignore:
Timestamp:
11/25/07 12:53:58 (5 years ago)
Author:
Carl Witty <cwitty@…>
Branch:
default
Message:

Implement complex root isolation.

Location:
sage/rings/polynomial
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • sage/rings/polynomial/polynomial_element.pyx

    r7423 r7426  
    3636import sage.rings.complex_field 
    3737import sage.rings.fraction_field_element 
    38 from sage.rings.infinity import infinity 
     38import sage.rings.infinity as infinity 
    3939#import sage.misc.misc as misc 
    4040from sage.misc.sage_eval import sage_eval 
     
    7474 
    7575cdef object is_AlgebraicRealField 
     76cdef object NumberField_quadratic 
     77cdef object is_ComplexIntervalField 
    7678 
    7779cdef void late_import(): 
    7880    # A hack to avoid circular imports. 
    7981    global is_AlgebraicRealField 
     82    global NumberField_quadratic 
     83    global is_ComplexIntervalField 
    8084 
    8185    if is_AlgebraicRealField is not None: 
     
    8488    import sage.rings.algebraic_real 
    8589    is_AlgebraicRealField = sage.rings.algebraic_real.is_AlgebraicRealField 
     90    import sage.rings.number_field.number_field 
     91    NumberField_quadratic = sage.rings.number_field.number_field.NumberField_quadratic 
     92    import sage.rings.complex_interval_field 
     93    is_ComplexIntervalField = sage.rings.complex_interval_field.is_ComplexIntervalField 
    8694 
    8795cdef class Polynomial(CommutativeAlgebraElement): 
     
    19091917            +Infinity 
    19101918        """ 
    1911         return infinity 
     1919        return infinity.infinity 
    19121920 
    19131921    def padded_list(self, n=None): 
     
    22952303        at the end of the docstring about this. 
    22962304 
    2297         If the output ring is a RealIntervalField of a given 
    2298         precision, then the answer will always be correct (or an 
    2299         exception will be raised, if a case is not implemented).  Each 
    2300         root will be contained in one of the returned intervals, 
    2301         and the intervals will be disjoint.  (The returned intervals 
    2302         may be of higher precision than the specified output ring.) 
     2305        If the output ring is a RealIntervalField or 
     2306        ComplexIntervalField of a given precision, then the answer 
     2307        will always be correct (or an exception will be raised, if a 
     2308        case is not implemented).  Each root will be contained in one 
     2309        of the returned intervals, and the intervals will be disjoint. 
     2310        (The returned intervals may be of higher precision than the 
     2311        specified output ring.) 
    23032312         
    23042313        At the end of this docstring (after the examples) is a description 
     
    24562465            sage: f.roots(ring=RIF, multiplicities=False) 
    24572466            [[-0.618033988749894848204586834365642 .. -0.618033988749894848204586834365629], [0.999999999999999999999999999999987 .. 1.00000000000000000000000000000003], [1.61803398874989484820458683436561 .. 1.61803398874989484820458683436565]] 
     2467 
     2468        Examples using complex root isolation: 
     2469            sage: x = polygen(ZZ) 
     2470            sage: p = x^5 - x - 1 
     2471            sage: p.roots() 
     2472            [] 
     2473            sage: p.roots(ring=CIF) 
     2474            [([1.1673039782614185 .. 1.1673039782614188], 1), ([0.18123244446987518 .. 0.18123244446987558] + [1.0839541013177103 .. 1.0839541013177110]*I, 1), ([0.18123244446987518 .. 0.18123244446987558] - [1.0839541013177103 .. 1.0839541013177110]*I, 1), ([-0.76488443360058489 .. -0.76488443360058455] + [0.35247154603172609 .. 0.35247154603172643]*I, 1), ([-0.76488443360058489 .. -0.76488443360058455] - [0.35247154603172609 .. 0.35247154603172643]*I, 1)] 
     2475            sage: p.roots(ring=ComplexIntervalField(200)) 
     2476            [([1.1673039782614186842560458998548421807205603715254890391400816 .. 1.1673039782614186842560458998548421807205603715254890391400829], 1), ([0.18123244446987538390180023778112063996871646618462304743773153 .. 0.18123244446987538390180023778112063996871646618462304743773341] + [1.0839541013177106684303444929807665742736402431551156543011306 .. 1.0839541013177106684303444929807665742736402431551156543011344]*I, 1), ([0.18123244446987538390180023778112063996871646618462304743773153 .. 0.18123244446987538390180023778112063996871646618462304743773341] - [1.0839541013177106684303444929807665742736402431551156543011306 .. 1.0839541013177106684303444929807665742736402431551156543011344]*I, 1), ([-0.76488443360058472602982318770854173032899665194736756700777454 .. -0.76488443360058472602982318770854173032899665194736756700777...] + [0.35247154603172624931794709140258105439420648082424733283769... .. 0.35247154603172624931794709140258105439420648082424733283769...]*I, 1), ([-0.76488443360058472602982318770854173032899665194736756700777454 .. -0.76488443360058472602982318770854173032899665194736756700777204] - [0.35247154603172624931794709140258105439420648082424733283769122 .. 0.35247154603172624931794709140258105439420648082424733283769341]*I, 1)] 
     2477 
     2478        Note that coefficients in a number field with defining polynomial 
     2479        x^2 + 1 are considered to be Gaussian rationals (with the generator 
     2480        mapping to +I), if you ask for complex roots. 
     2481 
     2482            sage: K.<im> = NumberField(x^2 + 1) 
     2483            sage: y = polygen(K) 
     2484            sage: p = y^4 - 2 - im 
     2485            sage: p.roots(ring=CC) 
     2486            [(-1.2146389322441... - 0.14142505258239...*I, 1), (-0.14142505258239... + 1.2146389322441...*I, 1), (0.14142505258239... - 1.2146389322441...*I, 1), (1.2146389322441... + 0.14142505258239...*I, 1)] 
     2487            sage: p = p^2 * (y^2 - 2) 
     2488            sage: p.roots(ring=CIF) 
     2489            [([-1.4142135623730952 .. -1.4142135623730949], 1), ([1.4142135623730949 .. 1.4142135623730952], 1), ([-1.2146389322441827 .. -1.2146389322441821] - [0.14142505258239376 .. 0.14142505258239399]*I, 2), ([-0.14142505258239399 .. -0.14142505258239376] + [1.2146389322441821 .. 1.2146389322441827]*I, 2), ([0.14142505258239376 .. 0.14142505258239399] - [1.2146389322441821 .. 1.2146389322441827]*I, 2), ([1.2146389322441821 .. 1.2146389322441827] + [0.14142505258239376 .. 0.14142505258239399]*I, 2)] 
    24582490 
    24592491        There are many combinations of floating-point input and output 
     
    25032535        Algorithms used: 
    25042536 
    2505         For brevity, we will use RR to mean any RealField of any precision; 
    2506         similarly for CC and CIF. 
     2537        For brevity, we will use RR to mean any RealField of any 
     2538        precision; similarly for RIF, CC, and CIF.  Since Sage has no 
     2539        specific implementation of Gaussian rationals (or of number 
     2540        fields with embedding, at all), when we refer to Gaussian 
     2541        rationals below we will accept any number field with defining 
     2542        polynomial x^2+1, mapping the field generator to +I. 
    25072543 
    25082544        We call the base ring of the polynomial K, and the ring given 
     
    25232559        this method gives.) 
    25242560 
    2525         If L is floating-point and K is not, then we attempt to 
    2526         change the polynomial ring to L (using .change_ring()) 
    2527         (or, if L is complex, to the corresponding real field). 
    2528         Then we use either Pari or numpy as specified above. 
     2561        If L is CIF, and K is ZZ, QQ, AA, or the Gaussian rationals, 
     2562        then the root isolation algorithm 
     2563        sage.rings.polynomial.complex_roots.complex_roots() is used. 
     2564        (You can call complex_roots() directly to get more control than 
     2565        this method gives.) 
     2566 
     2567        If L is floating-point and K is not, then we attempt to change 
     2568        the polynomial ring to L (using .change_ring()) (or, if L is 
     2569        complex and K is not, to the corresponding real field).  Then 
     2570        we use either Pari or numpy as specified above. 
    25292571 
    25302572        For all other cases where K is different than L, we just use 
     
    25332575        The next method is to attempt to factor the polynomial. 
    25342576        If this succeeds, then for every degree-one factor a*x+b, we 
    2535         add -b/a as a root. 
     2577        add -b/a as a root (as long as this quotient is actually in 
     2578        the desired ring). 
    25362579 
    25372580        If factoring over K is not implemented, and K is finite, then 
     
    25632606        if L is None: L = K 
    25642607         
     2608        late_import() 
     2609 
    25652610        input_fp = (is_RealField(K) 
    25662611                    or is_ComplexField(K)  
     
    25752620        output_complex = (is_ComplexField(L) 
    25762621                          or is_ComplexDoubleField(L)) 
     2622        input_gaussian = (isinstance(K, NumberField_quadratic) 
     2623                          and list(K.polynomial()) == [1, 0, 1]) 
    25772624 
    25782625        if input_fp and output_fp: 
     
    26342681                return rts 
    26352682 
    2636         late_import() 
    2637  
    26382683        if L != K or is_AlgebraicRealField(L): 
    2639             # So far, the only "special" implementation is for K exact 
    2640             # and L either AA or a real interval field. 
     2684            # So far, the only "special" implementations are for real 
     2685            # and complex root isolation. 
    26412686            if (is_IntegerRing(K) or is_RationalField(K) 
    26422687                or is_AlgebraicRealField(K)) and \ 
     
    26692714                    return [rt for (rt, mult) in rts] 
    26702715 
    2671             if output_fp and output_complex: 
     2716            if (is_IntegerRing(K) or is_RationalField(K) 
     2717                or is_AlgebraicRealField(K) or input_gaussian) and \ 
     2718                (is_ComplexIntervalField(L)): 
     2719 
     2720                from sage.rings.polynomial.complex_roots import complex_roots 
     2721 
     2722                rts = complex_roots(self, min_prec=L.prec()) 
     2723 
     2724                if multiplicities: 
     2725                    return rts 
     2726                else: 
     2727                    return [rt for (rt, mult) in rts] 
     2728 
     2729            if output_fp and output_complex and not input_gaussian: 
    26722730                # If we want the complex roots, and the input is not 
    2673                 # floating point, we convert to a real polynomial. 
    2674                 # I think this works for now, because there are no 
    2675                 # non-floating-point complex types in Sage.  Hopefully 
    2676                 # someday we will have Gaussian integers and rationals, 
    2677                 # and this will have to change then. 
     2731                # floating point, we convert to a real polynomial 
     2732                # (except when the input coefficients are Gaussian rationals). 
    26782733                if is_ComplexDoubleField(L): 
    26792734                    real_field = RDF 
     
    28202875 
    28212876        if not self: 
    2822             return infinity 
    2823  
    2824         if p is infinity: 
     2877            return infinity.infinity 
     2878 
     2879        if p is infinity.infinity: 
    28252880            return -self.degree() 
    28262881 
     
    30613116         
    30623117        coeffs = self.coeffs() 
    3063         if p == infinity: 
     3118        if p == infinity.infinity: 
    30643119            return RR(max([abs(i) for i in coeffs])) 
    30653120         
Note: See TracChangeset for help on using the changeset viewer.