Skip to content

Mpmath 1.4 alpha update, setup.py and meson compatible#40669

Closed
kiwifb wants to merge 17 commits intosagemath:developfrom
kiwifb:mpmath-1.4
Closed

Mpmath 1.4 alpha update, setup.py and meson compatible#40669
kiwifb wants to merge 17 commits intosagemath:developfrom
kiwifb:mpmath-1.4

Conversation

@kiwifb
Copy link
Copy Markdown
Member

@kiwifb kiwifb commented Aug 23, 2025

This branch takes over from #38565 and include fix for the meson build.
It also update to the latest mpmath 1.4.0 alpha release. Releases beyond 1.4.0.a1 have some fix for sagemath but some test may still be broken.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

@github-actions
Copy link
Copy Markdown

Documentation preview for this PR (built with commit e7f5fb5; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@orlitzky
Copy link
Copy Markdown
Contributor

The big problem here is that no other distros are going to switch to an alpha release without a very good reason. I think for there to be any hope of it getting merged before the official 1.4.0, we would need to support 1.3.x as well. (Debian et al. may remain on 1.3.x for a while anyway).

It doesn't look like there are too many tests to worry about. Just code that needs to be enabled/disabled. With meson, we could check for the version being used,

>>> import mpmath
>>> mpmath.__version__.startswith("1.4.")
True

and then add e.g. CPPFLAGS="-DMPMATH14". The pyx files that are removed in the PR could be selectively disabled, and the functions that are deleted could be turned off by checking #ifdef MPMATH14.

@orlitzky
Copy link
Copy Markdown
Contributor

Actually for the deleted functions like bitcount and normalize, we wouldn't even need -DMPMATH14. We could just check for mpmath.__version__ directly, and return None rather than whatever the function does now. The meson check is still necessary to exclude certain pyx/pxd files though.

@antonio-rojas
Copy link
Copy Markdown
Contributor

1.4 is out, this needs rebasing

@antonio-rojas
Copy link
Copy Markdown
Contributor

There are still a few issues with 1.4:

python3 -m sage.doctest --long /usr/lib/python3.14/site-packages/sage/functions/error.py  # 1 doctest failed
python3 -m sage.doctest --long /usr/lib/python3.14/site-packages/sage/functions/exp_integral.py  # 1 doctest failed
python3 -m sage.doctest --long /usr/lib/python3.14/site-packages/sage/matrix/matrix2.pyx  # 3 doctests failed
python3 -m sage.doctest --long /usr/lib/python3.14/site-packages/sage/symbolic/constants.py  # 18 doctests failed

The first two are just numerical noise. The last one is due to some constants (kinchin, twinprime, glaisher, mertens) no longer being evaluated. The third one is a coercion error:

**********************************************************************
File "/usr/lib/python3.14/site-packages/sage/matrix/matrix2.pyx", line 7152, in sage.matrix.matrix2.Matrix.Sequence
Failed example:
    m.eigenvalues(algorithm="mpmath")  # abs tol 1e-14
Exception raised:
    Traceback (most recent call last):
      File "sage/rings/complex_mpfr.pyx", line 993, in sage.rings.complex_mpfr.ComplexNumber.__init__
        rr = R(real)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/real_mpfr.pyx", line 700, in sage.rings.real_mpfr.RealField_class._element_constructor_
        z._set(x, base)
      File "sage/rings/real_mpfr.pyx", line 1574, in sage.rings.real_mpfr.RealNumber._set
        raise TypeError("unable to convert {!r} to a real number".format(s))
    TypeError: unable to convert '(0.0-1.41421356237309j)' to a real number

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 734, in _run
        self.compile_and_execute(example, compiler, test.globs)
        ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 1158, in compile_and_execute
        exec(compiled, globs)
        ~~~~^^^^^^^^^^^^^^^^^
      File "<doctest sage.matrix.matrix2.Matrix.Sequence[23]>", line 1, in <module>
        m.eigenvalues(algorithm="mpmath")  # abs tol 1e-14
        ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
      File "sage/matrix/matrix2.pyx", line 7178, in sage.matrix.matrix2.Matrix.eigenvalues
        self._eigenvectors_left(
      File "sage/matrix/matrix2.pyx", line 7439, in sage.matrix.matrix2.Matrix._eigenvectors_left
        return self._fix_eigenvectors_extend(self._eigenvectors_left_mpmath(), extend)
      File "sage/matrix/matrix2.pyx", line 7624, in sage.matrix.matrix2.Matrix._eigenvectors_left_mpmath
        (C(e), [vector(C, V)], 1)
      File "sage/rings/complex_mpfr.pyx", line 478, in sage.rings.complex_mpfr.ComplexField_class.__call__
        return Parent.__call__(self, x)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/complex_mpfr.pyx", line 564, in sage.rings.complex_mpfr.ComplexField_class._element_constructor_
        return ComplexNumber(self, x)
      File "sage/rings/complex_mpfr.pyx", line 998, in sage.rings.complex_mpfr.ComplexNumber.__init__
        raise TypeError("unable to coerce to a ComplexNumber: %s" % type(real))
    TypeError: unable to coerce to a ComplexNumber: <class 'mpmath.ctx_mp_python.mpc'>
**********************************************************************
File "/usr/lib/python3.14/site-packages/sage/matrix/matrix2.pyx", line 7612, in sage.matrix.matrix2.Matrix.list
Failed example:
    m.eigenvectors_left(algorithm="mpmath")
Exception raised:
    Traceback (most recent call last):
      File "sage/rings/complex_mpfr.pyx", line 993, in sage.rings.complex_mpfr.ComplexNumber.__init__
        rr = R(real)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/real_mpfr.pyx", line 700, in sage.rings.real_mpfr.RealField_class._element_constructor_
        z._set(x, base)
      File "sage/rings/real_mpfr.pyx", line 1574, in sage.rings.real_mpfr.RealNumber._set
        raise TypeError("unable to convert {!r} to a real number".format(s))
    TypeError: unable to convert '(0.0-1.41421356237309j)' to a real number

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 734, in _run
        self.compile_and_execute(example, compiler, test.globs)
        ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 1158, in compile_and_execute
        exec(compiled, globs)
        ~~~~^^^^^^^^^^^^^^^^^
      File "<doctest sage.matrix.matrix2.Matrix.list[1]>", line 1, in <module>
        m.eigenvectors_left(algorithm="mpmath")
        ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^
      File "sage/matrix/matrix2.pyx", line 7417, in sage.matrix.matrix2.Matrix.eigenvectors_left
        return self._eigenvectors_left(
      File "sage/matrix/matrix2.pyx", line 7439, in sage.matrix.matrix2.Matrix._eigenvectors_left
        return self._fix_eigenvectors_extend(self._eigenvectors_left_mpmath(), extend)
      File "sage/matrix/matrix2.pyx", line 7624, in sage.matrix.matrix2.Matrix._eigenvectors_left_mpmath
        (C(e), [vector(C, V)], 1)
      File "sage/rings/complex_mpfr.pyx", line 478, in sage.rings.complex_mpfr.ComplexField_class.__call__
        return Parent.__call__(self, x)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/complex_mpfr.pyx", line 564, in sage.rings.complex_mpfr.ComplexField_class._element_constructor_
        return ComplexNumber(self, x)
      File "sage/rings/complex_mpfr.pyx", line 998, in sage.rings.complex_mpfr.ComplexNumber.__init__
        raise TypeError("unable to coerce to a ComplexNumber: %s" % type(real))
    TypeError: unable to coerce to a ComplexNumber: <class 'mpmath.ctx_mp_python.mpc'>
**********************************************************************
File "/usr/lib/python3.14/site-packages/sage/matrix/matrix2.pyx", line 7615, in sage.matrix.matrix2.Matrix.list
Failed example:
    m.eigenvectors_left(algorithm="mpmath", extend=False)
Exception raised:
    Traceback (most recent call last):
      File "sage/rings/complex_mpfr.pyx", line 993, in sage.rings.complex_mpfr.ComplexNumber.__init__
        rr = R(real)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/real_mpfr.pyx", line 700, in sage.rings.real_mpfr.RealField_class._element_constructor_
        z._set(x, base)
      File "sage/rings/real_mpfr.pyx", line 1574, in sage.rings.real_mpfr.RealNumber._set
        raise TypeError("unable to convert {!r} to a real number".format(s))
    TypeError: unable to convert '(0.0-1.41421356237309j)' to a real number

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 734, in _run
        self.compile_and_execute(example, compiler, test.globs)
        ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/usr/lib/python3.14/site-packages/sage/doctest/forker.py", line 1158, in compile_and_execute
        exec(compiled, globs)
        ~~~~^^^^^^^^^^^^^^^^^
      File "<doctest sage.matrix.matrix2.Matrix.list[2]>", line 1, in <module>
        m.eigenvectors_left(algorithm="mpmath", extend=False)
        ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "sage/matrix/matrix2.pyx", line 7417, in sage.matrix.matrix2.Matrix.eigenvectors_left
        return self._eigenvectors_left(
      File "sage/matrix/matrix2.pyx", line 7439, in sage.matrix.matrix2.Matrix._eigenvectors_left
        return self._fix_eigenvectors_extend(self._eigenvectors_left_mpmath(), extend)
      File "sage/matrix/matrix2.pyx", line 7624, in sage.matrix.matrix2.Matrix._eigenvectors_left_mpmath
        (C(e), [vector(C, V)], 1)
      File "sage/rings/complex_mpfr.pyx", line 478, in sage.rings.complex_mpfr.ComplexField_class.__call__
        return Parent.__call__(self, x)
      File "sage/structure/parent.pyx", line 899, in sage.structure.parent.Parent.__call__
        return mor._call_(x)
      File "sage/structure/coerce_maps.pyx", line 92, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        raise
      File "sage/structure/coerce_maps.pyx", line 87, in sage.structure.coerce_maps.DefaultConvertMap_unique._call_
        return C._element_constructor(x)
      File "sage/rings/complex_mpfr.pyx", line 564, in sage.rings.complex_mpfr.ComplexField_class._element_constructor_
        return ComplexNumber(self, x)
      File "sage/rings/complex_mpfr.pyx", line 998, in sage.rings.complex_mpfr.ComplexNumber.__init__
        raise TypeError("unable to coerce to a ComplexNumber: %s" % type(real))
    TypeError: unable to coerce to a ComplexNumber: <class 'mpmath.ctx_mp_python.mpc'>
**********************************************************************

@antonio-rojas
Copy link
Copy Markdown
Contributor

This fixes the remaining issues

diff --git a/src/sage/functions/error.py b/src/sage/functions/error.py
index 78eb4992aa6..8822b3ed584 100644
--- a/src/sage/functions/error.py
+++ b/src/sage/functions/error.py
@@ -257,7 +257,7 @@ class Function_erf(BuiltinFunction):
             sage: erf(2).n(200)                                                         # needs sage.symbolic
             0.99532226501895273416206925636725292861089179704006007673835
             sage: erf(pi - 1/2*I).n(100)                                                # needs sage.symbolic
-            1.0000111669099367825726058952 + 1.6332655417638522934072124547e-6*I
+            1.0000111669099367825726058952 + 1.633265541763852293407212454...e-6*I
 
         TESTS:
 
diff --git a/src/sage/functions/exp_integral.py b/src/sage/functions/exp_integral.py
index e074c430808..09d2bbda71b 100644
--- a/src/sage/functions/exp_integral.py
+++ b/src/sage/functions/exp_integral.py
@@ -993,7 +993,7 @@ class Function_cos_integral(BuiltinFunction):
             sage: N(cos_integral(10^-10), digits=30)                                    # needs sage.symbolic
             -22.4486352650389239795759024568
             sage: cos_integral(ComplexField(100)(I))                                    # needs sage.symbolic
-            0.83786694098020824089467857943 + 1.5707963267948966192313216916*I
+            0.8378669409802082408946785794... + 1.5707963267948966192313216916*I
         """
         return _mpmath_utils_call(_mpmath_ci, z, parent=parent)
 
diff --git a/src/sage/libs/mpmath/all.py b/src/sage/libs/mpmath/all.py
index ea35faeb721..14a4be971e6 100644
--- a/src/sage/libs/mpmath/all.py
+++ b/src/sage/libs/mpmath/all.py
@@ -22,5 +22,5 @@ _constants_funcs = {
 
 
 def eval_constant(name, ring):
-    prec = ring.precision() + 20
+    prec = int(ring.precision() + 20)
     return ring(_constants_funcs[name](prec)) >> prec
diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx
index 11f58008fcf..ba26d194b1f 100644
--- a/src/sage/rings/complex_mpfr.pyx
+++ b/src/sage/rings/complex_mpfr.pyx
@@ -54,6 +54,7 @@ from sage.rings.integer_ring import ZZ
 
 cimport gmpy2
 gmpy2.import_gmpy2()
+from mpmath import mp
 
 try:
     from cypari2.gen import Gen as pari_gen
@@ -984,7 +985,7 @@ cdef class ComplexNumber(sage.structure.element.FieldElement):
                 real, imag = real
             elif isinstance(real, complex):
                 real, imag = real.real, real.imag
-            elif type(real) is gmpy2.mpc:
+            elif isinstance(real, (gmpy2.mpc, mp.mpc)):
                 real, imag = (<gmpy2.mpc>real).real, (<gmpy2.mpc>real).imag
             else:
                 imag = 0

@kiwifb
Copy link
Copy Markdown
Member Author

kiwifb commented Feb 24, 2026

Thanks for the extra work @antonio-rojas I am not sure when I will have time to act on this. I am bit swamped in my real job and life in general.

@antonio-rojas
Copy link
Copy Markdown
Contributor

antonio-rojas commented Feb 28, 2026

split and rebased the sagelib changes in #41728. The mpmath update requires patching sympy, and I personally no longer want to spend any time on sage-the-distro (and, in general, I think it's good to separate the sagelib changes from the sage-the-distro version upgrades whenever possible)

vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 6, 2026
sagemathgh-41728: Make sagelib compatible with mpmath 1.4
    
pick sagelib changes from sagemath#40669
and sagemath#38565 for mpmath 1.4
compatibility
    
URL: sagemath#41728
Reported by: Antonio Rojas
Reviewer(s):
@orlitzky
Copy link
Copy Markdown
Contributor

orlitzky commented Mar 6, 2026

Looks like the most recent PR will make it in

@orlitzky orlitzky closed this Mar 6, 2026
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 15, 2026
sagemathgh-41728: Make sagelib compatible with mpmath 1.4
    
pick sagelib changes from sagemath#40669
and sagemath#38565 for mpmath 1.4
compatibility
    
URL: sagemath#41728
Reported by: Antonio Rojas
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 18, 2026
sagemathgh-41728: Make sagelib compatible with mpmath 1.4
    
pick sagelib changes from sagemath#40669
and sagemath#38565 for mpmath 1.4
compatibility
    
URL: sagemath#41728
Reported by: Antonio Rojas
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 21, 2026
sagemathgh-41728: Make sagelib compatible with mpmath 1.4
    
pick sagelib changes from sagemath#40669
and sagemath#38565 for mpmath 1.4
compatibility
    
URL: sagemath#41728
Reported by: Antonio Rojas
Reviewer(s):
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 22, 2026
sagemathgh-41728: Make sagelib compatible with mpmath 1.4
    
pick sagelib changes from sagemath#40669
and sagemath#38565 for mpmath 1.4
compatibility
    
URL: sagemath#41728
Reported by: Antonio Rojas
Reviewer(s):
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants