Changeset 4122:dcc3a21b3bbc


Ignore:
Timestamp:
04/26/07 22:04:37 (6 years ago)
Author:
William Stein <wstein@…>
Branch:
default
Parents:
4120:cb21d372affb (diff), 4121:1058fc175758 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • sage/rings/real_mpfr.pyx

    r4120 r4122  
    15781578            return intv.simplest_rational(low_open = True) 
    15791579         
     1580    def nearby_rational(self, max_error=None, max_denominator=None): 
     1581        """ 
     1582        Find a rational near to self.  Exactly one of max_error 
     1583        or max_denominator must be specified.  If max_error is specified, 
     1584        then this returns the simplest rational in the range 
     1585        [self-max_error .. self+max_error].  If max_denominator is 
     1586        specified, then this returns the rational closest to self with 
     1587        denominator at most max_denominator.  (In case of ties, we 
     1588        pick the simpler rational.) 
     1589 
     1590        EXAMPLES: 
     1591            sage: (0.333).nearby_rational(max_error=0.001) 
     1592            1/3 
     1593            sage: (0.333).nearby_rational(max_error=1) 
     1594            0 
     1595            sage: (-0.333).nearby_rational(max_error=0.0001) 
     1596            -257/772 
     1597 
     1598            sage: (0.333).nearby_rational(max_denominator=100) 
     1599            1/3 
     1600            sage: RR(1/3 + 1/1000000).nearby_rational(max_denominator=2999999) 
     1601            777780/2333333 
     1602            sage: RR(1/3 + 1/1000000).nearby_rational(max_denominator=3000000) 
     1603            1000003/3000000 
     1604            sage: (-0.333).nearby_rational(max_denominator=1000) 
     1605            -333/1000 
     1606            sage: RR(3/4).nearby_rational(max_denominator=2) 
     1607            1 
     1608            sage: RR(pi).nearby_rational(max_denominator=120) 
     1609            355/113 
     1610            sage: RR(pi).nearby_rational(max_denominator=10000) 
     1611            355/113 
     1612            sage: RR(pi).nearby_rational(max_denominator=100000) 
     1613            312689/99532 
     1614            sage: RR(pi).nearby_rational(max_denominator=1) 
     1615            3 
     1616            sage: RR(-3.5).nearby_rational(max_denominator=1) 
     1617            -3 
     1618        """ 
     1619        if ((max_error is None and max_denominator is None) or 
     1620            (max_error is not None and max_denominator is not None)): 
     1621            raise ValueError, 'Must specify exactly one of max_error or max_denominator in nearby_rational()' 
     1622 
     1623        if max_error is not None: 
     1624            from real_mpfi import RealIntervalField 
     1625 
     1626            intv_field = RealIntervalField(self.prec()) 
     1627            intv = intv_field(self - max_error, self + max_error) 
     1628 
     1629            return intv.simplest_rational() 
     1630 
     1631        cdef int sgn = mpfr_sgn(self.value) 
     1632 
     1633        if sgn == 0: 
     1634            return Rational(0) 
     1635 
     1636        cdef Rational self_r = self.exact_rational() 
     1637 
     1638        cdef Integer self_d = self_r.denominator() 
     1639 
     1640        if self_d <= max_denominator: 
     1641            return self_r 
     1642 
     1643        if sgn < 0: 
     1644            self_r = -self_r 
     1645 
     1646        cdef Integer fl = self_r.floor() 
     1647        cdef Rational target = self_r - fl 
     1648 
     1649        cdef int low_done = 0 
     1650        cdef int high_done = 0 
     1651 
     1652        # We use the Stern-Brocot tree to find the nearest neighbors of 
     1653        # self with denominator at most max_denominator.  However, 
     1654        # navigating the Stern-Brocot tree in the straightforward way 
     1655        # can be very slow; for instance, to get to 1/1000000 takes a 
     1656        # million steps.  Instead, we perform many steps at once; 
     1657        # this probably slows down the average case, but it drastically 
     1658        # speeds up the worst case. 
     1659 
     1660        # Suppose we have a/b < c/d < e/f, where a/b and e/f are 
     1661        # neighbors in the Stern-Brocot tree and c/d is the target. 
     1662        # We alternate between moving the low and the high end toward 
     1663        # the target as much as possible.  Suppose that there are 
     1664        # k consecutive rightward moves in the Stern-Brocot tree 
     1665        # traversal; then we end up with (a+k*e)/(b+k*f).  We have 
     1666        # two constraints on k.  First, the result must be <= c/d; 
     1667        # this gives us the following: 
     1668        # (a+k*e)/(b+k*f) <= c/d 
     1669        # d*a + k*(d*e) <= c*b + k*(c*f) 
     1670        # k*(d*e) - k*(c*f) <= c*b - d*a 
     1671        # k <= (c*b - d*a)/(d*e - c*f) 
     1672        # when moving the high side, we get 
     1673        # (k*a+e)/(k*b+f) >= c/d 
     1674        # k*(d*a) + d*e >= k*(c*b) + c*f 
     1675        # d*e - c*f >= k*(c*b - d*a) 
     1676        # k <= (d*e - c*f)/(c*b - d*a) 
     1677 
     1678        # We also need the denominator to be <= max_denominator; this 
     1679        # gives (b+k*f) <= max_denominator or 
     1680        # k <= (max_denominator - b)/f 
     1681        # or 
     1682        # k <= (max_denominator - f)/b 
     1683 
     1684        # We use variables with the same names as in the math above. 
     1685 
     1686        cdef Integer a = Integer(0) 
     1687        cdef Integer b = Integer(1) 
     1688        cdef Integer c = target.numerator() 
     1689        cdef Integer d = target.denominator() 
     1690        cdef Integer e = Integer(1) 
     1691        cdef Integer f = Integer(1) 
     1692 
     1693        cdef Integer k 
     1694 
     1695        while (not low_done) or (not high_done): 
     1696            # Move the low side 
     1697            k = (c*b - d*a) // (d*e - c*f) 
     1698 
     1699            if b+k*f > max_denominator: 
     1700                k = (max_denominator - b) // f 
     1701                low_done = True 
     1702 
     1703            if k == 0: 
     1704                low_done = True 
     1705 
     1706            a = a + k*e 
     1707            b = b + k*f 
     1708 
     1709            # Move the high side 
     1710            k = (d*e - c*f) // (c*b - d*a) 
     1711 
     1712            if k*b + f >= max_denominator: 
     1713                k = (max_denominator - f) // b 
     1714                high_done = True 
     1715 
     1716            if k == 0: 
     1717                high_done = True 
     1718 
     1719            e = k*a + e 
     1720            f = k*b + f 
     1721 
     1722        # Now a/b and e/f are rationals surrounding c/d.  We know that 
     1723        # neither is equal to c/d, since d > max_denominator and 
     1724        # b and f are both <= max_denominator.  (We know that 
     1725        # d > max_denominator because we return early (before we 
     1726        # get here) if d <= max_denominator.) 
     1727 
     1728        low = a/b 
     1729        high = e/f 
     1730 
     1731        cdef int compare = cmp(target - low, high - target) 
     1732 
     1733        if compare > 0: 
     1734            result = high 
     1735        elif compare < 0: 
     1736            result = low 
     1737        else: 
     1738            compare = cmp(b, f) 
     1739            if compare > 0: 
     1740                result = high 
     1741            elif compare < 0: 
     1742                result = low 
     1743            else: 
     1744                compare = cmp(a, e) 
     1745                if compare > 0: 
     1746                    result = high 
     1747                else: 
     1748                    result = low 
     1749 
     1750        result = fl + result 
     1751 
     1752        if sgn < 0: 
     1753            return -result 
     1754        return result         
     1755 
    15801756 
    15811757    ########################################### 
  • sage/rings/real_mpfr.pyx

    r4121 r4122  
    4848include '../ext/interrupt.pxi' 
    4949include "../ext/stdsage.pxi" 
     50include "../ext/random.pxi" 
    5051 
    5152cimport sage.rings.ring 
     
    216217        """ 
    217218        if hasattr(x, '_mpfr_'): 
    218             # This design with the hasattr is very annoying. 
    219             # The only thing that uses it right now is symbolic constants 
    220             # and symbolic function evaluation. 
    221             # Getting rid of this would speed things up. 
    222219            return x._mpfr_(self) 
    223220        cdef RealNumber z 
     
    246243        elif self.__prec <= 53 and is_RealDoubleElement(x): 
    247244            return self(x) 
    248         import sage.functions.constants 
    249         return self._coerce_try(x, [sage.functions.constants.ConstantRing]) 
     245        raise TypeError 
     246        #import sage.functions.constants 
     247        #return self._coerce_try(x, [sage.functions.constants.ConstantRing]) 
    250248 
    251249    def __cmp__(self, other): 
     
    411409            0.69314718055994530941723212146 
    412410        """ 
    413         cdef RealNumber x 
    414         x = self._new()         
     411        cdef RealNumber x = self._new() 
    415412        mpfr_const_log2(x.value, self.rnd) 
    416413        return x 
     414         
     415    def random_element(self, min=-1, max=1, distribution=None): 
     416        """ 
     417        Returns a uniformly distributed random number between  
     418        min and max (default -1 to 1).  
     419         
     420        EXAMPLES: 
     421            sage: RealField(100).random_element(-5, 10) 
     422            4.2682457657074627882421620493 
     423            sage: RealField(10).random_element() 
     424            .27 
     425        """ 
     426        cdef RealNumber x = self._new() 
     427        mpfr_urandomb(x.value, state) 
     428        if min == 0 and max == 1: 
     429            return x 
     430        else: 
     431            return (max-min)*x + min 
    417432 
    418433    def factorial(self, int n): 
     
    663678 
    664679    def _latex_(self): 
    665         return str(self) 
     680        s = self.str() 
     681        parts = s.split('e') 
     682        if len(parts) > 1: 
     683            # scientific notation 
     684            if parts[1][0] == '+': 
     685                parts[1] = parts[1][1:] 
     686            s = "%s \\times 10^{%s}" % (parts[0], parts[1]) 
     687        return s 
    666688 
    667689    def _interface_init_(self): 
     
    12631285        Returns integer truncation of this real number. 
    12641286        """ 
    1265         s = self.str(32) 
    1266         i = s.find('.') 
    1267         return int(s[:i], 32) 
     1287        cdef Integer z = Integer() 
     1288        mpfr_get_z(z.value, self.value, GMP_RNDZ) 
     1289        return z.__int__() 
    12681290 
    12691291    def __long__(self): 
     
    12711293        Returns long integer truncation of this real number. 
    12721294        """ 
    1273         s = self.str(32) 
    1274         i = s.find('.') 
    1275         return long(s[:i], 32) 
     1295        cdef Integer z = Integer() 
     1296        mpfr_get_z(z.value, self.value, GMP_RNDZ) 
     1297        return z.__long__() 
    12761298 
    12771299    def __complex__(self): 
     
    18161838 
    18171839    def sqrt(self): 
    1818         """ 
     1840        r""" 
    18191841        Return a square root of self. 
    18201842 
    18211843        If self is negative a complex number is returned. 
    18221844 
    1823         If you use self.square_root() then a real number will always 
    1824         be returned (though it will be NaN if self is negative). 
     1845        If you use \code{self.sqrt_approx()} then a real number will 
     1846        always be returned (though it will be NaN if self is 
     1847        negative). 
    18251848 
    18261849        EXAMPLES: 
     
    18331856            sage: r = 4344 
    18341857            sage: r.sqrt() 
    1835             65.9090282131363 
     1858            2*sqrt(1086) 
     1859             
     1860            sage: r = 4344.0 
    18361861            sage: r.sqrt()^2 == r 
    18371862            True 
    18381863            sage: r.sqrt()^2 - r             
    1839              0.000000000000000 
     1864            0.000000000000000 
    18401865 
    18411866            sage: r = -2.0 
     
    18441869            """ 
    18451870        if self >= 0: 
    1846             return self.square_root() 
     1871            return self.sqrt_approx() 
    18471872        return self._complex_number_().sqrt() 
    1848          
    1849  
    1850     def square_root(self): 
     1873 
     1874    def sqrt_approx(self): 
    18511875        """ 
    18521876        Return a square root of self.  A real number will always be 
     
    18571881        EXAMPLES: 
    18581882            sage: r = -2.0 
    1859             sage: r.square_root() 
     1883            sage: r.sqrt_approx() 
    18601884            NaN 
    18611885            sage: r.sqrt() 
     
    19181942            1.0000000*I                    # 32-bit 
    19191943            -1.0842022e-19 + 1.0000000*I   # 64-bit 
     1944 
     1945        We raise a real number to a symbolic object: 
     1946            sage: 1.5^x 
     1947            1.50000000000000^x 
     1948            sage: -2.3^(x+y^3+sin(x)) 
     1949            -2.30000000000000^(y^3 + sin(x) + x) 
    19201950        """ 
    19211951        cdef RealNumber x 
     
    19231953            return self.__pow__(float(exponent)) 
    19241954        if not PY_TYPE_CHECK(exponent, RealNumber): 
    1925             x = self 
    1926             exponent = x._parent(exponent) 
     1955            try: 
     1956                x = self 
     1957                exponent = x._parent(exponent) 
     1958            except TypeError: 
     1959                try: 
     1960                    return exponent.parent()(self)**exponent 
     1961                except AttributeError: 
     1962                    raise TypeError 
    19271963        return self.__pow(exponent) 
    19281964 
     
    22592295        return x 
    22602296 
     2297    def coth(self): 
     2298        """ 
     2299        EXAMPLES: 
     2300            sage: RealField(100)(2).coth() 
     2301            1.0373147207275480958778097648 
     2302        """ 
     2303        return 1/self.tanh() 
     2304 
     2305    def csch(self): 
     2306        """ 
     2307        EXAMPLES: 
     2308            sage: RealField(100)(2).csch() 
     2309            0.27572056477178320775835148216 
     2310        """ 
     2311        return 1/self.sinh() 
     2312 
     2313    def sech(self): 
     2314        """ 
     2315        EXAMPLES: 
     2316            sage: RealField(100)(2).sech() 
     2317            0.26580222883407969212086273982         
     2318        """ 
     2319        return 1/self.cosh() 
     2320 
    22612321    def acosh(self): 
    22622322        """ 
     
    24192479 
    24202480        EXAMPLE: 
    2421              sage: r = sqrt(2); r 
     2481             sage: r = sqrt(2.0); r 
    24222482             1.41421356237310 
    24232483             sage: r.algdep(5) 
     
    24362496 
    24372497         EXAMPLE: 
    2438               sage: r = sqrt(2); r 
     2498              sage: r = sqrt(2.0); r 
    24392499              1.41421356237310 
    24402500              sage: r.algdep(5) 
     
    25362596 
    25372597def is_RealField(x): 
    2538     return PY_TYPE_CHECK(x, RealField) 
     2598    return bool(PY_TYPE_CHECK(x, RealField)) 
    25392599 
    25402600def is_RealNumber(x): 
    2541     return PY_TYPE_CHECK(x, RealNumber) 
     2601    return bool(PY_TYPE_CHECK(x, RealNumber)) 
    25422602 
    25432603def __create__RealField_version0(prec, sci_not, rnd): 
Note: See TracChangeset for help on using the changeset viewer.