Changeset 7807:ab81cbfbb27b


Ignore:
Timestamp:
12/01/07 22:12:58 (6 years ago)
Author:
Carl Witty <cwitty@…>
Branch:
default
Message:

Robert Bradshaw's sqrt() for complex intervals, plus some docstrings and doctests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sage/rings/complex_interval.pyx

    r7471 r7807  
    396396    def __pow__(self, right, modulus): 
    397397        """ 
     398        Compute $x^y$.  If y is an integer, uses multiplication; 
     399        otherwise, uses the standard definition exp(log(x)*y). 
     400        WARNING: If the interval x crosses the negative real axis, 
     401        then we use a non-standard definition of log() (see 
     402        the docstring for argument() for more details).  This means 
     403        that we will not select the principal value of the power, 
     404        for part of the input interval (and that we violate the 
     405        interval guarantees). 
     406 
    398407        EXAMPLES: 
    399408            sage: C.<i> = ComplexIntervalField(20) 
     
    405414            [8.0000000 .. 8.0000000] - [8.0000000 .. 8.0000000]*I 
    406415            sage: (1+i)^(1+i) 
    407             Traceback (most recent call last): 
    408             ... 
    409             TypeError: Can only raise ComplexIntervalField to integral powers 
     416            [0.27395439 .. 0.27396012] + [0.58369827 .. 0.58370495]*I 
    410417            sage: a.parent() 
    411418            Complex Interval Field with 20 bits of precision 
    412419            sage: (2+i)^(-39) 
    413420            [1.6873519e-14 .. 1.6879375e-14] + [1.6273278e-14 .. 1.6279215e-14]*I 
     421 
     422        If the interval crosses the negative real axis, then we don't 
     423        use the standard branch cut (and we violate the interval 
     424        guarantees): 
     425            sage: CIF(-7, RIF(-1, 1)) ^ CIF(0.3) 
     426            [0.99109735947126309 .. 1.1179269966896264] + [1.4042388462787560 .. 1.4984624123369835]*I 
     427            sage: CIF(-7, -1) ^ CIF(0.3) 
     428            [1.1179269966896254 .. 1.1179269966896264] - [1.4085007145753596 .. 1.4085007145753606]*I 
    414429        """ 
    415430        if isinstance(right, (int, long, integer.Integer)): 
    416431            return sage.rings.ring_element.RingElement.__pow__(self, right) 
    417         raise TypeError, "Can only raise ComplexIntervalField to integral powers" 
     432        return (self.log() * right).exp() 
    418433     
    419434    def prec(self): 
     
    600615            sage: CIF(-2).argument() 
    601616            [3.1415926535897931 .. 3.1415926535897936] 
     617 
     618        Here we see that if the interval crosses the negative real 
     619        axis, then the argument() can exceed $\pi$, and we 
     620        we violate the standard interval guarantees in the process: 
     621            sage: CIF(-2, RIF(-0.1, 0.1)).argument() 
     622            [3.0916342578678501 .. 3.1915510493117365] 
     623            sage: CIF(-2, -0.1).argument() 
     624            [-3.0916342578678511 .. -3.0916342578678501] 
    602625        """ 
    603626        if mpfi_has_zero(self.__re) and mpfi_has_zero(self.__im): 
     
    735758            sage: a in a.log().exp() 
    736759            True 
     760 
     761        If the interval crosses the negative real axis, then we don't 
     762        use the standard branch cut (and we violate the interval guarantees): 
     763            sage: CIF(-3, RIF(-1/4, 1/4)).log() 
     764            [1.0986122886681095 .. 1.1020725100903968] + [3.0584514217013518 .. 3.2247338854782349]*I 
     765            sage: CIF(-3, -1/4).log() 
     766            [1.1020725100903963 .. 1.1020725100903968] - [3.0584514217013518 .. 3.0584514217013524]*I 
    737767        """ 
    738768        theta = self.argument() 
    739769        rho = abs(self) 
    740770        return ComplexIntervalFieldElement(self._parent, rho.log(), theta) 
     771         
     772    def sqrt(self, bint all=False, **kwds): 
     773        """ 
     774        The square root function.  
     775         
     776        WARNING: We approximate the standard branch cut along the 
     777        negative real axis, with sqrt(-r^2) = i*r for positive real r; 
     778        but if the interval crosses the negative real axis, we pick 
     779        the root with positive imaginary component for the entire 
     780        interval. 
     781                 
     782        INPUT: 
     783            all -- bool (default: False); if True, return a list 
     784                of all square roots. 
     785         
     786        EXAMPLES:  
     787            sage: a = CIF(-1).sqrt()^2; a 
     788            [-1.0000000000000003 .. -0.99999999999999966] + [-0.00000000000000032162452993532733 .. 0.00000000000000012246467991473533]*I 
     789            sage: sqrt(CIF(2)) 
     790            [1.4142135623730949 .. 1.4142135623730952] 
     791            sage: sqrt(CIF(-1)) 
     792            [-0.00000000000000016081226496766367 .. 0.000000000000000061232339957367661] + [0.99999999999999988 .. 1.0000000000000000]*I 
     793            sage: sqrt(CIF(2-I))^2 
     794            [1.9999999999999980 .. 2.0000000000000014] - [0.99999999999999877 .. 1.0000000000000012]*I 
     795            sage: CC(-2-I).sqrt()^2 
     796            -2.00000000000000 - 1.00000000000000*I 
     797 
     798        Here, we select a non-principal root for part of the interval, and 
     799        violate the standard interval guarantees: 
     800            sage: CIF(-5, RIF(-1, 1)).sqrt() 
     801            [-0.22250788030178321 .. 0.22250788030178296] + [2.2251857651053086 .. 2.2581008643532262]*I 
     802            sage: CIF(-5, -1).sqrt() 
     803            [0.22250788030178228 .. 0.22250788030178296] - [2.2471114250958694 .. 2.2471114250958709]*I 
     804        """ 
     805        if self.is_zero(): 
     806            return [self] if all else self 
     807        theta = self.argument()/2 
     808        rho = abs(self).sqrt() 
     809        x = ComplexIntervalFieldElement(self._parent, rho*theta.cos(), rho*theta.sin()) 
     810        if all: 
     811            return [x, -x] 
     812        else: 
     813            return x 
     814 
    741815 
    742816    def is_square(self): 
Note: See TracChangeset for help on using the changeset viewer.