Changeset 4122:dcc3a21b3bbc
- Timestamp:
- 04/26/07 22:04:37 (6 years ago)
- 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. - Files:
-
- 2 edited
-
sage/rings/real_mpfr.pyx (modified) (1 diff)
-
sage/rings/real_mpfr.pyx (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
sage/rings/real_mpfr.pyx
r4120 r4122 1578 1578 return intv.simplest_rational(low_open = True) 1579 1579 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 1580 1756 1581 1757 ########################################### -
sage/rings/real_mpfr.pyx
r4121 r4122 48 48 include '../ext/interrupt.pxi' 49 49 include "../ext/stdsage.pxi" 50 include "../ext/random.pxi" 50 51 51 52 cimport sage.rings.ring … … 216 217 """ 217 218 if hasattr(x, '_mpfr_'): 218 # This design with the hasattr is very annoying.219 # The only thing that uses it right now is symbolic constants220 # and symbolic function evaluation.221 # Getting rid of this would speed things up.222 219 return x._mpfr_(self) 223 220 cdef RealNumber z … … 246 243 elif self.__prec <= 53 and is_RealDoubleElement(x): 247 244 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]) 250 248 251 249 def __cmp__(self, other): … … 411 409 0.69314718055994530941723212146 412 410 """ 413 cdef RealNumber x 414 x = self._new() 411 cdef RealNumber x = self._new() 415 412 mpfr_const_log2(x.value, self.rnd) 416 413 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 417 432 418 433 def factorial(self, int n): … … 663 678 664 679 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 666 688 667 689 def _interface_init_(self): … … 1263 1285 Returns integer truncation of this real number. 1264 1286 """ 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__() 1268 1290 1269 1291 def __long__(self): … … 1271 1293 Returns long integer truncation of this real number. 1272 1294 """ 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__() 1276 1298 1277 1299 def __complex__(self): … … 1816 1838 1817 1839 def sqrt(self): 1818 """1840 r""" 1819 1841 Return a square root of self. 1820 1842 1821 1843 If self is negative a complex number is returned. 1822 1844 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). 1825 1848 1826 1849 EXAMPLES: … … 1833 1856 sage: r = 4344 1834 1857 sage: r.sqrt() 1835 65.9090282131363 1858 2*sqrt(1086) 1859 1860 sage: r = 4344.0 1836 1861 sage: r.sqrt()^2 == r 1837 1862 True 1838 1863 sage: r.sqrt()^2 - r 1839 0.0000000000000001864 0.000000000000000 1840 1865 1841 1866 sage: r = -2.0 … … 1844 1869 """ 1845 1870 if self >= 0: 1846 return self.sq uare_root()1871 return self.sqrt_approx() 1847 1872 return self._complex_number_().sqrt() 1848 1849 1850 def square_root(self): 1873 1874 def sqrt_approx(self): 1851 1875 """ 1852 1876 Return a square root of self. A real number will always be … … 1857 1881 EXAMPLES: 1858 1882 sage: r = -2.0 1859 sage: r.sq uare_root()1883 sage: r.sqrt_approx() 1860 1884 NaN 1861 1885 sage: r.sqrt() … … 1918 1942 1.0000000*I # 32-bit 1919 1943 -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) 1920 1950 """ 1921 1951 cdef RealNumber x … … 1923 1953 return self.__pow__(float(exponent)) 1924 1954 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 1927 1963 return self.__pow(exponent) 1928 1964 … … 2259 2295 return x 2260 2296 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 2261 2321 def acosh(self): 2262 2322 """ … … 2419 2479 2420 2480 EXAMPLE: 2421 sage: r = sqrt(2 ); r2481 sage: r = sqrt(2.0); r 2422 2482 1.41421356237310 2423 2483 sage: r.algdep(5) … … 2436 2496 2437 2497 EXAMPLE: 2438 sage: r = sqrt(2 ); r2498 sage: r = sqrt(2.0); r 2439 2499 1.41421356237310 2440 2500 sage: r.algdep(5) … … 2536 2596 2537 2597 def is_RealField(x): 2538 return PY_TYPE_CHECK(x, RealField)2598 return bool(PY_TYPE_CHECK(x, RealField)) 2539 2599 2540 2600 def is_RealNumber(x): 2541 return PY_TYPE_CHECK(x, RealNumber)2601 return bool(PY_TYPE_CHECK(x, RealNumber)) 2542 2602 2543 2603 def __create__RealField_version0(prec, sci_not, rnd):
Note: See TracChangeset
for help on using the changeset viewer.
