sagemath: update to 10.2.

This commit is contained in:
Gonzalo Tornaría 2023-09-13 19:50:44 -03:00 committed by Leah Neukirchen
parent e95804ddf4
commit a265508ef0
12 changed files with 1974 additions and 2864 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,221 +0,0 @@
diff --git a/build/pkgs/singular/checksums.ini b/build/pkgs/singular/checksums.ini
index 313463d2fea..1101fc55700 100644
--- a/build/pkgs/singular/checksums.ini
+++ b/build/pkgs/singular/checksums.ini
@@ -1,5 +1,5 @@
tarball=singular-VERSION.tar.gz
-sha1=28bb3ee97ef48d04dfa96de182fd93eebe08426c
-md5=fc0a4f5720dadba45a52ee94324ce00c
-cksum=1573851737
-upstream_url=ftp://jim.mathematik.uni-kl.de/pub/Math/Singular/SOURCES/4-3-1/singular-VERSION.tar.gz
+sha1=df1997f412580f2073295aba569bb955ad227317
+md5=50349213e206a18cdaa1bc410dde7ea4
+cksum=376854707
+upstream_url=ftp://jim.mathematik.uni-kl.de/pub/Math/Singular/SOURCES/4-3-2/singular-VERSION.tar.gz
diff --git a/build/pkgs/singular/package-version.txt b/build/pkgs/singular/package-version.txt
index 66e2bede53a..9f1bf008217 100644
--- a/build/pkgs/singular/package-version.txt
+++ b/build/pkgs/singular/package-version.txt
@@ -1 +1 @@
-4.3.1p3
+4.3.2p7
diff --git a/build/pkgs/singular/spkg-configure.m4 b/build/pkgs/singular/spkg-configure.m4
index 6a85631f624..f7621ec5fa1 100644
--- a/build/pkgs/singular/spkg-configure.m4
+++ b/build/pkgs/singular/spkg-configure.m4
@@ -6,14 +6,27 @@ SAGE_SPKG_CONFIGURE([singular], [
AS_IF([test -z "${SINGULAR_BIN}"], [sage_spkg_install_singular=yes], [
dnl Use pkg-config to ensure that Singular is new enough.
PKG_CHECK_MODULES([SINGULAR], [Singular >= 4.2.1], [
- AC_MSG_CHECKING([that Singular's help is working])
- AS_IF([test x`printf "system(\"--browser\", \"builtin\"); \n help;" | Singular 2>&1 | grep "error occurred"` = x], [
- AC_MSG_RESULT(yes)
- ], [
- AC_MSG_RESULT(no)
- sage_spkg_install_singular=yes
- ]
- )], [
+ AC_MSG_CHECKING([whether Singular is built with FLINT])
+ AC_COMPILE_IFELSE([
+ AC_LANG_PROGRAM([
+ #include <singular/singularconfig.h>
+ #if !defined(HAVE_FLINT)
+ # error "Need Singular compiled with FLINT"
+ ], [])
+ ], [
+ AC_MSG_RESULT([yes])
+ AC_MSG_CHECKING([that Singular's help is working])
+ AS_IF([test x`printf "system(\"--browser\", \"builtin\"); \n help;" | Singular 2>&1 | grep "error occurred"` = x], [
+ AC_MSG_RESULT(yes)
+ ], [
+ AC_MSG_RESULT(no)
+ sage_spkg_install_singular=yes
+ ])
+ ], [
+ AC_MSG_RESULT([no])
+ sage_spkg_install_singular=yes
+ ])
+ ], [
dnl pkg-config version check failed
sage_spkg_install_singular=yes
])
diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py
index b15cc1c602c..4b5c76e2bfa 100644
--- a/src/sage/interfaces/singular.py
+++ b/src/sage/interfaces/singular.py
@@ -604,8 +604,7 @@ def eval(self, x, allow_semicolon=True, strip=True, **kwds):
sage: i = singular.ideal(['x^2','y^2','z^2'])
sage: s = i.std()
sage: singular.eval('hilb(%s)'%(s.name()))
- '// 1 t^0\n// -3 t^2\n// 3 t^4\n// -1 t^6\n\n// 1 t^0\n//
- 3 t^1\n// 3 t^2\n// 1 t^3\n// dimension (affine) = 0\n//
+ '...// dimension (affine) = 0\n//
degree (affine) = 8'
::
@@ -613,15 +612,7 @@ def eval(self, x, allow_semicolon=True, strip=True, **kwds):
sage: from sage.misc.verbose import set_verbose
sage: set_verbose(1)
sage: o = singular.eval('hilb(%s)'%(s.name()))
- // 1 t^0
- // -3 t^2
- // 3 t^4
- // -1 t^6
- // 1 t^0
- // 3 t^1
- // 3 t^2
- // 1 t^3
- // dimension (affine) = 0
+ ...// dimension (affine) = 0
// degree (affine) = 8
This is mainly useful if this method is called implicitly. Because
@@ -631,15 +622,7 @@ def eval(self, x, allow_semicolon=True, strip=True, **kwds):
::
sage: o = s.hilb()
- // 1 t^0
- // -3 t^2
- // 3 t^4
- // -1 t^6
- // 1 t^0
- // 3 t^1
- // 3 t^2
- // 1 t^3
- // dimension (affine) = 0
+ ...// dimension (affine) = 0
// degree (affine) = 8
// ** right side is not a datum, assignment ignored
...
diff --git a/src/sage/libs/singular/function.pyx b/src/sage/libs/singular/function.pyx
index f40346d1fd0..c597c63aafe 100644
--- a/src/sage/libs/singular/function.pyx
+++ b/src/sage/libs/singular/function.pyx
@@ -1241,32 +1241,22 @@ cdef class SingularFunction(SageObject):
sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
sage: I = Ideal(I.groebner_basis())
sage: hilb = sage.libs.singular.function_factory.ff.hilb
- sage: hilb(I) # Singular will print // ** _ is no standard basis
- // ** _ is no standard basis
- // 1 t^0
- // -1 t^5
- <BLANKLINE>
- // 1 t^0
- // 1 t^1
- // 1 t^2
- // 1 t^3
- // 1 t^4
- // dimension (proj.) = 1
- // degree (proj.) = 5
+ sage: from sage.misc.sage_ostools import redirection
+ sage: out = tmp_filename()
+ sage: with redirection(sys.stdout, open(out, 'w')):
+ ....: hilb(I) # Singular will print // ** _ is no standard basis
+ sage: with open(out) as f:
+ ....: 'is no standard basis' in f.read()
+ True
So we tell Singular that ``I`` is indeed a Groebner basis::
- sage: hilb(I,attributes={I:{'isSB':1}}) # no complaint from Singular
- // 1 t^0
- // -1 t^5
- <BLANKLINE>
- // 1 t^0
- // 1 t^1
- // 1 t^2
- // 1 t^3
- // 1 t^4
- // dimension (proj.) = 1
- // degree (proj.) = 5
+ sage: out = tmp_filename()
+ sage: with redirection(sys.stdout, open(out, 'w')):
+ ....: hilb(I,attributes={I:{'isSB':1}}) # no complaint from Singular
+ sage: with open(out) as f:
+ ....: 'is no standard basis' in f.read()
+ False
TESTS:
diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py
index 22ada6de947..80352700872 100644
--- a/src/sage/rings/polynomial/multi_polynomial_ideal.py
+++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py
@@ -3132,13 +3132,16 @@ def hilbert_numerator(self, grading=None, algorithm='sage'):
sage: I.hilbert_numerator() # needs sage.rings.number_field
-t^5 + 1
- This example returns a wrong answer due to an integer overflow in Singular::
+ This example returns a wrong answer in singular < 4.3.2p4 due to an integer overflow::
sage: n=4; m=11; P = PolynomialRing(QQ, n*m, "x"); x = P.gens(); M = Matrix(n, x)
sage: I = P.ideal(M.minors(2))
sage: J = P * [m.lm() for m in I.groebner_basis()]
- sage: J.hilbert_numerator(algorithm='singular')
- ...120*t^33 - 3465*t^32 + 48180*t^31 - ...
+ sage: J.hilbert_numerator(algorithm='singular') # known bug
+ Traceback (most recent call last):
+ ....
+ RuntimeError: error in Singular function call 'hilb':
+ overflow at t^22
Our two algorithms should always agree; not tested until
:trac:`33178` is fixed::
diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py
index 02d2021b2fb..c8e15e06f05 100644
--- a/src/sage/sandpiles/sandpile.py
+++ b/src/sage/sandpiles/sandpile.py
@@ -2493,9 +2493,15 @@ def _set_ideal(self):
sage: '_ideal' in S.__dict__
True
"""
+ from sage.libs.singular.function_factory import ff
+ try:
+ sat = ff.elim__lib.sat_with_exp
+ except NameError:
+ sat = ff.elim__lib.sat
R = self.ring()
- I = self._unsaturated_ideal._singular_()
- self._ideal = R.ideal(I.sat(prod(R.gens())._singular_())[1])
+ I = self._unsaturated_ideal
+ I_sat_gens = sat(I, prod(R.gens()))[0]
+ self._ideal = R.ideal(I_sat_gens)
def unsaturated_ideal(self):
r"""
diff --git a/src/sage/schemes/projective/projective_subscheme.py b/src/sage/schemes/projective/projective_subscheme.py
index e6caf19ba74..afd6484d779 100644
--- a/src/sage/schemes/projective/projective_subscheme.py
+++ b/src/sage/schemes/projective/projective_subscheme.py
@@ -1001,7 +1001,10 @@ def dual(self):
for i in range(n + 1):
J = J + S.ideal(z[-1] * f_S.derivative(z[i]) - z[i + n + 1])
- sat = ff.elim__lib.sat
+ try:
+ sat = ff.elim__lib.sat_with_exp
+ except NameError:
+ sat = ff.elim__lib.sat
max_ideal = S.ideal(z[n + 1: 2 * n + 2])
J_sat_gens = sat(J, max_ideal)[0]

View file

@ -1,38 +0,0 @@
diff --git a/src/sage/ext/memory.pyx b/src/sage/ext/memory.pyx
index 1de6dedab82..b95130b19dd 100644
--- a/src/sage/ext/memory.pyx
+++ b/src/sage/ext/memory.pyx
@@ -3,14 +3,14 @@ Low-level memory allocation functions
TESTS:
-Check that a ``MemoryError`` is raised if we try to allocate a
+Check that an error is raised if we try to allocate a
ridiculously large integer, see :trac:`15363`::
- sage: 2^(2^63-3)
- Traceback (most recent call last):
- ...
- OverflowError: exponent must be at most 2147483647 # 32-bit
- RuntimeError: Aborted # 64-bit
+ sage: try:
+ ....: 2^(2^63-3)
+ ....: except (OverflowError, RuntimeError, FloatingPointError):
+ ....: print ('Overflow error')
+ ...Overflow error
AUTHORS:
diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx
index d5e87626d31..37ed9364845 100644
--- a/src/sage/rings/integer.pyx
+++ b/src/sage/rings/integer.pyx
@@ -6654,7 +6654,7 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement):
sage: try:
....: print('Possible error output from gmp', flush=True)
....: 1 << (2^60)
- ....: except (MemoryError, OverflowError, RuntimeError):
+ ....: except (MemoryError, OverflowError, RuntimeError, FloatingPointError):
....: pass
....: else:
....: print("Failed to raise exception")

View file

@ -1,740 +0,0 @@
diff --git a/src/sage/ext_data/valgrind/valgrind-python.supp b/src/sage/ext_data/valgrind/valgrind-python.supp
new file mode 100644
index 00000000000..16aa2858484
--- /dev/null
+++ b/src/sage/ext_data/valgrind/valgrind-python.supp
@@ -0,0 +1,480 @@
+# From the CPython repository with the suppressions for _PyObject_Free
+# and _PyObject_Realloc enabled. See the upstream suppression file for
+# details:
+#
+# https://github.com/python/cpython/blob/main/Misc/valgrind-python.supp
+
+# all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:address_in_range
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:address_in_range
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64)
+ Memcheck:Value8
+ fun:address_in_range
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:address_in_range
+}
+
+#
+# Leaks (including possible leaks)
+# Hmmm, I wonder if this masks some real leaks. I think it does.
+# Will need to fix that.
+#
+
+{
+ Suppress leaking the GIL after a fork.
+ Memcheck:Leak
+ fun:malloc
+ fun:PyThread_allocate_lock
+ fun:PyEval_ReInitThreads
+}
+
+{
+ Suppress leaking the autoTLSkey. This looks like it shouldn't leak though.
+ Memcheck:Leak
+ fun:malloc
+ fun:PyThread_create_key
+ fun:_PyGILState_Init
+ fun:Py_InitializeEx
+ fun:Py_Main
+}
+
+{
+ Hmmm, is this a real leak or like the GIL?
+ Memcheck:Leak
+ fun:malloc
+ fun:PyThread_ReInitTLS
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:realloc
+ fun:_PyObject_GC_Resize
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_New
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+{
+ Handle PyMalloc confusing valgrind (possibly leaked)
+ Memcheck:Leak
+ fun:malloc
+ fun:_PyObject_GC_NewVar
+ fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING
+}
+
+#
+# Non-python specific leaks
+#
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:calloc
+ fun:allocate_dtv
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ Handle pthread issue (possibly leaked)
+ Memcheck:Leak
+ fun:memalign
+ fun:_dl_allocate_tls_storage
+ fun:_dl_allocate_tls
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:_PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:_PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+ Memcheck:Addr8
+ fun:_PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+ Memcheck:Value8
+ fun:_PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:_PyObject_Free
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Addr4
+ fun:_PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Invalid read of size 4
+ Memcheck:Value4
+ fun:_PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+ Memcheck:Addr8
+ fun:_PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Use of uninitialised value of size 8
+ Memcheck:Value8
+ fun:_PyObject_Realloc
+}
+
+{
+ ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value
+ Memcheck:Cond
+ fun:_PyObject_Realloc
+}
+
+###
+### All the suppressions below are for errors that occur within libraries
+### that Python uses. The problems to not appear to be related to Python's
+### use of the libraries.
+###
+
+{
+ Generic ubuntu ld problems
+ Memcheck:Addr8
+ obj:/lib/ld-2.4.so
+ obj:/lib/ld-2.4.so
+ obj:/lib/ld-2.4.so
+ obj:/lib/ld-2.4.so
+}
+
+{
+ Generic gentoo ld problems
+ Memcheck:Cond
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+ obj:/lib/ld-2.3.4.so
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_close
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Value8
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ DBM problems, see test_dbm
+ Memcheck:Cond
+ fun:memmove
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ obj:/usr/lib/libdb1.so.2
+ fun:dbm_store
+ fun:dbm_ass_sub
+}
+
+{
+ GDBM problems, see test_gdbm
+ Memcheck:Param
+ write(buf)
+ fun:write
+ fun:gdbm_open
+
+}
+
+{
+ Uninitialised byte(s) false alarm, see bpo-35561
+ Memcheck:Param
+ epoll_ctl(event)
+ fun:epoll_ctl
+ fun:pyepoll_internal_ctl
+}
+
+{
+ ZLIB problems, see test_gzip
+ Memcheck:Cond
+ obj:/lib/libz.so.1.2.3
+ obj:/lib/libz.so.1.2.3
+ fun:deflate
+}
+
+{
+ Avoid problems w/readline doing a putenv and leaking on exit
+ Memcheck:Leak
+ fun:malloc
+ fun:xmalloc
+ fun:sh_set_lines_and_columns
+ fun:_rl_get_screen_size
+ fun:_rl_init_terminal_io
+ obj:/lib/libreadline.so.4.3
+ fun:rl_initialize
+}
+
+# Valgrind emits "Conditional jump or move depends on uninitialised value(s)"
+# false alarms on GCC builtin strcmp() function. The GCC code is correct.
+#
+# Valgrind bug: https://bugs.kde.org/show_bug.cgi?id=264936
+{
+ bpo-38118: Valgrind emits false alarm on GCC builtin strcmp()
+ Memcheck:Cond
+ fun:PyUnicode_Decode
+}
+
+
+###
+### These occur from somewhere within the SSL, when running
+### test_socket_sll. They are too general to leave on by default.
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:memset
+###}
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:memset
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Cond
+### fun:MD5_Update
+###}
+###
+###{
+### somewhere in SSL stuff
+### Memcheck:Value4
+### fun:MD5_Update
+###}
+
+# Fedora's package "openssl-1.0.1-0.1.beta2.fc17.x86_64" on x86_64
+# See http://bugs.python.org/issue14171
+{
+ openssl 1.0.1 prng 1
+ Memcheck:Cond
+ fun:bcmp
+ fun:fips_get_entropy
+ fun:FIPS_drbg_instantiate
+ fun:RAND_init_fips
+ fun:OPENSSL_init_library
+ fun:SSL_library_init
+ fun:init_hashlib
+}
+
+{
+ openssl 1.0.1 prng 2
+ Memcheck:Cond
+ fun:fips_get_entropy
+ fun:FIPS_drbg_instantiate
+ fun:RAND_init_fips
+ fun:OPENSSL_init_library
+ fun:SSL_library_init
+ fun:init_hashlib
+}
+
+{
+ openssl 1.0.1 prng 3
+ Memcheck:Value8
+ fun:_x86_64_AES_encrypt_compact
+ fun:AES_encrypt
+}
+
+#
+# All of these problems come from using test_socket_ssl
+#
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_bin2bn
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:BN_num_bits_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont_word
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BN_mod_exp_mont
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Param
+ write(buf)
+ fun:write
+ obj:/usr/lib/libcrypto.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:RSA_verify
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_set_key_unchecked
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:DES_encrypt2
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ obj:/usr/lib/libssl.so.0.9.7
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:BUF_MEM_grow_clean
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:memcpy
+ fun:ssl3_read_bytes
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Cond
+ fun:SHA1_Update
+}
+
+{
+ from test_socket_ssl
+ Memcheck:Value4
+ fun:SHA1_Update
+}
+
+{
+ test_buffer_non_debug
+ Memcheck:Addr4
+ fun:PyUnicodeUCS2_FSConverter
+}
+
+{
+ test_buffer_non_debug
+ Memcheck:Addr4
+ fun:PyUnicode_FSConverter
+}
+
+{
+ wcscmp_false_positive
+ Memcheck:Addr8
+ fun:wcscmp
+ fun:_PyOS_GetOpt
+ fun:Py_Main
+ fun:main
+}
+
+# Additional suppressions for the unified decimal tests:
+{
+ test_decimal
+ Memcheck:Addr4
+ fun:PyUnicodeUCS2_FSConverter
+}
+
+{
+ test_decimal2
+ Memcheck:Addr4
+ fun:PyUnicode_FSConverter
+}
+
diff --git a/src/sage/symbolic/ginac/numeric.cpp b/src/sage/symbolic/ginac/numeric.cpp
index b40ed64edb5..8c55861c147 100644
--- a/src/sage/symbolic/ginac/numeric.cpp
+++ b/src/sage/symbolic/ginac/numeric.cpp
@@ -1576,6 +1576,62 @@ const numeric numeric::div(const numeric &other) const {
}
}
+
+// Compute `a^b` as an integer, where a is an integer. Assign to ``res``` if it is integral, or return ``false``.
+// The nonnegative real root is taken for even denominators. To be used inside numeric::integer_rational_power,
+// to handle the special case of integral ``a``.
+bool integer_rational_power_of_mpz(
+ numeric& res,
+ const numeric& a,
+ const numeric& b
+) {
+ if (a.t != MPZ)
+ throw std::runtime_error("integer_rational_power_of_mpz: bad input");
+ mpz_t z;
+ mpz_init(z);
+ mpz_set_ui(z, 0);
+ int sgn = mpz_sgn(a.v._bigint);
+ if (mpz_cmp_ui(a.v._bigint, 1) == 0
+ or mpz_cmp_ui(mpq_numref(b.v._bigrat), 0) == 0)
+ mpz_set_ui(z, 1);
+ else if (sgn == 0) {
+ res = *_num0_p;
+ mpz_clear(z);
+ return true;
+ }
+ else if (sgn < 0 and mpz_cmp_ui(mpq_denref(b.v._bigrat), 1)) {
+ mpz_clear(z);
+ return false;
+ } else {
+ if (not mpz_fits_ulong_p(mpq_numref(b.v._bigrat))
+ or not mpz_fits_ulong_p(mpq_denref(b.v._bigrat))) {
+ // too big to take roots/powers
+ mpz_clear(z);
+ return false;
+ }
+ if (mpz_cmp_ui(mpq_denref(b.v._bigrat), 2) == 0) {
+ if (mpz_perfect_square_p(a.v._bigint)) {
+ mpz_sqrt(z, a.v._bigint);
+ } else {
+ mpz_clear(z);
+ return false;
+ }
+ }
+ else {
+ bool exact = mpz_root(z, a.v._bigint,
+ mpz_get_ui(mpq_denref(b.v._bigrat)));
+ if (not exact) {
+ mpz_clear(z);
+ return false;
+ }
+ }
+ mpz_pow_ui(z, z, mpz_get_ui(mpq_numref(b.v._bigrat)));
+ }
+ res = numeric(z); // transfers ownership, no mpz_clear
+ return true;
+}
+
+
// Compute `a^b` as an integer, if it is integral, or return ``false``.
// The nonnegative real root is taken for even denominators.
bool numeric::integer_rational_power(numeric& res,
@@ -1598,13 +1654,12 @@ bool numeric::integer_rational_power(numeric& res,
if (a.v._long < 0
and mpz_cmp_ui(mpq_denref(b.v._bigrat), 1))
return false;
- long z;
if (not mpz_fits_ulong_p(mpq_numref(b.v._bigrat))
or not mpz_fits_ulong_p(mpq_denref(b.v._bigrat)))
// too big to take roots/powers
return false;
if (b.is_equal(*_num1_2_p)) {
- z = std::lround(std::sqrt(a.v._long));
+ long z = std::lround(std::sqrt(a.v._long));
if (a.v._long == z*z) {
res = numeric(z);
return true;
@@ -1613,44 +1668,11 @@ bool numeric::integer_rational_power(numeric& res,
}
return integer_rational_power(res, a.to_bigint(), b);
}
- if (a.t != MPZ)
- throw std::runtime_error("integer_rational_power: bad input");
- int sgn = mpz_sgn(a.v._bigint);
- mpz_t z;
- mpz_init(z);
- mpz_set_ui(z, 0);
- if (mpz_cmp_ui(a.v._bigint, 1) == 0
- or mpz_cmp_ui(mpq_numref(b.v._bigrat), 0) == 0)
- mpz_set_ui(z, 1);
- else if (sgn == 0) {
- res = *_num0_p;
- return true;
- }
- else if (sgn < 0 and mpz_cmp_ui(mpq_denref(b.v._bigrat), 1))
- return false;
- else {
- if (not mpz_fits_ulong_p(mpq_numref(b.v._bigrat))
- or not mpz_fits_ulong_p(mpq_denref(b.v._bigrat)))
- // too big to take roots/powers
- return false;
- if (mpz_cmp_ui(mpq_denref(b.v._bigrat), 2) == 0) {
- if (mpz_perfect_square_p(a.v._bigint))
- mpz_sqrt(z, a.v._bigint);
- else
- return false;
- }
- else {
- bool exact = mpz_root(z, a.v._bigint,
- mpz_get_ui(mpq_denref(b.v._bigrat)));
- if (not exact)
- return false;
- }
- mpz_pow_ui(z, z, mpz_get_ui(mpq_numref(b.v._bigrat)));
- }
- res = numeric(z);
- return true;
+ // otherwise: a is integer
+ return integer_rational_power_of_mpz(res, a, b);
}
+
// for a^b return c,d such that a^b = c*d^b
// only for MPZ/MPQ base and MPQ exponent
void rational_power_parts(const numeric& a_orig, const numeric& b_orig,
diff --git a/src/sage/tests/memcheck/__init__.py b/src/sage/tests/memcheck/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/src/sage/tests/memcheck/run_tests.py b/src/sage/tests/memcheck/run_tests.py
new file mode 100644
index 00000000000..6ff4503a81b
--- /dev/null
+++ b/src/sage/tests/memcheck/run_tests.py
@@ -0,0 +1,24 @@
+import types
+
+
+def run_tests() -> None:
+ """
+ Run all memcheck tests
+ """
+ from sage.tests.memcheck import symbolic_expression
+ run_tests_in_module(symbolic_expression)
+
+
+def run_tests_in_module(mod: types.ModuleType) -> None:
+ """
+ Run all memcheck tests in the given module
+ """
+ for entry in dir(mod):
+ if not entry.startswith('test_'):
+ continue
+ test_func = getattr(mod, entry)
+ test_func()
+
+
+if __name__ == '__main__':
+ run_tests()
diff --git a/src/sage/tests/memcheck/run_tests_in_valgrind.py b/src/sage/tests/memcheck/run_tests_in_valgrind.py
new file mode 100644
index 00000000000..df5ad0e92b2
--- /dev/null
+++ b/src/sage/tests/memcheck/run_tests_in_valgrind.py
@@ -0,0 +1,35 @@
+"""
+Launch valgrind and run the memory leak tests
+
+
+From the commandline, run
+
+ sage -python -m sage.tests.memcheck.run_tests_in_valgrind
+
+to launch valgrind and execute the memory leak tests. Requires valgrind
+to be installed. Alternatively, run as a unit test:
+
+ sage: from sage.tests.memcheck.run_tests_in_valgrind import run_tests_in_valgrind
+ sage: run_tests_in_valgrind() # optional - valgrind
+"""
+
+import subprocess
+
+
+def run_tests_in_valgrind() -> None:
+ """
+ Run the sage.tests.memcheck.run_tests module inside valgrind
+ """
+ subprocess.check_call([
+ 'valgrind',
+ '--suppressions=src/sage/ext_data/valgrind/valgrind-python.supp',
+ '--show-possibly-lost=no',
+ '--show-reachable=no',
+ './venv/bin/python',
+ '-m',
+ 'sage.tests.memcheck.run_tests'
+ ])
+
+
+if __name__ == '__main__':
+ run_tests_in_valgrind()
diff --git a/src/sage/tests/memcheck/symbolic_expression.py b/src/sage/tests/memcheck/symbolic_expression.py
new file mode 100644
index 00000000000..52182fbe62d
--- /dev/null
+++ b/src/sage/tests/memcheck/symbolic_expression.py
@@ -0,0 +1,11 @@
+from sage.tests.memcheck.verify_no_leak import verify_no_leak
+
+
+def test_sqrt_sqrt_2() -> None:
+ from sage.misc.functional import sqrt
+ T2 = sqrt(2)
+
+ def sqrt_T2() -> None:
+ sqrt(T2)
+
+ verify_no_leak(sqrt_T2)
diff --git a/src/sage/tests/memcheck/verify_no_leak.py b/src/sage/tests/memcheck/verify_no_leak.py
new file mode 100644
index 00000000000..89ca90cf89c
--- /dev/null
+++ b/src/sage/tests/memcheck/verify_no_leak.py
@@ -0,0 +1,27 @@
+from typing import Tuple, Sequence, List, Callable, Any
+import valgrind
+
+
+def verify_no_leak(callback: Callable[[], Any],
+ repeat: int = 10000,
+ fuzzy: int = 10,
+ ) -> None:
+ """
+ Verify that the callback does not generate new definitely lost blocks
+
+ Raises an assertion if the callback leaks memory
+ """
+ callback() # warm_up
+ initial_blocks = (0, 0, 0, 0)
+ valgrind.memcheck_do_leak_check()
+ initial_blocks = valgrind.memcheck_count_leak_blocks()
+ for _ in range(repeat):
+ callback()
+ valgrind.memcheck_do_leak_check()
+ leak_blocks = valgrind.memcheck_count_leak_blocks()
+ leak = leak_blocks[0] - initial_blocks[0]
+ if leak < repeat - fuzzy:
+ return # callback did not leak at least once per call
+ blocks = round(leak / repeat, 2)
+ message = f'{callback} leaked {blocks} block on average ({repeat} iterations)'
+ raise AssertionError(message)

View file

@ -1,39 +0,0 @@
diff --git a/src/sage/libs/ecl.pyx b/src/sage/libs/ecl.pyx
index 8f46570313d..a8e73e57b52 100644
--- a/src/sage/libs/ecl.pyx
+++ b/src/sage/libs/ecl.pyx
@@ -563,15 +563,15 @@ cdef class EclObject:
Floats in Python are IEEE double, which LISP has as well. However,
the printing of floating point types in LISP depends on settings::
- sage: a = EclObject(float(10^40))
+ sage: a = EclObject(float(1.234e40))
sage: ecl_eval("(setf *read-default-float-format* 'single-float)")
<ECL: SINGLE-FLOAT>
sage: a
- <ECL: 1.d40>
+ <ECL: 1.234d40>
sage: ecl_eval("(setf *read-default-float-format* 'double-float)")
<ECL: DOUBLE-FLOAT>
sage: a
- <ECL: 1.e40>
+ <ECL: 1.234e40>
Tuples are translated to dotted lists::
diff --git a/src/sage/libs/eclsig.h b/src/sage/libs/eclsig.h
index e249ccf6874..005b2d99d0b 100644
--- a/src/sage/libs/eclsig.h
+++ b/src/sage/libs/eclsig.h
@@ -45,7 +45,11 @@ static inline void ecl_sig_off(void)
sig_off();
}
+#if ECL_VERSION_NUMBER < 230909
#define ecl_mpz_from_bignum(obj) ((obj)->big.big_num)
+#else
+#define ecl_mpz_from_bignum(obj) ecl_bignum(obj)
+#endif
cl_object ecl_bignum_from_mpz(mpz_t num)
{

View file

@ -1,24 +0,0 @@
diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py
index 59f10f6b13f..adcccff059b 100644
--- a/src/sage/plot/graphics.py
+++ b/src/sage/plot/graphics.py
@@ -36,6 +36,7 @@
# ****************************************************************************
import os
+from numbers import Integral
from collections.abc import Iterable
from math import isnan
import sage.misc.verbose
@@ -2874,6 +2875,11 @@ def matplotlib(self, filename=None,
weight=lopts.pop('font_weight', 'medium'),
variant=lopts.pop('font_variant', 'normal'))
color = lopts.pop('back_color', 'white')
+ if 'loc' in lopts:
+ loc = lopts['loc']
+ if isinstance(loc, Integral):
+ # matplotlib 3.8 doesn't support sage integers
+ lopts['loc'] = int(loc)
leg = subplot.legend(prop=prop, **lopts)
if leg is None:
from warnings import warn

View file

@ -1,29 +0,0 @@
Minor patch so that #36403 applies cleanly over sagemath 10.1
diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx
index 2053bca80c3..86aca6e00d8 100644
--- a/src/sage/matrix/matrix2.pyx
+++ b/src/sage/matrix/matrix2.pyx
@@ -15123,7 +15302,8 @@ cdef class Matrix(Matrix1):
sage: N.conjugate_transpose()
Traceback (most recent call last):
...
- AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object has no attribute 'conjugate'
+ AttributeError: 'sage.rings.finite_rings.integer_mod.IntegerMod_int' object
+ has no attribute 'conjugate'
"""
# limited testing on a 1000 x 1000 matrix over CC:
# transpose is fast, conjugate is slow
diff --git a/src/sage/cpython/getattr.pyx b/src/sage/cpython/getattr.pyx
index 525ea5aa934..52afed49d64 100644
--- a/src/sage/cpython/getattr.pyx
+++ b/src/sage/cpython/getattr.pyx
@@ -55,7 +55,7 @@ cdef class AttributeErrorMessage:
...
AttributeError: 'sage.rings.integer.Integer' object has no attribute 'bla'
sage: x = polygen(ZZ, 'x')
- sage: QQ[x].gen().bla # optional - sage.libs.flint
+ sage: QQ[x].gen().bla # needs sage.libs.flint
Traceback (most recent call last):
...
AttributeError: 'sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint' object has no attribute 'bla'

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,92 @@
diff --git a/src/sage/interfaces/jmoldata.py b/src/sage/interfaces/jmoldata.py
index a68e53e2d85..55c07255b74 100644
--- a/src/sage/interfaces/jmoldata.py
+++ b/src/sage/interfaces/jmoldata.py
@@ -71,6 +71,47 @@ def is_jvm_available(self):
java_version_number = int(re.sub(r'.*version "(0\.|1\.)?(\d*)[\s\S]*', r'\2', version, flags=re.S))
return java_version_number >= 7
+ def jmolpath(self):
+ """
+ Return the path to the jar file.
+
+ EXAMPLES::
+
+ sage: from sage.interfaces.jmoldata import JmolData
+ sage: JData = JmolData()
+ sage: JData.jmolpath()
+ '.../JmolData.jar'
+
+ """
+ jmolpath = os.path.join(JMOL_DIR, "JmolData.jar")
+
+ if sys.platform == 'cygwin':
+ import cygwin
+ jmolpath = cygwin.cygpath(jmolpath, 'w')
+
+ return jmolpath
+
+ def is_jmol_available(self):
+ """
+ Returns True if jmol is available and False if not.
+
+ EXAMPLES:
+
+ Check that it returns a boolean::
+
+ sage: from sage.interfaces.jmoldata import JmolData
+ sage: JData = JmolData()
+ sage: type(JData.is_jmol_available())
+ <... 'bool'>
+ """
+ if not os.path.isfile(self.jmolpath()):
+ return False
+
+ if not self.is_jvm_available():
+ return False
+
+ return True
+
def export_image(self,
targetfile,
datafile, #name (path) of data file Jmol can read or script file telling it what to read or load
@@ -154,12 +195,11 @@ def export_image(self,
sage: archive.close()
"""
# Set up paths, file names and scripts
- jmolpath = os.path.join(JMOL_DIR, "JmolData.jar")
+ jmolpath = self.jmolpath()
target_native = targetfile
if sys.platform == 'cygwin':
import cygwin
- jmolpath = cygwin.cygpath(jmolpath, 'w')
target_native = cygwin.cygpath(target_native, 'w')
if datafile_cmd != 'script':
datafile = cygwin.cygpath(datafile, 'w')
diff --git a/src/sage/plot/plot3d/base.pyx b/src/sage/plot/plot3d/base.pyx
index 253f152130c..7588cde2e27 100644
--- a/src/sage/plot/plot3d/base.pyx
+++ b/src/sage/plot/plot3d/base.pyx
@@ -278,7 +278,7 @@ cdef class Graphics3d(SageObject):
T.export_jmol(scene_zip, **opts)
from sage.interfaces.jmoldata import JmolData
jdata = JmolData()
- if not jdata.is_jvm_available():
+ if not jdata.is_jmol_available():
# We can only use JMol to generate preview if a jvm is installed
from sage.repl.rich_output.output_graphics import OutputImagePng
tachyon = self._rich_repr_tachyon(OutputImagePng, **opts)
diff --git a/src/sage/repl/rich_output/backend_ipython.py b/src/sage/repl/rich_output/backend_ipython.py
index 69e63b76d60..10ccdc0c2c8 100644
--- a/src/sage/repl/rich_output/backend_ipython.py
+++ b/src/sage/repl/rich_output/backend_ipython.py
@@ -369,7 +369,7 @@ def launch_jmol(self, output_jmol, plain_text):
from sage.doctest import DOCTEST_MODE
from sage.interfaces.jmoldata import JmolData
jdata = JmolData()
- if not jdata.is_jvm_available() and not DOCTEST_MODE:
+ if not jdata.is_jmol_available() and not DOCTEST_MODE:
raise RuntimeError('jmol cannot run, no suitable java version found')
launch_script = output_jmol.launch_script_filename()
jmol_cmd = 'jmol'

View file

@ -1,6 +1,6 @@
#! /bin/sh
version=10.1
version=10.2
URL_BASE_PR="https://github.com/sagemath/sage/pull/"
URL_BASE_COMPARE="https://github.com/sagemath/sage/compare/${version}..."
@ -20,24 +20,6 @@ get_pr() {
# run from patches dir
cd $(dirname "$0")
# merged in 10.2.beta0
#get_pr 36018 "singular 4.3.2p4" # included in #35934
get_pr 36046 "fix memory leak"
# merged in 10.2.beta1
get_pr 35934 "singular 4.3.2p7"
# merged in 10.2.beta2
get_pr 36006 "gmp 6.3.0"
# merged in 10.2.beta3
get_pr 36235 "ecl 23.9.9"
# merged in 10.2.beta4
get_pr 36279 "matplotlib 3.8.0"
# positive review
#get_pr 36403 "python 3.12" # included in #36407
# needs review
get_pr 36407 "python 3.12"
get_pr 35848 "flintlib 3.0"
get_pr 36769 "fix jmol detect"

View file

@ -1,14 +1,14 @@
# Template file for 'sagemath'
pkgname=sagemath
version=10.1
revision=4
version=10.2
revision=1
build_wrksrc=pkgs/sagemath-standard
build_style=python3-module
_bindir=/usr/lib/sagemath/$version/bin
make_install_args="--install-scripts=$_bindir"
hostmakedepends="m4 pkg-config python3-Cython0.29 python3-Jinja2
hostmakedepends="m4 pkg-config python3-Cython python3-Jinja2
python3-pkgconfig python3-setuptools"
makedepends="arb-devel boost-devel brial-devel cliquer-devel ecl eclib-devel
makedepends="boost-devel brial-devel cliquer-devel ecl eclib-devel
ecm-devel fflas-ffpack flintlib-devel gap-devel gd-devel giac-devel glpk-devel
gsl-devel iml-devel lcalc-devel libbraiding-devel libhomfly-devel libmpc-devel
libpng-devel linbox-devel m4ri-devel m4rie-devel mpfi-devel
@ -18,7 +18,7 @@ makedepends="arb-devel boost-devel brial-devel cliquer-devel ecl eclib-devel
depends="eclib-devel fflas-ffpack flintlib-devel gcc-fortran gd-devel
gfan giac gsl-devel gzip libpng-devel linbox-devel m4ri-devel maxima-ecl
mpfr-devel nauty ntl-devel palp pari-devel pari-elldata-small pari-galdata
pari-galpol-small pari-seadata-small pkg-config python3-Cython0.29 python3-cypari2
pari-galpol-small pari-seadata-small pkg-config python3-Cython python3-cypari2
python3-cysignals python3-devel python3-fpylll python3-ipython python3-lrcalc
python3-ipython_ipykernel python3-jupyter_ipywidgets python3-matplotlib
python3-memory_allocator python3-networkx python3-pip python3-pkgconfig
@ -33,8 +33,8 @@ license="GPL-2.0-or-later"
homepage="https://www.sagemath.org/"
changelog="https://github.com/sagemath/sage/releases"
distfiles="https://github.com/sagemath/sage/archive/refs/tags/$version.tar.gz"
checksum=a658612b1b2376ddaf207cc8ed0ef458d4c2880c16e19139bedbe8baa42ad62f
nocross="due to ntl (flintlib), fflas-ffpack, givaro, linbox, cysignals, sympow, maxima"
checksum=e7125f13495e1068edab73735aca7f9b2c655688096e9d109e628c023e76411f
nocross="due to ntl (eclib), fflas-ffpack, givaro, linbox, sympow, maxima"
post_patch() {
# git tree needs bootstrapping

View file

@ -1,2 +1,6 @@
pkgname="sage"
site="https://mirrors.mit.edu/sage/src/index.html"
site="https://mirrors.mit.edu/sage/src/"
if [[ "$version" == *[abr]* ]]; then
site+="
https://mirrors.mit.edu/sage/devel/"
fi