Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit bce4fb0

Browse files
committed
Use mpfr for Bessel functions if possible
1 parent a486db2 commit bce4fb0

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

src/sage/functions/bessel.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,32 @@ def _evalf_(self, n, x, parent=None, algorithm=None):
308308
EXAMPLES::
309309
310310
sage: bessel_J(0.0, 1.0)
311-
0.765197686557966
311+
0.765197686557967
312312
sage: bessel_J(0, 1).n(digits=20)
313313
0.76519768655796655145
314+
sage: bessel_J(0.5, 1.5)
315+
0.649838074753747
316+
317+
Check for correct rounding (:trac:`17122`)::
318+
319+
sage: R = RealField(113)
320+
sage: a = R("8.935761195587725798762818805462843676e-01")
321+
sage: aa = RealField(200)(a)
322+
sage: for n in [-10..10]:
323+
....: b = bessel_J(R(n), a)
324+
....: bb = R(bessel_J(n, aa))
325+
....: if b != bb:
326+
....: print n, b-bb
314327
"""
328+
if parent is not None:
329+
x = parent(x)
330+
331+
try:
332+
return x.jn(Integer(n))
333+
except Exception:
334+
pass
335+
336+
n, x = get_coercion_model().canonical_coercion(n, x)
315337
import mpmath
316338
return mpmath_utils.call(mpmath.besselj, n, x, parent=parent)
317339

@@ -457,11 +479,33 @@ def _evalf_(self, n, x, parent=None, algorithm=None):
457479
"""
458480
EXAMPLES::
459481
482+
sage: bessel_Y(0.5, 1.5)
483+
-0.0460831658930974
460484
sage: bessel_Y(1.0+2*I, 3.0+4*I)
461485
0.699410324467538 + 0.228917940896421*I
462486
sage: bessel_Y(0, 1).n(256)
463487
0.08825696421567695798292676602351516282781752309067554671104384761199978932351
488+
489+
Check for correct rounding (:trac:`17122`)::
490+
491+
sage: R = RealField(113)
492+
sage: a = R("8.935761195587725798762818805462843676e-01")
493+
sage: aa = RealField(200)(a)
494+
sage: for n in [-10..10]:
495+
....: b = bessel_Y(R(n), a)
496+
....: bb = R(bessel_Y(n, aa))
497+
....: if b != bb:
498+
....: print n, b-bb
464499
"""
500+
if parent is not None:
501+
x = parent(x)
502+
503+
try:
504+
return x.yn(Integer(n))
505+
except Exception:
506+
pass
507+
508+
n, x = get_coercion_model().canonical_coercion(n, x)
465509
import mpmath
466510
return mpmath_utils.call(mpmath.bessely, n, x, parent=parent)
467511

src/sage/libs/mpmath/ext_impl.pyx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,8 @@ from cpython.float cimport *
2525
from cpython.complex cimport *
2626
from cpython.number cimport *
2727

28-
cdef extern from "math.h":
29-
cdef double fpow "pow" (double, double)
30-
cdef double fsqrt "sqrt" (double)
31-
cdef double frexp "frexp" (double, int*)
28+
from libc.math cimport sqrt as fsqrt
29+
from libc.math cimport frexp
3230

3331
from sage.libs.gmp.all cimport *
3432
from sage.libs.mpfr cimport *
@@ -1147,6 +1145,7 @@ cdef cy_exp_basecase(mpz_t y, mpz_t x, int prec):
11471145
mpz_fdiv_q_2exp(x2, x2, prec)
11481146
mpz_set(a, x2)
11491147
while mpz_sgn(a):
1148+
sig_check()
11501149
mpz_fdiv_q_ui(a, a, k)
11511150
mpz_add(s0, s0, a)
11521151
k += 1
@@ -1160,6 +1159,7 @@ cdef cy_exp_basecase(mpz_t y, mpz_t x, int prec):
11601159
mpz_add(s0, s0, s1)
11611160
u = r
11621161
while r:
1162+
sig_check()
11631163
mpz_mul(s0, s0, s0)
11641164
mpz_fdiv_q_2exp(s0, s0, prec)
11651165
r -= 1
@@ -2037,6 +2037,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z,
20372037
else:
20382038
mpz_set_tuple_fixed(ZRE, z, wp)
20392039
for i in range(0,p):
2040+
sig_check()
20402041
if param_types[i] == 'Z':
20412042
mpz_init(AINT[aint])
20422043
mpz_set_integer(AINT[aint], coeffs[i])
@@ -2060,6 +2061,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z,
20602061
else:
20612062
raise ValueError
20622063
for i in range(p,p+q):
2064+
sig_check()
20632065
if param_types[i] == 'Z':
20642066
mpz_init(BINT[bint])
20652067
mpz_set_integer(BINT[bint], coeffs[i])
@@ -2113,22 +2115,28 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z,
21132115

21142116
# Multiply real factors
21152117
for k in range(0, cancellable_real):
2118+
sig_check()
21162119
mpz_mul(PRE, PRE, AREAL[k])
21172120
mpz_fdiv_q(PRE, PRE, BREAL[k])
21182121
for k in range(cancellable_real, areal):
2122+
sig_check()
21192123
mpz_mul(PRE, PRE, AREAL[k])
21202124
mpz_fdiv_q_2exp(PRE, PRE, wp)
21212125
for k in range(cancellable_real, breal):
2126+
sig_check()
21222127
mpz_mul_2exp(PRE, PRE, wp)
21232128
mpz_fdiv_q(PRE, PRE, BREAL[k])
21242129
if have_complex:
21252130
for k in range(0, cancellable_real):
2131+
sig_check()
21262132
mpz_mul(PIM, PIM, AREAL[k])
21272133
mpz_fdiv_q(PIM, PIM, BREAL[k])
21282134
for k in range(cancellable_real, areal):
2135+
sig_check()
21292136
mpz_mul(PIM, PIM, AREAL[k])
21302137
mpz_fdiv_q_2exp(PIM, PIM, wp)
21312138
for k in range(cancellable_real, breal):
2139+
sig_check()
21322140
mpz_mul_2exp(PIM, PIM, wp)
21332141
mpz_fdiv_q(PIM, PIM, BREAL[k])
21342142

@@ -2162,6 +2170,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z,
21622170
mpz_fdiv_q(PIM, PIM, DIV)
21632171

21642172
for i in range(acomplex):
2173+
sig_check()
21652174
mpz_mul(TRE, PRE, ACRE[i])
21662175
mpz_submul(TRE, PIM, ACIM[i])
21672176
mpz_mul(TIM, PIM, ACRE[i])
@@ -2170,6 +2179,7 @@ cdef MPF_hypsum(MPF *a, MPF *b, int p, int q, param_types, str ztype, coeffs, z,
21702179
mpz_fdiv_q_2exp(PIM, TIM, wp)
21712180

21722181
for i in range(bcomplex):
2182+
sig_check()
21732183
mpz_mul(URE, BCRE[i], BCRE[i])
21742184
mpz_addmul(URE, BCIM[i], BCIM[i])
21752185
mpz_mul(TRE, PRE, BCRE[i])

src/sage/rings/real_mpfr.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3769,7 +3769,7 @@ cdef class RealNumber(sage.structure.element.RingElement):
37693769

37703770
def is_integer(self):
37713771
"""
3772-
Return ``True`` if this number is a integer
3772+
Return ``True`` if this number is a integer.
37733773
37743774
EXAMPLES::
37753775
@@ -3778,7 +3778,7 @@ cdef class RealNumber(sage.structure.element.RingElement):
37783778
sage: RR(0.1).is_integer()
37793779
False
37803780
"""
3781-
return self in ZZ
3781+
return mpfr_integer_p(self.value) != 0
37823782

37833783
def __nonzero__(self):
37843784
"""

0 commit comments

Comments
 (0)