Skip to content

Commit

Permalink
Merge branch 'vbraun' for 10.5.beta4
Browse files Browse the repository at this point in the history
  • Loading branch information
kiwifb committed Sep 16, 2024
2 parents 37394a7 + 3b8624e commit 8390ff3
Show file tree
Hide file tree
Showing 2 changed files with 342 additions and 4 deletions.
333 changes: 333 additions & 0 deletions sci-mathematics/sagemath-standard/files/mpmath.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,333 @@
diff --git a/sage/env.py b/sage/env.py
index 3548c65f43e..d6b6218d7b6 100644
--- a/sage/env.py
+++ b/sage/env.py
@@ -245,8 +245,9 @@ SINGULAR_BIN = var("SINGULAR_BIN") or "Singular"
OPENMP_CFLAGS = var("OPENMP_CFLAGS", "")
OPENMP_CXXFLAGS = var("OPENMP_CXXFLAGS", "")

-# Make sure mpmath uses Sage types
-os.environ['MPMATH_SAGE'] = '1'
+# Make sure that mpmath < 1.4 does not try to use Sage types
+os.environ.pop('MPMATH_SAGE', None)
+os.environ['MPMATH_NOSAGE'] = '1'

# misc
SAGE_BANNER = var("SAGE_BANNER", "")
diff --git a/sage/libs/mpmath/utils.pyx b/sage/libs/mpmath/utils.pyx
index 0123d4190be..0f451e18f65 100644
--- a/sage/libs/mpmath/utils.pyx
+++ b/sage/libs/mpmath/utils.pyx
@@ -1,9 +1,9 @@
"""
Utilities for Sage-mpmath interaction
-
-Also patches some mpmath functions for speed
"""

+cimport gmpy2
+
from sage.ext.stdsage cimport PY_NEW

from sage.rings.integer cimport Integer
@@ -16,141 +16,8 @@ from sage.libs.gmp.all cimport *

from sage.rings.real_mpfr cimport RealField

-cpdef int bitcount(n) noexcept:
- """
- Bitcount of a Sage Integer or Python int/long.
-
- EXAMPLES::
-
- sage: from mpmath.libmp import bitcount
- sage: bitcount(0)
- 0
- sage: bitcount(1)
- 1
- sage: bitcount(100)
- 7
- sage: bitcount(-100)
- 7
- sage: bitcount(2r)
- 2
- sage: bitcount(2L)
- 2
- """
- cdef Integer m
- if isinstance(n, Integer):
- m = <Integer>n
- else:
- m = Integer(n)
- if mpz_sgn(m.value) == 0:
- return 0
- return mpz_sizeinbase(m.value, 2)
-
-cpdef isqrt(n):
- """
- Square root (rounded to floor) of a Sage Integer or Python int/long.
- The result is a Sage Integer.
-
- EXAMPLES::
-
- sage: from mpmath.libmp import isqrt
- sage: isqrt(0)
- 0
- sage: isqrt(100)
- 10
- sage: isqrt(10)
- 3
- sage: isqrt(10r)
- 3
- sage: isqrt(10L)
- 3
- """
- cdef Integer m, y
- if isinstance(n, Integer):
- m = <Integer>n
- else:
- m = Integer(n)
- if mpz_sgn(m.value) < 0:
- raise ValueError("square root of negative integer not defined.")
- y = PY_NEW(Integer)
- mpz_sqrt(y.value, m.value)
- return y
-
-cpdef from_man_exp(man, exp, long prec = 0, str rnd = 'd'):
- """
- Create normalized mpf value tuple from mantissa and exponent.
-
- With prec > 0, rounds the result in the desired direction
- if necessary.
+gmpy2.import_gmpy2()

- EXAMPLES::
-
- sage: from mpmath.libmp import from_man_exp
- sage: from_man_exp(-6, -1)
- (1, 3, 0, 2)
- sage: from_man_exp(-6, -1, 1, 'd')
- (1, 1, 1, 1)
- sage: from_man_exp(-6, -1, 1, 'u')
- (1, 1, 2, 1)
- """
- cdef Integer res
- cdef long bc
- res = Integer(man)
- bc = mpz_sizeinbase(res.value, 2)
- if not prec:
- prec = bc
- if mpz_sgn(res.value) < 0:
- mpz_neg(res.value, res.value)
- return normalize(1, res, exp, bc, prec, rnd)
- else:
- return normalize(0, res, exp, bc, prec, rnd)
-
-cpdef normalize(long sign, Integer man, exp, long bc, long prec, str rnd):
- """
- Create normalized mpf value tuple from full list of components.
-
- EXAMPLES::
-
- sage: from mpmath.libmp import normalize
- sage: normalize(0, 4, 5, 3, 53, 'n')
- (0, 1, 7, 1)
- """
- cdef long shift
- cdef Integer res
- cdef unsigned long trail
- if mpz_sgn(man.value) == 0:
- from mpmath.libmp import fzero
- return fzero
- if bc <= prec and mpz_odd_p(man.value):
- return (sign, man, exp, bc)
- shift = bc - prec
- res = PY_NEW(Integer)
- if shift > 0:
- if rnd == 'n':
- if mpz_tstbit(man.value, shift-1) and (mpz_tstbit(man.value, shift)
- or (mpz_scan1(man.value, 0) < (shift-1))):
- mpz_cdiv_q_2exp(res.value, man.value, shift)
- else:
- mpz_fdiv_q_2exp(res.value, man.value, shift)
- elif rnd == 'd':
- mpz_fdiv_q_2exp(res.value, man.value, shift)
- elif rnd == 'f':
- if sign: mpz_cdiv_q_2exp(res.value, man.value, shift)
- else: mpz_fdiv_q_2exp(res.value, man.value, shift)
- elif rnd == 'c':
- if sign: mpz_fdiv_q_2exp(res.value, man.value, shift)
- else: mpz_cdiv_q_2exp(res.value, man.value, shift)
- elif rnd == 'u':
- mpz_cdiv_q_2exp(res.value, man.value, shift)
- exp += shift
- else:
- mpz_set(res.value, man.value)
- # Strip trailing bits
- trail = mpz_scan1(res.value, 0)
- if 0 < trail < bc:
- mpz_tdiv_q_2exp(res.value, res.value, trail)
- exp += trail
- bc = mpz_sizeinbase(res.value, 2)
- return (sign, res, int(exp), bc)

cdef mpfr_from_mpfval(mpfr_t res, tuple x):
"""
@@ -158,12 +25,12 @@ cdef mpfr_from_mpfval(mpfr_t res, tuple x):
data tuple.
"""
cdef int sign
- cdef Integer man
+ cdef gmpy2.mpz man
cdef long exp
cdef long bc
sign, man, exp, bc = x
if man:
- mpfr_set_z(res, man.value, MPFR_RNDZ)
+ mpfr_set_z(res, man.z, MPFR_RNDZ)
if sign:
mpfr_neg(res, res, MPFR_RNDZ)
mpfr_mul_2si(res, res, exp, MPFR_RNDZ)
@@ -207,7 +74,7 @@ cdef mpfr_to_mpfval(mpfr_t value):
mpz_tdiv_q_2exp(man.value, man.value, trailing)
exp += trailing
bc = mpz_sizeinbase(man.value, 2)
- return (sign, man, int(exp), bc)
+ return (sign, man.__mpz__(), int(exp), bc)


def mpmath_to_sage(x, prec):
@@ -412,7 +279,7 @@ def call(func, *args, **kwargs):
Check that :issue:`11885` is fixed::

sage: a.call(a.ei, 1.0r, parent=float)
- 1.8951178163559366
+ 1.8951178163559368

Check that :issue:`14984` is fixed::

diff --git a/sage/rings/real_mpfr.pyx b/sage/rings/real_mpfr.pyx
index 7e1ab748b55..4a332e6fb5d 100644
--- a/sage/rings/real_mpfr.pyx
+++ b/sage/rings/real_mpfr.pyx
@@ -150,8 +150,6 @@ from sage.structure.richcmp cimport rich_to_bool_sgn
cdef bin_op
from sage.structure.element import bin_op

-from sage.libs.mpmath.utils cimport mpfr_to_mpfval
-
from sage.rings.integer cimport Integer
from sage.rings.rational cimport Rational
from sage.rings.real_double cimport RealDoubleElement
diff --git a/sage/structure/coerce.pyx b/sage/structure/coerce.pyx
index cc15eff82e9..79d5ecb74e0 100644
--- a/sage/structure/coerce.pyx
+++ b/sage/structure/coerce.pyx
@@ -144,6 +144,13 @@ cpdef py_scalar_parent(py_type):
Real Double Field
sage: py_scalar_parent(gmpy2.mpc) # needs sage.rings.complex_double
Complex Double Field
+
+ sage: # needs mpmath
+ sage: import mpmath
+ sage: py_scalar_parent(mpmath.mpf)
+ Real Double Field
+ sage: py_scalar_parent(mpmath.mpc) # needs sage.rings.complex_double
+ Complex Double Field
"""
if issubclass(py_type, int):
import sage.rings.integer_ring
@@ -151,39 +158,46 @@ cpdef py_scalar_parent(py_type):
if py_type is FractionType:
import sage.rings.rational_field
return sage.rings.rational_field.QQ
- elif issubclass(py_type, float):
+ if issubclass(py_type, float):
import sage.rings.real_double
return sage.rings.real_double.RDF
- elif issubclass(py_type, complex):
+ if issubclass(py_type, complex):
import sage.rings.complex_double
return sage.rings.complex_double.CDF
- elif is_numpy_type(py_type):
+ if is_numpy_type(py_type):
import numpy
if issubclass(py_type, numpy.integer):
import sage.rings.integer_ring
return sage.rings.integer_ring.ZZ
- elif issubclass(py_type, numpy.floating):
+ if issubclass(py_type, numpy.floating):
import sage.rings.real_double
return sage.rings.real_double.RDF
- elif issubclass(py_type, numpy.complexfloating):
+ if issubclass(py_type, numpy.complexfloating):
import sage.rings.complex_double
return sage.rings.complex_double.CDF
- else:
- return None
- elif issubclass(py_type, gmpy2.mpz):
+ return None
+ if issubclass(py_type, gmpy2.mpz):
import sage.rings.integer_ring
return sage.rings.integer_ring.ZZ
- elif issubclass(py_type, gmpy2.mpq):
+ if issubclass(py_type, gmpy2.mpq):
import sage.rings.rational_field
return sage.rings.rational_field.QQ
- elif issubclass(py_type, gmpy2.mpfr):
+ if issubclass(py_type, gmpy2.mpfr):
import sage.rings.real_double
return sage.rings.real_double.RDF
- elif issubclass(py_type, gmpy2.mpc):
+ if issubclass(py_type, gmpy2.mpc):
import sage.rings.complex_double
return sage.rings.complex_double.CDF
- else:
+ if is_mpmath_type(py_type):
+ import mpmath
+ if issubclass(py_type, mpmath.mpf):
+ from sage.rings.real_double import RDF
+ return RDF
+ if issubclass(py_type, mpmath.mpc):
+ from sage.rings.complex_double import CDF
+ return CDF
return None
+ return None

cpdef py_scalar_to_element(x):
"""
@@ -469,10 +483,10 @@ cpdef bint is_numpy_type(t) noexcept:
return True
return False

+
cpdef bint is_mpmath_type(t) noexcept:
r"""
- Check whether the type ``t`` is a type whose name starts with either
- ``mpmath.`` or ``sage.libs.mpmath.``.
+ Check whether the type ``t`` is a type whose name starts with ``mpmath.``

EXAMPLES::

@@ -489,7 +503,7 @@ cpdef bint is_mpmath_type(t) noexcept:
True
"""
return isinstance(t, type) and \
- strncmp((<PyTypeObject*>t).tp_name, "sage.libs.mpmath.", 17) == 0
+ t.__module__.startswith("mpmath.")


cdef class CoercionModel:
diff --git a/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py b/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py
index bf0bb747282..9e7597eba9d 100644
--- a/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py
+++ b/sage/tests/books/computational-mathematics-with-sagemath/integration_doctest.py
@@ -151,7 +151,7 @@ Sage example in ./integration.tex, line 846::
sage: mpmath.quad(f, [0, 1])
Traceback (most recent call last):
...
- TypeError: no canonical coercion from <class 'sage.libs.mpmath.ext_main.mpf'> to ...
+ TypeError: no canonical coercion from <class '...mpf'> to ...

Sage example in ./integration.tex, line 866::

13 changes: 9 additions & 4 deletions sci-mathematics/sagemath-standard/sagemath-standard-9999.ebuild
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ PYTHON_COMPAT=( python3_{10..12} )
PYTHON_REQ_USE="readline,sqlite"
DISTUTILS_USE_PEP517=setuptools
DISTUTILS_EXT=1
# 38113 mpmath 1.4 support
# GIT_PRS=(
# 38113
# )

inherit desktop distutils-r1 multiprocessing sage-git-patch toolchain-funcs

Expand Down Expand Up @@ -145,6 +141,7 @@ REQUIRED_USE="doc? ( jmol )

PATCHES=(
"${FILESDIR}"/gap-4.13.1_b.patch
"${FILESDIR}"/mpmath.patch
"${FILESDIR}"/${PN}-10.4-env.patch
"${FILESDIR}"/sage_exec-9.3.patch
"${FILESDIR}"/${PN}-10.4b-neutering.patch
Expand All @@ -158,6 +155,14 @@ pkg_setup() {
python_prepare_all() {
distutils-r1_python_prepare_all

# delete mpmath files. This saves a lot of patch space
rm -r \
sage/libs/mpmath/ext_impl.pxd \
sage/libs/mpmath/ext_impl.pyx \
sage/libs/mpmath/ext_libmp.pyx \
sage/libs/mpmath/ext_main.pxd \
sage/libs/mpmath/ext_main.pyx

# use installed copy, not the vendored one.
rm -rf sage_setup

Expand Down

0 comments on commit 8390ff3

Please sign in to comment.