-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'vbraun' for 10.5.beta4
- Loading branch information
Showing
2 changed files
with
342 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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:: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters