From 67c8cbb79521151d88e62ccafe95151e79f41bbb Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 28 Mar 2021 15:00:12 +0200 Subject: [PATCH 001/378] trac #30566: random spanning tree by weights --- src/sage/graphs/spanning_tree.pyx | 76 ++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 922ecc62ecb..e2b801e95e0 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -796,7 +796,7 @@ cpdef boruvka(G, wfunction=None, bint check=False, bint by_weight=True): return T -def random_spanning_tree(self, output_as_graph=False): +def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_function=None): r""" Return a random spanning tree of the graph. @@ -808,11 +808,27 @@ def random_spanning_tree(self, output_as_graph=False): edge `(i, j)` to the spanning tree, where `i` is the previous vertex in the random walk. + When ``by_weight`` is ``True`` or a weight function is given, the selection + of the neighbor is done proportionaly to the edge weights. + INPUT: + - ``G`` -- an undirected graph + - ``output_as_graph`` -- boolean (default: ``False``); whether to return a list of edges or a graph + - ``by_weight`` -- boolean (default: ``False``); if ``True``, the edges in + the graph are weighted, otherwise all edges have weight 1 + + - ``weight_function`` -- function (default: ``None``); a function that takes + as input an edge ``(u, v, l)`` and outputs its weight. If not ``None``, + ``by_weight`` is automatically set to ``True``. If ``None`` and + ``by_weight`` is ``True``, we use the edge label ``l`` , if ``l`` is not + ``None``, else ``1`` as a weight. The ``weight_function`` can be used to + transform the label into a weight (note that, if the weight returned is + not convertible to a float, an error is raised) + .. SEEALSO:: :meth:`~sage.graphs.generic_graph.GenericGraph.spanning_trees_count` @@ -846,6 +862,26 @@ def random_spanning_tree(self, output_as_graph=False): sage: T.set_pos(pos) sage: T.show(vertex_labels=False) + We can also use edge weights to change the probability of returning a + spanning tree:: + + sage: def foo(G, k): + ....: S = set() + ....: for _ in range(k): + ....: E = G.random_spanning_tree(by_weight=True) + ....: S.add(Graph(E).graph6_string()) + ....: return S + sage: K3 = graphs.CompleteGraph(3) + sage: for u, v in K3.edges(labels=False): + ....: K3.set_edge_label(u, v, randint(1, 2)) + sage: foo(K3, 100) == {'BW', 'Bg', 'Bo'} # random + True + sage: K4 = graphs.CompleteGraph(4) + sage: for u, v in K4.edges(labels=False): + ....: K4.set_edge_label(u, v, randint(1, 2)) + sage: print(len(foo(K4, 100))) # random + 16 + TESTS:: sage: G = Graph() @@ -861,21 +897,47 @@ def random_spanning_tree(self, output_as_graph=False): ValueError: works only for non-empty connected graphs """ from sage.misc.prandom import randint + from sage.misc.prandom import random from sage.graphs.graph import Graph - cdef int N = self.order() + cdef int N = G.order() - if not N or not self.is_connected(): + if not N or not G.is_connected(): raise ValueError('works only for non-empty connected graphs') - s = next(self.vertex_iterator()) + if G.order() == G.size() + 1: + # G is a tree + if output_as_graph: + return G.copy() + return list(G.edge_iterator(label=False)) + + if weight_function is not None: + by_weight = True + + if by_weight: + if weight_function is None: + def weight_function(e): + return 1 if e[2] is None else e[2] + + def next_neighbor(s): + p = random() * sum(weight_function(e) + for e in G.edge_iterator(s, sort_vertices=False)) + for e in G.edge_iterator(s, sort_vertices=False): + p -= weight_function(e) + if p <= 0: + break + return e[1] if e[0] == s else e[0] + + else: + def next_neighbor(s): + return G.neighbors(s)[randint(0, G.degree(s) - 1)] + + s = next(G.vertex_iterator()) cdef set found = set([s]) cdef int found_nr = 1 cdef list tree_edges = [] - cdef list neighbors while found_nr < N: - neighbors = self.neighbors(s) - new_s = neighbors[randint(0, len(neighbors) - 1)] + new_s = next_neighbor(s) if new_s not in found: found.add(new_s) found_nr += 1 From b211f2aac6dda659a60da73812ce6e54aa1ec9fe Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 19 Mar 2021 22:08:03 -0700 Subject: [PATCH 002/378] .homebrew-build-env: Use /usr/local/opt/polymake if it exists --- .homebrew-build-env | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.homebrew-build-env b/.homebrew-build-env index a3d58b57ba9..dc0a53d05e3 100644 --- a/.homebrew-build-env +++ b/.homebrew-build-env @@ -2,7 +2,7 @@ # that activate keg-only homebrew package installations HOMEBREW=`brew --prefix` || return 1 -for l in gettext bzip2 texinfo; do +for l in gettext bzip2 texinfo polymake; do if [ -d "$HOMEBREW/opt/$l/bin" ]; then PATH="$HOMEBREW/opt/$l/bin:$PATH" fi @@ -23,7 +23,7 @@ export PKG_CONFIG_PATH LIBRARY_PATH="$HOMEBREW/lib$LIBRARY_PATH" [ -z "$CPATH" ] || CPATH=":${CPATH}" CPATH="$HOMEBREW/include$CPATH" -for l in readline bzip2 ntl; do +for l in readline bzip2 ntl polymake; do if [ -d "$HOMEBREW/opt/$l/lib" ]; then LIBRARY_PATH="$HOMEBREW/opt/$l/lib:$LIBRARY_PATH" fi From 27b4992b2df5258d196f97134021c3ee2bfdcf43 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 19 Mar 2021 22:25:07 -0700 Subject: [PATCH 003/378] build/pkgs/polymake/spkg-configure.m4: New --- build/pkgs/polymake/spkg-configure.m4 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 build/pkgs/polymake/spkg-configure.m4 diff --git a/build/pkgs/polymake/spkg-configure.m4 b/build/pkgs/polymake/spkg-configure.m4 new file mode 100644 index 00000000000..0ebeb12968b --- /dev/null +++ b/build/pkgs/polymake/spkg-configure.m4 @@ -0,0 +1,15 @@ +SAGE_SPKG_CONFIGURE([polymake], [ + dnl Need polymake >= 3.5 for "improve callable library compatibility with threads" + m4_pushdef([POLYMAKE_VERSION_MIN], [3.5]) + AC_CACHE_CHECK([for polymake-config >= ]POLYMAKE_VERSION_MIN, [ac_cv_path_POLYMAKE_CONFIG], [ + AC_PATH_PROGS_FEATURE_CHECK([POLYMAKE_CONFIG], [polymake-config], [ + polymake_config_version=$($ac_path_POLYMAKE_CONFIG --version 2>&1) + AS_IF([test -n "$polymake_config_version"], [ + AX_COMPARE_VERSION([$polymake_config_version], [ge], [1.7.2], [ + ac_cv_path_POLYMAKE_CONFIG="$ac_path_POLYMAKE_CONFIG" + ]) + ]) + ]) + ]) + AS_IF([test -z "$ac_cv_path_POLYMAKE_CONFIG"], [sage_spkg_install_polymake=yes]) +]) From d30256bb0a93b81278be7d7be2d2a82566f39463 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 19 Mar 2021 23:09:12 -0700 Subject: [PATCH 004/378] build/pkgs/polymake/spkg-configure.m4: If system polymake is in use, do not require Perl packages --- build/pkgs/polymake/spkg-configure.m4 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/pkgs/polymake/spkg-configure.m4 b/build/pkgs/polymake/spkg-configure.m4 index 0ebeb12968b..3f631403dbe 100644 --- a/build/pkgs/polymake/spkg-configure.m4 +++ b/build/pkgs/polymake/spkg-configure.m4 @@ -11,5 +11,8 @@ SAGE_SPKG_CONFIGURE([polymake], [ ]) ]) ]) - AS_IF([test -z "$ac_cv_path_POLYMAKE_CONFIG"], [sage_spkg_install_polymake=yes]) + AS_IF([test -z "$ac_cv_path_POLYMAKE_CONFIG"], + [sage_spkg_install_polymake=yes], + [sage_require_perl_cpan_polymake_prereq=no + sage_require_perl_term_readline_gnu=no]) ]) From 6860f90f8939d3d1089ddd0d9c67dda95c058242 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 19 Mar 2021 23:39:54 -0700 Subject: [PATCH 005/378] build/pkgs/polymake/distros: Add more --- build/pkgs/polymake/distros/arch.txt | 1 + build/pkgs/polymake/distros/debian.txt | 1 + build/pkgs/polymake/distros/fedora.txt | 1 + build/pkgs/polymake/distros/gentoo.txt | 1 + 4 files changed, 4 insertions(+) create mode 100644 build/pkgs/polymake/distros/arch.txt create mode 100644 build/pkgs/polymake/distros/debian.txt create mode 100644 build/pkgs/polymake/distros/fedora.txt create mode 100644 build/pkgs/polymake/distros/gentoo.txt diff --git a/build/pkgs/polymake/distros/arch.txt b/build/pkgs/polymake/distros/arch.txt new file mode 100644 index 00000000000..2a9cc70b2f5 --- /dev/null +++ b/build/pkgs/polymake/distros/arch.txt @@ -0,0 +1 @@ +polymake diff --git a/build/pkgs/polymake/distros/debian.txt b/build/pkgs/polymake/distros/debian.txt new file mode 100644 index 00000000000..2a9cc70b2f5 --- /dev/null +++ b/build/pkgs/polymake/distros/debian.txt @@ -0,0 +1 @@ +polymake diff --git a/build/pkgs/polymake/distros/fedora.txt b/build/pkgs/polymake/distros/fedora.txt new file mode 100644 index 00000000000..2a9cc70b2f5 --- /dev/null +++ b/build/pkgs/polymake/distros/fedora.txt @@ -0,0 +1 @@ +polymake diff --git a/build/pkgs/polymake/distros/gentoo.txt b/build/pkgs/polymake/distros/gentoo.txt new file mode 100644 index 00000000000..2a9cc70b2f5 --- /dev/null +++ b/build/pkgs/polymake/distros/gentoo.txt @@ -0,0 +1 @@ +polymake From f4eb33bd909c71d5857e5e9e45f14c7db1138d95 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 Mar 2021 00:09:37 -0700 Subject: [PATCH 006/378] build/pkgs/polymake/dependencies: Make lrslib only an optional dependency --- build/pkgs/polymake/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/polymake/dependencies b/build/pkgs/polymake/dependencies index 3572f765d54..7d77b977a21 100644 --- a/build/pkgs/polymake/dependencies +++ b/build/pkgs/polymake/dependencies @@ -1,4 +1,4 @@ -$(MP_LIBRARY) bliss cddlib lrslib normaliz perl_term_readline_gnu ppl perl_cpan_polymake_prereq libxml2 | ninja_build +$(MP_LIBRARY) bliss cddlib $(findstring lrslib,$(OPTIONAL_INSTALLED_PACKAGES)) normaliz perl_term_readline_gnu ppl perl_cpan_polymake_prereq libxml2 | ninja_build ---------- All lines of this file are ignored except the first. From d93788a4417b503cc4f47927a4c45a24ab3f34c7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 Mar 2021 00:50:30 -0700 Subject: [PATCH 007/378] build/pkgs/polymake/spkg-install.in: Only pass --with-lrs if it is installed --- build/pkgs/polymake/spkg-install.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/pkgs/polymake/spkg-install.in b/build/pkgs/polymake/spkg-install.in index 5a74ff5c609..c7ee9e328fb 100644 --- a/build/pkgs/polymake/spkg-install.in +++ b/build/pkgs/polymake/spkg-install.in @@ -15,11 +15,15 @@ case $(uname) in esac # We disable SoPlex to avoid linking errors (#24905). + # Since polymake v3.4, it does not find our lrs installation if we do not provide --with-lrs explicitly. +if [ -x $SAGE_LOCAL/bin/lrs1 ]; then + more_configure_options="$more_configure_options --with-lrs=$SAGE_LOCAL" +fi + ./configure --without-java \ --without-javaview \ --without-soplex \ - --with-lrs="$SAGE_LOCAL" \ --prefix="$SAGE_LOCAL" \ --exec-prefix="$SAGE_LOCAL" \ --includedir="$SAGE_LOCAL"/include \ From 9ad9e2f8d94cd03e7ccea2474213b2f9b7213421 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 20 Mar 2021 14:41:35 -0700 Subject: [PATCH 008/378] build/pkgs/polymake/distros/debian.txt: Add libpolymake-dev --- build/pkgs/polymake/distros/debian.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/build/pkgs/polymake/distros/debian.txt b/build/pkgs/polymake/distros/debian.txt index 2a9cc70b2f5..6b4b4327e45 100644 --- a/build/pkgs/polymake/distros/debian.txt +++ b/build/pkgs/polymake/distros/debian.txt @@ -1 +1,2 @@ polymake +libpolymake-dev From 43eb34e8129e18a603cdbeabc9ac5d19e60b4d2a Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 25 Jun 2021 14:03:43 -0400 Subject: [PATCH 009/378] Trac #32061: new standard SPKG for GNU Gengetopt 2.23. This is a small GNU package with a standard build system and no external dependencies, so thankfully the SPKG is not very exciting. --- build/pkgs/gengetopt/SPKG.rst | 15 +++++++++++++++ build/pkgs/gengetopt/checksums.ini | 5 +++++ build/pkgs/gengetopt/dependencies | 7 +++++++ build/pkgs/gengetopt/package-version.txt | 1 + build/pkgs/gengetopt/spkg-build.in | 3 +++ build/pkgs/gengetopt/spkg-configure.m4 | 4 ++++ build/pkgs/gengetopt/spkg-install.in | 2 ++ build/pkgs/gengetopt/type | 1 + 8 files changed, 38 insertions(+) create mode 100644 build/pkgs/gengetopt/SPKG.rst create mode 100644 build/pkgs/gengetopt/checksums.ini create mode 100644 build/pkgs/gengetopt/dependencies create mode 100644 build/pkgs/gengetopt/package-version.txt create mode 100644 build/pkgs/gengetopt/spkg-build.in create mode 100644 build/pkgs/gengetopt/spkg-configure.m4 create mode 100644 build/pkgs/gengetopt/spkg-install.in create mode 100644 build/pkgs/gengetopt/type diff --git a/build/pkgs/gengetopt/SPKG.rst b/build/pkgs/gengetopt/SPKG.rst new file mode 100644 index 00000000000..2c62df01867 --- /dev/null +++ b/build/pkgs/gengetopt/SPKG.rst @@ -0,0 +1,15 @@ +gengetopt: getopt_long parser generator +=========================================== + +Description +----------- + +GNU Gengetopt converts a textual description of your program's +arguments and options into a getopt_long() parser in C (or C++). + +Website: https://www.gnu.org/software/gengetopt/ + + +License +------- +GPL-3+ (https://www.gnu.org/software/gengetopt/LICENSE) diff --git a/build/pkgs/gengetopt/checksums.ini b/build/pkgs/gengetopt/checksums.ini new file mode 100644 index 00000000000..189f6c0aaca --- /dev/null +++ b/build/pkgs/gengetopt/checksums.ini @@ -0,0 +1,5 @@ +tarball=gengetopt-VERSION.tar.xz +sha1=0d5979af61a7be309898608803056aeebe3a3657 +md5=ea165d618640dbdecb42ae4491337965 +cksum=3423561524 +upstream_url=ftp://ftp.gnu.org/gnu/gengetopt/gengetopt-VERSION.tar.xz diff --git a/build/pkgs/gengetopt/dependencies b/build/pkgs/gengetopt/dependencies new file mode 100644 index 00000000000..7a7b9cf8a80 --- /dev/null +++ b/build/pkgs/gengetopt/dependencies @@ -0,0 +1,7 @@ +| xz + +xz is needed for unpacking the tarball when sage-bootstrap-python is ancient + +---------- +All lines of this file are ignored except the first. +It is copied by SAGE_ROOT/build/make/install into SAGE_ROOT/build/make/Makefile. diff --git a/build/pkgs/gengetopt/package-version.txt b/build/pkgs/gengetopt/package-version.txt new file mode 100644 index 00000000000..aac433c1a6b --- /dev/null +++ b/build/pkgs/gengetopt/package-version.txt @@ -0,0 +1 @@ +2.23 diff --git a/build/pkgs/gengetopt/spkg-build.in b/build/pkgs/gengetopt/spkg-build.in new file mode 100644 index 00000000000..ffb822c8a97 --- /dev/null +++ b/build/pkgs/gengetopt/spkg-build.in @@ -0,0 +1,3 @@ +cd src +sdh_configure +sdh_make diff --git a/build/pkgs/gengetopt/spkg-configure.m4 b/build/pkgs/gengetopt/spkg-configure.m4 new file mode 100644 index 00000000000..db4c51046d6 --- /dev/null +++ b/build/pkgs/gengetopt/spkg-configure.m4 @@ -0,0 +1,4 @@ +SAGE_SPKG_CONFIGURE([gengetopt], [ + AC_PATH_PROG(GENGETOPT, gengetopt) + AS_IF([test -z "${GENGETOPT}"], [sage_spkg_install_gengetopt=yes]) +]) diff --git a/build/pkgs/gengetopt/spkg-install.in b/build/pkgs/gengetopt/spkg-install.in new file mode 100644 index 00000000000..3ea8c053669 --- /dev/null +++ b/build/pkgs/gengetopt/spkg-install.in @@ -0,0 +1,2 @@ +cd src +sdh_make_install diff --git a/build/pkgs/gengetopt/type b/build/pkgs/gengetopt/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/gengetopt/type @@ -0,0 +1 @@ +standard From 76192dcc3542de8f0a253a3534f57e51229f1825 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 25 Jun 2021 14:07:49 -0400 Subject: [PATCH 010/378] Trac #32061: add distro package information for GNU Gengetopt. Populate gengetopt's "distros" directory based on https://repology.org/project/gengetopt/versions We are still missing at least Conda, FreeBSD, Homebrew, MacPorts, OpenSUSE, and Slackware. --- build/pkgs/gengetopt/distros/cygwin.txt | 1 + build/pkgs/gengetopt/distros/debian.txt | 1 + build/pkgs/gengetopt/distros/fedora.txt | 1 + build/pkgs/gengetopt/distros/gentoo.txt | 1 + build/pkgs/gengetopt/distros/nix.txt | 1 + build/pkgs/gengetopt/distros/repology.txt | 1 + build/pkgs/gengetopt/distros/void.txt | 1 + 7 files changed, 7 insertions(+) create mode 100644 build/pkgs/gengetopt/distros/cygwin.txt create mode 100644 build/pkgs/gengetopt/distros/debian.txt create mode 100644 build/pkgs/gengetopt/distros/fedora.txt create mode 100644 build/pkgs/gengetopt/distros/gentoo.txt create mode 100644 build/pkgs/gengetopt/distros/nix.txt create mode 100644 build/pkgs/gengetopt/distros/repology.txt create mode 100644 build/pkgs/gengetopt/distros/void.txt diff --git a/build/pkgs/gengetopt/distros/cygwin.txt b/build/pkgs/gengetopt/distros/cygwin.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/cygwin.txt @@ -0,0 +1 @@ +gengetopt diff --git a/build/pkgs/gengetopt/distros/debian.txt b/build/pkgs/gengetopt/distros/debian.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/debian.txt @@ -0,0 +1 @@ +gengetopt diff --git a/build/pkgs/gengetopt/distros/fedora.txt b/build/pkgs/gengetopt/distros/fedora.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/fedora.txt @@ -0,0 +1 @@ +gengetopt diff --git a/build/pkgs/gengetopt/distros/gentoo.txt b/build/pkgs/gengetopt/distros/gentoo.txt new file mode 100644 index 00000000000..7ec17eed600 --- /dev/null +++ b/build/pkgs/gengetopt/distros/gentoo.txt @@ -0,0 +1 @@ +dev-util/gengetopt diff --git a/build/pkgs/gengetopt/distros/nix.txt b/build/pkgs/gengetopt/distros/nix.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/nix.txt @@ -0,0 +1 @@ +gengetopt diff --git a/build/pkgs/gengetopt/distros/repology.txt b/build/pkgs/gengetopt/distros/repology.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/repology.txt @@ -0,0 +1 @@ +gengetopt diff --git a/build/pkgs/gengetopt/distros/void.txt b/build/pkgs/gengetopt/distros/void.txt new file mode 100644 index 00000000000..2865264cd70 --- /dev/null +++ b/build/pkgs/gengetopt/distros/void.txt @@ -0,0 +1 @@ +gengetopt From 881c768aae06938d0abcf45db24d2a5bcfa12cd0 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 25 Jun 2021 18:57:18 -0400 Subject: [PATCH 011/378] Trac #32061: add spkg-check.in for gengetopt. Gengetopt has a standard "make check" autotools test suite. This commit allows it to be run with SAGE_CHECK=yes by adding an appropriate spkg-check.in file. --- build/pkgs/gengetopt/spkg-check.in | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 build/pkgs/gengetopt/spkg-check.in diff --git a/build/pkgs/gengetopt/spkg-check.in b/build/pkgs/gengetopt/spkg-check.in new file mode 100644 index 00000000000..45b317a382c --- /dev/null +++ b/build/pkgs/gengetopt/spkg-check.in @@ -0,0 +1,2 @@ +cd src +sdh_make_check From e8ecc6b9c8e7996557eb8c28062b3c400461a395 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 8 Jul 2021 08:31:17 -0400 Subject: [PATCH 012/378] Trac #32061: allow gengetopt to build without makeinfo. The gengetopt release tarball has a bug wherein the maintainer-only rebuild rules for doc/gengetopt.info and doc/gengetopt.html get triggered, and fail if the end user does not have the "makeinfo" program installed. This is not by design; to work around it, we sidestep the "doc" directory entirely, running "make" and "make install" only within the executable/gnulib subdirectories. --- build/pkgs/gengetopt/spkg-build.in | 8 ++++++++ build/pkgs/gengetopt/spkg-install.in | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/build/pkgs/gengetopt/spkg-build.in b/build/pkgs/gengetopt/spkg-build.in index ffb822c8a97..08e39b1143b 100644 --- a/build/pkgs/gengetopt/spkg-build.in +++ b/build/pkgs/gengetopt/spkg-build.in @@ -1,3 +1,11 @@ cd src sdh_configure + +# Don't run "make" at the top-level because the documentation build +# requires the "makeinfo" program. This is a bug that should be fixed +# in gengetopt-2.24. First build gnulib, then build gengetopt. +cd gl sdh_make +cd ../src +sdh_make +cd .. diff --git a/build/pkgs/gengetopt/spkg-install.in b/build/pkgs/gengetopt/spkg-install.in index 3ea8c053669..c6d060135dd 100644 --- a/build/pkgs/gengetopt/spkg-install.in +++ b/build/pkgs/gengetopt/spkg-install.in @@ -1,2 +1,7 @@ cd src + +# Only run "make install" in the src directory to avoid the +# documentation, which currently (due to a bug) tries to invoke the +# "makeinfo" program. +cd src sdh_make_install From d677a53ea96a20dc332c00d1469b3ebf39521892 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 1 Aug 2021 12:43:53 +0800 Subject: [PATCH 013/378] warn when Ideal() creates an ideal in a field --- src/sage/rings/ideal.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 53076ac62ed..57757e36703 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -35,6 +35,8 @@ import sage.rings.infinity from sage.structure.sequence import Sequence +import warnings + def Ideal(*args, **kwds): r""" Create the ideal in ring with given generators. @@ -183,6 +185,10 @@ def Ideal(*args, **kwds): gens = args gens = Sequence(gens) R = gens.universe() + if isinstance(R, sage.rings.ring.Field) and not hasattr(R, 'fractional_ideal'): + warnings.warn(f'Constructing an ideal in {R}, which is a field.' + ' Did you intend to take numerators first?' + ' This warning can be muted by passing the base ring to Ideal() explicitly.') else: R = first gens = args[1:] From 6705fccfaff6f81f719a740c5e9e52b6781e3c37 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Tue, 10 Aug 2021 10:49:09 -0400 Subject: [PATCH 014/378] implement derivative for graded forms and quasiforms --- src/sage/modular/modform/element.py | 61 +++++++++++++++ src/sage/modular/quasimodform/element.py | 94 ++++++++++++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index ef826b35db9..aeb5224d012 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -3722,3 +3722,64 @@ def to_polynomial(self, names='x', gens=None): # sum the polynomial of each homogeneous part return sum(M(self[k])._homogeneous_to_polynomial(names, gens) for k in self.weights_list()) + + def serre_derivative(self): + r""" + Return the Serre derivative of the given graded modular form. If ``self`` + is a modular form of weight `k`, then the returned modular form will be + of weight `k + 2`. If the form is not homogeneous, then this method sums + the Serre derivative of each homogeneous components. + + EXAMPLES:: + + sage: M = ModularFormsRing(1) + sage: E4 = M.0 + sage: E6 = M.1 + sage: DE4 = E4.serre_derivative(); DE4 + -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6) + sage: DE4 == (-1/3) * E6 + True + sage: DE6 = E6.serre_derivative(); DE6 + -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6) + sage: DE6 == (-1/2) * E4^2 + True + sage: f = E4 + E6 + sage: Df = f.serre_derivative(); Df + -5/6 - 72*q - 25416*q^2 - 484128*q^3 - 3785544*q^4 - 18225072*q^5 + O(q^6) + sage: Df == (-1/3) * E6 + (-1/2) * E4^2 + True + sage: M(1/2).serre_derivative() + 0 + """ + M = self.parent() + return M(sum(M(f.serre_derivative()) for k, f in self._forms_dictionary.items() if k != 0)) + + def derivative(self, name='E2'): + r""" + Return the derivative `q \frac{d}{dq}` of the given graded form. Note + that this method returns an element of a new parent, that is a + quasimodular form. If the form is not homogeneous, then this method sums + the derivative of each homogeneous components. + + INPUT: + + - ``name`` (str, default: 'E2') - the name of the weight 2 Eisenstein + series generating the graded algebra of quasimodular forms over the + ring of modular forms. + + OUTPUT: a :class:`sage.modular.quasimodform.element.QuasiModularFormsElement` + + EXAMPLES:: + + sage: M = ModularFormsRing(1) + sage: E4 = M.0; E6 = M.1 + sage: dE4 = E4.derivative(); dE4 + 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6) + sage: dE4.parent() + Ring of Quasimodular Forms for Modular Group SL(2,Z) over Rational Field + sage: dE4.is_modular_form() + False + """ + from sage.modular.quasimodform.ring import QuasiModularForms + F = QuasiModularForms(self.group(), self.base_ring(), name)(self) + return F.derivative() diff --git a/src/sage/modular/quasimodform/element.py b/src/sage/modular/quasimodform/element.py index 5b8242e036d..da815d8dd10 100644 --- a/src/sage/modular/quasimodform/element.py +++ b/src/sage/modular/quasimodform/element.py @@ -436,3 +436,97 @@ def homogeneous_components(self): poly_self = self.to_polynomial() pol_hom_comp = poly_self.homogeneous_components() return { k : QM.from_polynomial(pol) for k, pol in pol_hom_comp.items()} + + def serre_derivative(self): + r""" + Return the Serre derivative of the given quasimodular form. If the form + is not homogeneous, then this method sums the serre derivative of each + homogeneous components. + + EXAMPLES:: + + sage: QM = QuasiModularForms(1) + sage: E2, E4, E6 = QM.gens() + sage: DE2 = E2.serre_derivative(); DE2 + -1/6 - 16*q - 216*q^2 - 832*q^3 - 2248*q^4 - 4320*q^5 + O(q^6) + sage: DE2 == (-E2^2 - E4)/12 + True + sage: DE4 = E4.serre_derivative(); DE4 + -1/3 + 168*q + 5544*q^2 + 40992*q^3 + 177576*q^4 + 525168*q^5 + O(q^6) + sage: DE4 == (-1/3) * E6 + True + sage: DE6 = E6.serre_derivative(); DE6 + -1/2 - 240*q - 30960*q^2 - 525120*q^3 - 3963120*q^4 - 18750240*q^5 + O(q^6) + sage: DE6 == (-1/2) * E4^2 + True + + The Serre derivative raises the weight of homogeneous elements by 2:: + + sage: F = E6 + E4 * E2 + sage: F.weight() + 6 + sage: F.serre_derivative().weight() + 8 + """ + # initial variables: + QM = self.parent() + R = QM.base_ring() + E2 = QM.gen(0) + E4 = QM.gen(1) + + # compute the derivative of E2: q*dE2/dq + E2deriv = R(12).inverse_of_unit() * (E2 ** 2 - E4) + + # sum the Serre derivative of each monomial of the form: f * E2^n + # they are equal to: + # [E2^n * serre_deriv(f)] + [n * f * E2^(n-1) * D(E2)] - [n/6 * f * E2^(n+1)] + # = A + B - C + der = QM.zero() + u6 = R(6).inverse_of_unit() + for n, f in enumerate(self._coefficients): + if n == 0: + der += QM(f.serre_derivative()) + else: + A = (E2 ** n) * f.serre_derivative() + B = R(n) * f * E2 ** (n - 1) * E2deriv + C = R(n) * u6 * E2 ** (n + 1) * f + der += QM(A + B - C) + return der + + def derivative(self): + r""" + Return the derivative `q \frac{d}{dq}` of the given quasiform. If the + form is not homogeneous, then this method sums the derivative of each + homogeneous components. + + EXAMPLES:: + + sage: QM = QuasiModularForms(1) + sage: E2, E4, E6 = QM.gens() + sage: dE2 = E2.derivative(); dE2 + -24*q - 144*q^2 - 288*q^3 - 672*q^4 - 720*q^5 + O(q^6) + sage: dE2 == (E2^2 - E4)/12 # Ramanujan identity + True + sage: dE4 = E4.derivative(); dE4 + 240*q + 4320*q^2 + 20160*q^3 + 70080*q^4 + 151200*q^5 + O(q^6) + sage: dE4 == (E2 * E4 - E6)/3 # Ramanujan identity + True + sage: dE6 = E6.derivative(); dE6 + -504*q - 33264*q^2 - 368928*q^3 - 2130912*q^4 - 7877520*q^5 + O(q^6) + sage: dE6 == (E2 * E6 - E4^2)/2 # Ramanujan identity + True + + Note that the derivative of a modular form is not necessarily a modular form:: + + sage: dE4.is_modular_form() + False + sage: dE4.weight() + 6 + """ + QM = self.parent() + E2 = QM.gen(0) + R = self.base_ring() + u = R(12).inverse_of_unit() + hom_comp = self.homogeneous_components() + + return sum(f.serre_derivative() + R(k) * u * f * E2 for k, f in hom_comp.items()) From ffded0ae69dfd8fcf33e90cb2eae7c809411519d Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Wed, 11 Aug 2021 09:46:40 -0400 Subject: [PATCH 015/378] added Hn function --- .../shifted_symmetric_functions/__init__.py | 1 + .../shifted_symmetric_functions/all.py | 1 + .../shifted_symmetric_functions/q_bracket.py | 53 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 src/sage/combinat/shifted_symmetric_functions/__init__.py create mode 100644 src/sage/combinat/shifted_symmetric_functions/all.py create mode 100644 src/sage/combinat/shifted_symmetric_functions/q_bracket.py diff --git a/src/sage/combinat/shifted_symmetric_functions/__init__.py b/src/sage/combinat/shifted_symmetric_functions/__init__.py new file mode 100644 index 00000000000..6e633f48916 --- /dev/null +++ b/src/sage/combinat/shifted_symmetric_functions/__init__.py @@ -0,0 +1 @@ +from . import all diff --git a/src/sage/combinat/shifted_symmetric_functions/all.py b/src/sage/combinat/shifted_symmetric_functions/all.py new file mode 100644 index 00000000000..82b9b34635c --- /dev/null +++ b/src/sage/combinat/shifted_symmetric_functions/all.py @@ -0,0 +1 @@ +from .q_bracket import * diff --git a/src/sage/combinat/shifted_symmetric_functions/q_bracket.py b/src/sage/combinat/shifted_symmetric_functions/q_bracket.py new file mode 100644 index 00000000000..fee6c40abe9 --- /dev/null +++ b/src/sage/combinat/shifted_symmetric_functions/q_bracket.py @@ -0,0 +1,53 @@ +from sage.modular.quasimodform.ring import QuasiModularForms + +from sage.rings.all import Integer + +def Hn(n): + r""" + Return the `n`-th `H_n` function defined by the recurrence relation + `4n(n-1)H_n = 8D(H_n(n-2)) + PH_n(n-2)`. + + INPUT: + + - `n` - (int, Integer) a nonnegative integer. + + EXAMPLES:: + + sage: from sage.combinat.shifted_symmetric_functions.q_bracket import Hn + sage: Hn(0) + 1 + sage: Hn(1) + 0 + sage: Hn(2) + 1/24 - q - 3*q^2 - 4*q^3 - 7*q^4 - 6*q^5 + O(q^6) + sage: Hn(2).to_polynomial('P, Q, R') + 1/24*P + + OUTPUT: A quasimodular form defined by the recurrence relation above. + + TESTS:: + + sage: Hn('n') + Traceback (most recent call last): + ... + ValueError: n (=n) must be a nonnegative integer + sage: Hn(-1) + Traceback (most recent call last): + ... + ValueError: n (=-1) must be a nonnegative integer + """ + if not isinstance(n, (int, Integer)) or n < 0: + raise ValueError("n (=%s) must be a nonnegative integer" % (n)) + QM = QuasiModularForms(1) + if n == 0: + H = QM.one() + elif n%2 or n == 1: + H = QM.zero() + else: + P, Q, R = QM.gens() + RR = QM.base_ring() + u = RR(4 * n * (n + 1)).inverse_of_unit() + H = u * (RR(8) * Hn(n - 2).derivative() + P * Hn(n - 2)) + return H + +# def q_bracket(polynomial, output_as_polynomial=True, names='P, Q, R'): From aa898ad59aa104de61ea70a4419a49870edc379e Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 15 Aug 2021 17:35:27 +0800 Subject: [PATCH 016/378] fractional ideals should be fractional ideals --- src/sage/rings/number_field/number_field_ideal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index 54d7ebb1535..dd18421bfd3 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -46,7 +46,7 @@ import sage.misc.misc as misc from sage.rings.finite_rings.finite_field_constructor import FiniteField -from sage.rings.ideal import Ideal_generic +from sage.rings.ideal import Ideal_generic, Ideal_fractional from sage.misc.all import prod from sage.misc.mrange import xmrange_iter from sage.misc.cachefunc import cached_method @@ -1734,7 +1734,7 @@ def is_NumberFieldIdeal(x): return isinstance(x, NumberFieldIdeal) -class NumberFieldFractionalIdeal(MultiplicativeGroupElement, NumberFieldIdeal): +class NumberFieldFractionalIdeal(MultiplicativeGroupElement, NumberFieldIdeal, Ideal_fractional): r""" A fractional ideal in a number field. From 5f69b30a313e9be643d1d6c935d54a4440584b8b Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 15 Aug 2021 17:17:44 +0800 Subject: [PATCH 017/378] do not warn when the constructed ideal is a fractional ideal --- src/sage/rings/ideal.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 57757e36703..dc4b9dcf447 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -174,6 +174,7 @@ def Ideal(*args, **kwds): first = args[0] + inferred_field = False if not isinstance(first, sage.rings.ring.Ring): if isinstance(first, Ideal_generic) and len(args) == 1: R = first.ring() @@ -185,10 +186,7 @@ def Ideal(*args, **kwds): gens = args gens = Sequence(gens) R = gens.universe() - if isinstance(R, sage.rings.ring.Field) and not hasattr(R, 'fractional_ideal'): - warnings.warn(f'Constructing an ideal in {R}, which is a field.' - ' Did you intend to take numerators first?' - ' This warning can be muted by passing the base ring to Ideal() explicitly.') + inferred_field = isinstance(R, sage.rings.ring.Field) else: R = first gens = args[1:] @@ -196,7 +194,14 @@ def Ideal(*args, **kwds): if not isinstance(R, sage.rings.ring.CommutativeRing): raise TypeError("R must be a commutative ring") - return R.ideal(*gens, **kwds) + I = R.ideal(*gens, **kwds) + + if inferred_field and not isinstance(I, Ideal_fractional): # trac 32327 + warnings.warn(f'Constructing an ideal in {R}, which is a field.' + ' Did you intend to take numerators first?' + ' This warning can be muted by passing the base ring to Ideal() explicitly.') + + return I def is_Ideal(x): r""" From fb94cd6635a3f2a3dcd50eaebf9403bb561ec79b Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 15 Aug 2021 17:51:53 +0800 Subject: [PATCH 018/378] only import the warnings module when needed --- src/sage/rings/ideal.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index dc4b9dcf447..5817778515f 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -35,8 +35,6 @@ import sage.rings.infinity from sage.structure.sequence import Sequence -import warnings - def Ideal(*args, **kwds): r""" Create the ideal in ring with given generators. @@ -197,6 +195,7 @@ def Ideal(*args, **kwds): I = R.ideal(*gens, **kwds) if inferred_field and not isinstance(I, Ideal_fractional): # trac 32327 + import warnings warnings.warn(f'Constructing an ideal in {R}, which is a field.' ' Did you intend to take numerators first?' ' This warning can be muted by passing the base ring to Ideal() explicitly.') From bc6fdeb65596c5cb5f407210be0b437c638dd429 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sun, 15 Aug 2021 17:52:33 +0800 Subject: [PATCH 019/378] oops, fix trac number in comment --- src/sage/rings/ideal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/ideal.py b/src/sage/rings/ideal.py index 5817778515f..971dde7a2d7 100644 --- a/src/sage/rings/ideal.py +++ b/src/sage/rings/ideal.py @@ -194,7 +194,7 @@ def Ideal(*args, **kwds): I = R.ideal(*gens, **kwds) - if inferred_field and not isinstance(I, Ideal_fractional): # trac 32327 + if inferred_field and not isinstance(I, Ideal_fractional): # trac 32320 import warnings warnings.warn(f'Constructing an ideal in {R}, which is a field.' ' Did you intend to take numerators first?' From 8039ce43a85aae80f543f0cfbaa97731f7252fe9 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Mon, 16 Aug 2021 00:15:32 +0800 Subject: [PATCH 020/378] add doctest for #32380 --- src/sage/rings/number_field/number_field_ideal.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/rings/number_field/number_field_ideal.py b/src/sage/rings/number_field/number_field_ideal.py index dd18421bfd3..4618672eb13 100644 --- a/src/sage/rings/number_field/number_field_ideal.py +++ b/src/sage/rings/number_field/number_field_ideal.py @@ -1747,6 +1747,14 @@ class NumberFieldFractionalIdeal(MultiplicativeGroupElement, NumberFieldIdeal, I sage: Jinv = I^(-2) sage: J*Jinv Fractional ideal (1) + + TESTS: + + Number-field fractional ideals are fractional ideals (:trac:`32380`):: + + sage: from sage.rings.ideal import Ideal_fractional + sage: isinstance(I, Ideal_fractional) + True """ def __init__(self, field, gens, coerce=True): """ From b0bbc1e887c05fe2c8b05089cdf15fe21c0156a0 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 25 Aug 2021 11:01:39 +0900 Subject: [PATCH 021/378] Remove unnecessary spacer code --- src/sage/misc/html.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/sage/misc/html.py b/src/sage/misc/html.py index 7dacc5f2748..9a0bc5efead 100644 --- a/src/sage/misc/html.py +++ b/src/sage/misc/html.py @@ -299,7 +299,8 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): # Get a regular LaTeX representation of x x = latex(x, combine_all=combine_all) - # The following block, hopefully, can be removed in some future MathJax. + # The "\text{\texttt{...}}" blocks are reformed to be renderable by MathJax. + # These blocks are produced by str_function() defined in sage.misc.latex. prefix = r"\text{\texttt{" parts = x.split(prefix) for i, part in enumerate(parts): @@ -324,7 +325,6 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): delimiter = "|" y = "(complicated string)" wrapper = r"\verb" + delimiter + "%s" + delimiter - spacer = r"\phantom{\verb!%s!}" y = y.replace("{ }", " ").replace("{-}", "-") for c in r"#$%&\^_{}~": char_wrapper = r"{\char`\%s}" % c @@ -336,14 +336,12 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): nspaces += 1 continue if nspaces > 0: - subparts.append(spacer % ("x" * nspaces)) + subparts.append(wrapper % (" " * nspaces)) nspaces = 1 subparts.append(wrapper % subpart) - # There is a bug with omitting empty lines in arrays - if not y: - subparts.append(spacer % "x") subparts.append(part[closing + 1:]) parts[i] = "".join(subparts) + from sage.misc.latex_macros import sage_configurable_latex_macros from sage.misc.latex import _Latex_prefs latex_string = ''.join( @@ -351,6 +349,7 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): [_Latex_prefs._option['macros']] + parts ) + if mode == 'display': html = r'\[{0}\]' elif mode == 'inline': From 656a8d3c6f9088e1c126a5b69b630a2c70bbe890 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Tue, 31 Aug 2021 21:04:29 +0900 Subject: [PATCH 022/378] Fix doctest failures --- src/sage/misc/html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/html.py b/src/sage/misc/html.py index 9a0bc5efead..07da7581fb9 100644 --- a/src/sage/misc/html.py +++ b/src/sage/misc/html.py @@ -294,7 +294,7 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): sage: MathJax().eval(3, mode='inline') \(\newcommand{\Bold}[1]{\mathbf{#1}}3\) sage: MathJax().eval(type(3), mode='inline') - \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb||\) + \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb||\) """ # Get a regular LaTeX representation of x x = latex(x, combine_all=combine_all) @@ -411,7 +411,7 @@ def __call__(self, obj, concatenate=True, strict=False): sagemath sage: html('sagemath', strict=True) - \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|sagemath|\] + \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|sagemath|\] """ # string obj is interpreted as an HTML in not strict mode if isinstance(obj, str) and not strict: From 52584ab2fa434105cfcbc865395bf63b29e423b3 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Tue, 14 Sep 2021 14:46:45 -0400 Subject: [PATCH 023/378] fix docbuild errors --- src/sage/modular/quasimodform/element.py | 11 ++++++----- src/sage/modular/quasimodform/ring.py | 8 +++++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sage/modular/quasimodform/element.py b/src/sage/modular/quasimodform/element.py index 150c2ebe4a4..feb5029157e 100644 --- a/src/sage/modular/quasimodform/element.py +++ b/src/sage/modular/quasimodform/element.py @@ -340,15 +340,16 @@ def is_modular_form(self): def to_polynomial(self, names='E2, E4, E6'): r""" - Return a polynomial `P(E_2, E_4, E_6)` corresponding to the given form - where `E_2`, `E_4` and `E_6` are the generators of the quasimodular - form ring given by :meth:`~sage.modular.quasiform.ring.QuasiModularForms.gens`. + Return a multivariate polynomial `P(E_2, E_4, E_6)` corresponding to the + given form where `E_2`, `E_4` and `E_6` are the generators of the + quasimodular form ring given by + :meth:`~sage.modular.quasiform.ring.QuasiModularForms.gens`. INPUT: - ``names`` (str, default: ``'E2, E4, E6'``) -- a list or tuple of names - (strings), or a comma separated string. Correspond to the names of the - variables; + (strings), or a comma separated string. Correspond to the names of the + variables; OUTPUT: A multivariate polynomial in the variables ``names`` diff --git a/src/sage/modular/quasimodform/ring.py b/src/sage/modular/quasimodform/ring.py index 5736d7cf3d0..8845d090765 100644 --- a/src/sage/modular/quasimodform/ring.py +++ b/src/sage/modular/quasimodform/ring.py @@ -494,15 +494,17 @@ def polygen(self): def polynomial_ring(self, names='E2, E4, E6'): r""" Return a multivariate polynomial ring isomorphic to the given graded - quasimodular forms ring. In the case of the full modular group, this + quasimodular forms ring. + + In the case of the full modular group, this ring is `R[E_2, E_4, E_6]` where `E_2`, `E_4` and `E_6` have degrees 2, 4 and 6 respectively. INPUT: - ``names`` (str, default: ``'E2, E4, E6'``) -- a list or tuple of names - (strings), or a comma separated string. Correspond to the names of the - variables; + (strings), or a comma separated string. Correspond to the names of the + variables. OUTPUT: A multivariate polynomial ring in the variables ``names`` From cb29e98053fca6818e365a36a4c22fa46f7f1e3c Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Thu, 16 Sep 2021 16:42:09 -0400 Subject: [PATCH 024/378] initial q_bracket implementation --- .../shifted_symmetric_functions/q_bracket.py | 144 +++++++++++++++++- 1 file changed, 143 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/shifted_symmetric_functions/q_bracket.py b/src/sage/combinat/shifted_symmetric_functions/q_bracket.py index fee6c40abe9..7b0b503ff59 100644 --- a/src/sage/combinat/shifted_symmetric_functions/q_bracket.py +++ b/src/sage/combinat/shifted_symmetric_functions/q_bracket.py @@ -1,6 +1,7 @@ from sage.modular.quasimodform.ring import QuasiModularForms from sage.rings.all import Integer +from sage.rings.polynomial.multi_polynomial_element import MPolynomial def Hn(n): r""" @@ -50,4 +51,145 @@ def Hn(n): H = u * (RR(8) * Hn(n - 2).derivative() + P * Hn(n - 2)) return H -# def q_bracket(polynomial, output_as_polynomial=True, names='P, Q, R'): +def _compute_derivative(polynomial): + r""" + Compute the shifted symmetric derivative of the given polynomial. + + INPUT: + + - ``polynomial`` -- a multivariate polynomial over `\QQ`. + + TESTS:: + + sage: from sage.combinat.shifted_symmetric_functions.q_bracket import _compute_derivative + sage: P. = QQ[] + sage: _compute_derivative(Q6) + Q5 + sage: _compute_derivative(Q5) + Q4 + sage: _compute_derivative(Q1) + 1 + sage: _compute_derivative(Q1 + Q3 + Q5) + Q2 + Q4 + 1 + sage: _compute_derivative(Q3 * Q5) + Q3*Q4 + Q2*Q5 + """ + if not isinstance(polynomial, MPolynomial): + raise ValueError("the given polynomial must be a multivariate polynomial") + poly_parent = polynomial.parent() + if polynomial in poly_parent.base_ring(): + return poly_parent.zero() + poly_gens = poly_parent.gens() + mon_list = polynomial.monomials() + der = poly_parent.zero() + + # compute the derivative for every monomials + for m in mon_list: + coeff = polynomial.monomial_coefficient(m) + degrees_list = list(m.degrees()) + der_m = poly_parent.zero() + for i in range(poly_parent.ngens()): + if degrees_list[i] != 0: + product_gen = poly_parent.one() + for j in range(poly_parent.ngens()): + d = degrees_list[j] + if d != 0: + if j == 0: + product_gen *= d * poly_gens[j] ** (d - 1) + elif j == i: + product_gen *= d * poly_gens[j] ** (d - 1) * poly_gens[j - 1] + else: + product_gen *= poly_gens[j] ** d + der_m += product_gen + der += coeff * der_m + return der + +def shifted_symmetric_derivative(polynomial, order=1): + r""" + Return the shifted symmetric derivative of the given polynomial. + + INPUT: + + - ``polynomial`` -- a multivariate polynomial over `\QQ`. + - ``order`` (Integer, default: 1) -- the order of the derivative. + + EXAMPLES:: + + sage: from sage.combinat.shifted_symmetric_functions.q_bracket import shifted_symmetric_derivative + sage: P. = QQ[] + sage: shifted_symmetric_derivative(Q2) + Q1 + sage: shifted_symmetric_derivative(Q2 * Q4) + Q2*Q3 + Q1*Q4 + sage: shifted_symmetric_derivative(Q4^5) + 5*Q3*Q4^4 + sage: shifted_symmetric_derivative(Q2^3, order=2) + 6*Q1*Q2 + 3*Q2^2 + """ + der_n = polynomial + for n in range(order): + der_n = _compute_derivative(der_n) + return der_n + + +def _compute_q_bracket(polynomial): + r""" + Compute the `q`-bracket of the given (shifted symmetric) polynomial. + + TESTS:: + + sage: from sage.combinat.shifted_symmetric_functions.q_bracket import _compute_q_bracket + sage: P. = QQ[] + sage: _compute_q_bracket(Q2) + -1/24 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) + sage: _compute_q_bracket(Q2 ** 2) + 7/2880 + 1/12*q + 9/4*q^2 + 31/3*q^3 + 343/12*q^4 + 117/2*q^5 + O(q^6) + sage: _compute_q_bracket(Q4) + 7/5760 + 1/24*q + 9/8*q^2 + 31/6*q^3 + 343/24*q^4 + 117/4*q^5 + O(q^6) + """ + if not isinstance(polynomial, MPolynomial): + raise ValueError("polynomial must be a multivariate polynomial") + QM = QuasiModularForms(1) + poly_parent = polynomial.parent() + if polynomial.is_constant(): + return QM(polynomial.base_ring()(polynomial)) + if polynomial % poly_parent.gen(0) == 0: + return QM.zero() + weighted_deg = polynomial.weighted_degree(list(range(1, poly_parent.ngens() + 1))) + bracket = QM.zero() + for n in range(2, weighted_deg + 1, 2): + der = shifted_symmetric_derivative(polynomial, order=n) + bracket += sum(-Hn(n) * der.monomial_coefficient(m) * _compute_q_bracket(m) for m in der.monomials()) + return bracket + +def q_bracket(polynomial, output_as_polynomial=True, names='P, Q, R'): + r""" + Return the `q`-bracket of the given (shifted symmetric) polynomial. + + If ``output_as_polynomial`` is set to ``True``, then the output will be a + multivariate polynomial in the generators of the ring of quasimodular forms + for `\mathrm{SL}_2(\ZZ)`. + + INPUT: + + - ``polynomial`` -- a multivariate polynomial over `\QQ` + - ``output_as_polynomial`` (default: True) -- a boolean + - ``names`` (default: 'P, Q, R') -- a string of names representing the + the generators of the quasimodular forms ring. + + EXAMPLES:: + + sage: from sage.combinat.shifted_symmetric_functions.q_bracket import q_bracket + sage: P. = QQ[] + sage: q_bracket(Q2) + -1/24*P + sage: q_bracket(Q3) + 0 + sage: q_bracket(Q4) + 1/1152*P^2 + 1/2880*Q + sage: q_bracket(Q2 ** 2) + 1/576*P^2 + 1/1440*Q + sage: q_bracket(Q2, output_as_polynomial=False) + -1/24 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) + """ + return _compute_q_bracket(polynomial).to_polynomial(names) if output_as_polynomial else _compute_q_bracket(polynomial) From e8986614aaed069c6c4351250a1ce07387332482 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Mon, 27 Sep 2021 11:15:11 -0400 Subject: [PATCH 025/378] revert last commits --- .../shifted_symmetric_functions/__init__.py | 1 - .../shifted_symmetric_functions/all.py | 1 - .../shifted_symmetric_functions/q_bracket.py | 195 ------------------ 3 files changed, 197 deletions(-) delete mode 100644 src/sage/combinat/shifted_symmetric_functions/__init__.py delete mode 100644 src/sage/combinat/shifted_symmetric_functions/all.py delete mode 100644 src/sage/combinat/shifted_symmetric_functions/q_bracket.py diff --git a/src/sage/combinat/shifted_symmetric_functions/__init__.py b/src/sage/combinat/shifted_symmetric_functions/__init__.py deleted file mode 100644 index 6e633f48916..00000000000 --- a/src/sage/combinat/shifted_symmetric_functions/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import all diff --git a/src/sage/combinat/shifted_symmetric_functions/all.py b/src/sage/combinat/shifted_symmetric_functions/all.py deleted file mode 100644 index 82b9b34635c..00000000000 --- a/src/sage/combinat/shifted_symmetric_functions/all.py +++ /dev/null @@ -1 +0,0 @@ -from .q_bracket import * diff --git a/src/sage/combinat/shifted_symmetric_functions/q_bracket.py b/src/sage/combinat/shifted_symmetric_functions/q_bracket.py deleted file mode 100644 index 7b0b503ff59..00000000000 --- a/src/sage/combinat/shifted_symmetric_functions/q_bracket.py +++ /dev/null @@ -1,195 +0,0 @@ -from sage.modular.quasimodform.ring import QuasiModularForms - -from sage.rings.all import Integer -from sage.rings.polynomial.multi_polynomial_element import MPolynomial - -def Hn(n): - r""" - Return the `n`-th `H_n` function defined by the recurrence relation - `4n(n-1)H_n = 8D(H_n(n-2)) + PH_n(n-2)`. - - INPUT: - - - `n` - (int, Integer) a nonnegative integer. - - EXAMPLES:: - - sage: from sage.combinat.shifted_symmetric_functions.q_bracket import Hn - sage: Hn(0) - 1 - sage: Hn(1) - 0 - sage: Hn(2) - 1/24 - q - 3*q^2 - 4*q^3 - 7*q^4 - 6*q^5 + O(q^6) - sage: Hn(2).to_polynomial('P, Q, R') - 1/24*P - - OUTPUT: A quasimodular form defined by the recurrence relation above. - - TESTS:: - - sage: Hn('n') - Traceback (most recent call last): - ... - ValueError: n (=n) must be a nonnegative integer - sage: Hn(-1) - Traceback (most recent call last): - ... - ValueError: n (=-1) must be a nonnegative integer - """ - if not isinstance(n, (int, Integer)) or n < 0: - raise ValueError("n (=%s) must be a nonnegative integer" % (n)) - QM = QuasiModularForms(1) - if n == 0: - H = QM.one() - elif n%2 or n == 1: - H = QM.zero() - else: - P, Q, R = QM.gens() - RR = QM.base_ring() - u = RR(4 * n * (n + 1)).inverse_of_unit() - H = u * (RR(8) * Hn(n - 2).derivative() + P * Hn(n - 2)) - return H - -def _compute_derivative(polynomial): - r""" - Compute the shifted symmetric derivative of the given polynomial. - - INPUT: - - - ``polynomial`` -- a multivariate polynomial over `\QQ`. - - TESTS:: - - sage: from sage.combinat.shifted_symmetric_functions.q_bracket import _compute_derivative - sage: P. = QQ[] - sage: _compute_derivative(Q6) - Q5 - sage: _compute_derivative(Q5) - Q4 - sage: _compute_derivative(Q1) - 1 - sage: _compute_derivative(Q1 + Q3 + Q5) - Q2 + Q4 + 1 - sage: _compute_derivative(Q3 * Q5) - Q3*Q4 + Q2*Q5 - """ - if not isinstance(polynomial, MPolynomial): - raise ValueError("the given polynomial must be a multivariate polynomial") - poly_parent = polynomial.parent() - if polynomial in poly_parent.base_ring(): - return poly_parent.zero() - poly_gens = poly_parent.gens() - mon_list = polynomial.monomials() - der = poly_parent.zero() - - # compute the derivative for every monomials - for m in mon_list: - coeff = polynomial.monomial_coefficient(m) - degrees_list = list(m.degrees()) - der_m = poly_parent.zero() - for i in range(poly_parent.ngens()): - if degrees_list[i] != 0: - product_gen = poly_parent.one() - for j in range(poly_parent.ngens()): - d = degrees_list[j] - if d != 0: - if j == 0: - product_gen *= d * poly_gens[j] ** (d - 1) - elif j == i: - product_gen *= d * poly_gens[j] ** (d - 1) * poly_gens[j - 1] - else: - product_gen *= poly_gens[j] ** d - der_m += product_gen - der += coeff * der_m - return der - -def shifted_symmetric_derivative(polynomial, order=1): - r""" - Return the shifted symmetric derivative of the given polynomial. - - INPUT: - - - ``polynomial`` -- a multivariate polynomial over `\QQ`. - - ``order`` (Integer, default: 1) -- the order of the derivative. - - EXAMPLES:: - - sage: from sage.combinat.shifted_symmetric_functions.q_bracket import shifted_symmetric_derivative - sage: P. = QQ[] - sage: shifted_symmetric_derivative(Q2) - Q1 - sage: shifted_symmetric_derivative(Q2 * Q4) - Q2*Q3 + Q1*Q4 - sage: shifted_symmetric_derivative(Q4^5) - 5*Q3*Q4^4 - sage: shifted_symmetric_derivative(Q2^3, order=2) - 6*Q1*Q2 + 3*Q2^2 - """ - der_n = polynomial - for n in range(order): - der_n = _compute_derivative(der_n) - return der_n - - -def _compute_q_bracket(polynomial): - r""" - Compute the `q`-bracket of the given (shifted symmetric) polynomial. - - TESTS:: - - sage: from sage.combinat.shifted_symmetric_functions.q_bracket import _compute_q_bracket - sage: P. = QQ[] - sage: _compute_q_bracket(Q2) - -1/24 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - sage: _compute_q_bracket(Q2 ** 2) - 7/2880 + 1/12*q + 9/4*q^2 + 31/3*q^3 + 343/12*q^4 + 117/2*q^5 + O(q^6) - sage: _compute_q_bracket(Q4) - 7/5760 + 1/24*q + 9/8*q^2 + 31/6*q^3 + 343/24*q^4 + 117/4*q^5 + O(q^6) - """ - if not isinstance(polynomial, MPolynomial): - raise ValueError("polynomial must be a multivariate polynomial") - QM = QuasiModularForms(1) - poly_parent = polynomial.parent() - if polynomial.is_constant(): - return QM(polynomial.base_ring()(polynomial)) - if polynomial % poly_parent.gen(0) == 0: - return QM.zero() - weighted_deg = polynomial.weighted_degree(list(range(1, poly_parent.ngens() + 1))) - bracket = QM.zero() - for n in range(2, weighted_deg + 1, 2): - der = shifted_symmetric_derivative(polynomial, order=n) - bracket += sum(-Hn(n) * der.monomial_coefficient(m) * _compute_q_bracket(m) for m in der.monomials()) - return bracket - -def q_bracket(polynomial, output_as_polynomial=True, names='P, Q, R'): - r""" - Return the `q`-bracket of the given (shifted symmetric) polynomial. - - If ``output_as_polynomial`` is set to ``True``, then the output will be a - multivariate polynomial in the generators of the ring of quasimodular forms - for `\mathrm{SL}_2(\ZZ)`. - - INPUT: - - - ``polynomial`` -- a multivariate polynomial over `\QQ` - - ``output_as_polynomial`` (default: True) -- a boolean - - ``names`` (default: 'P, Q, R') -- a string of names representing the - the generators of the quasimodular forms ring. - - EXAMPLES:: - - sage: from sage.combinat.shifted_symmetric_functions.q_bracket import q_bracket - sage: P. = QQ[] - sage: q_bracket(Q2) - -1/24*P - sage: q_bracket(Q3) - 0 - sage: q_bracket(Q4) - 1/1152*P^2 + 1/2880*Q - sage: q_bracket(Q2 ** 2) - 1/576*P^2 + 1/1440*Q - sage: q_bracket(Q2, output_as_polynomial=False) - -1/24 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) - """ - return _compute_q_bracket(polynomial).to_polynomial(names) if output_as_polynomial else _compute_q_bracket(polynomial) From de1a48c38bf33bc3dc4c2dc82770d6ad8c08c14f Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Thu, 11 Feb 2021 16:26:54 -0800 Subject: [PATCH 026/378] sage.misc.packages, sage-list-packages: Use new class PackageInfo --- src/bin/sage-list-packages | 12 ++-- src/sage/doctest/control.py | 4 +- src/sage/misc/package.py | 117 ++++++++++++++++++++++-------------- 3 files changed, 79 insertions(+), 54 deletions(-) diff --git a/src/bin/sage-list-packages b/src/bin/sage-list-packages index f2e9331ca2e..813b1c0d648 100755 --- a/src/bin/sage-list-packages +++ b/src/bin/sage-list-packages @@ -91,16 +91,16 @@ else: if WARN: print(WARN) if args['installed_only']: - L = [pkg for pkg in L if pkg['installed']] + L = [pkg for pkg in L if pkg.is_installed()] elif args['not_installed_only']: - L = [pkg for pkg in L if not pkg['installed']] + L = [pkg for pkg in L if not pkg.is_installed()] -L.sort(key=lambda pkg: pkg['name']) +L.sort(key=lambda pkg: pkg.name) # print (while getting rid of None in versions) for pkg in L: - pkg['installed_version'] = pkg['installed_version'] or 'not_installed' - pkg['remote_version'] = pkg['remote_version'] or '?' - print(format_string.format(**pkg)) + pkg.installed_version = pkg.installed_version or 'not_installed' + pkg.remote_version = pkg.remote_version or '?' + print(format_string.format(**pkg._asdict())) if WARN: print(WARN) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index afb0d6cbcf1..fdce853a074 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -365,8 +365,8 @@ def __init__(self, options, args): options.optional.discard('optional') from sage.misc.package import list_packages for pkg in list_packages('optional', local=True).values(): - if pkg['installed'] and pkg['installed_version'] == pkg['remote_version']: - options.optional.add(pkg['name']) + if pkg.is_installed() and pkg.installed_version == pkg.remote_version: + options.optional.add(pkg.name) from sage.features import package_systems options.optional.update(system.name for system in package_systems()) diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index c42435101c5..e37f63862b2 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -40,6 +40,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** +from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union import sage.env @@ -159,15 +160,13 @@ def pip_installed_packages(normalization=None): stderr=devnull, ) stdout = proc.communicate()[0].decode() - - def normalize(name): + def normalize(name: str): if normalization is None: return name elif normalization == 'spkg': return name.lower().replace('-', '_').replace('.', '_') else: raise NotImplementedError(f'normalization {normalization} is not implemented') - try: return {normalize(package['name']): package['version'] for package in json.loads(stdout)} @@ -176,12 +175,50 @@ def normalize(name): # This may happen if pip is not correctly installed. return {} -def list_packages(*pkg_types, **opts): +class PackageInfo(NamedTuple): + """Represents information about a package.""" + name: str + type: Optional[str] = None + source: Optional[str] = None + installed_version: Optional[str] = None + remote_version: Optional[str] = None + + def is_installed(self) -> bool: + return self.installed_version is not None + + def __getitem__(self, key: Union[int, str]): + """ + Only for backwards compatibility to allow dict-like access. + + TESTS:: + + sage: package = PackageInfo("test_package") + sage: package["name"] + doctest:...: DeprecationWarning: dict-like access is deprecated, use e.g `pkg.name` instead of `pkg[name]` + See https://trac.sagemath.org/31013 for details. + test_package + sage: package[0] + test_package + """ + if isinstance(key, str): + from sage.misc.superseded import deprecation + + if key == "installed": + deprecation(31013, "dict-like access via `installed` is deprecated, use `is_installed` instead") + return self.is_installed() + else: + deprecation(31013, "dict-like access is deprecated, use e.g `pkg.name` instead of `pkg[name]`") + return self.__getattribute__(key) + else: + return tuple.__getitem__(self, key) + + +def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 'script'], + local: bool = False, ignore_URLError: bool = False, exclude_pip: bool = False) -> Dict[str, PackageInfo]: r""" Return a dictionary of information about each package. - The keys are package names and values are dictionaries with the following - keys: + The keys are package names and values are named tuples with the following keys: - ``'type'``: either ``'base``, ``'standard'``, ``'optional'``, or ``'experimental'`` - ``'source'``: either ``'normal', ``'pip'``, or ``'script'`` @@ -221,24 +258,24 @@ def list_packages(*pkg_types, **opts): ... 'zn_poly'] sage: sage_conf_info = L['sage_conf'] # optional - build - sage: sage_conf_info['type'] # optional - build + sage: sage_conf_info.type # optional - build 'standard' - sage: sage_conf_info['installed'] # optional - build + sage: sage_conf_info.installed # optional - build True - sage: sage_conf_info['source'] # optional - build + sage: sage_conf_info.source # optional - build 'script' sage: L = list_packages(pkg_sources=['pip'], local=True) # optional - build internet sage: bs4_info = L['beautifulsoup4'] # optional - build internet - sage: bs4_info['type'] # optional - build internet + sage: bs4_info.type # optional - build internet 'optional' - sage: bs4_info['source'] # optional - build internet + sage: bs4_info.source # optional - build internet 'pip' Check the option ``exclude_pip``:: sage: [p for p, d in list_packages('optional', exclude_pip=True).items() # optional - build - ....: if d['source'] == 'pip'] + ....: if d.source == 'pip'] [] """ if not pkg_types: @@ -246,21 +283,13 @@ def list_packages(*pkg_types, **opts): elif any(pkg_type not in ('base', 'standard', 'optional', 'experimental') for pkg_type in pkg_types): raise ValueError("Each pkg_type must be one of 'base', 'standard', 'optional', 'experimental'") - pkg_sources = opts.pop('pkg_sources', - ('normal', 'pip', 'script')) - - local = opts.pop('local', False) - ignore_URLError = opts.pop('ignore_URLError', False) - exclude_pip = opts.pop('exclude_pip', False) if exclude_pip: pkg_sources = [s for s in pkg_sources if s != 'pip'] - if opts: - raise ValueError("{} are not valid options".format(sorted(opts))) - pkgs = {p: {'name': p, 'installed_version': v, 'installed': True, - 'remote_version': None, 'source': None} + pkgs = {p: PackageInfo(name=p, installed_version=v) for p, v in installed_packages('pip' not in pkg_sources).items()} + # Add additional information based on Sage's package repository lp = [] SAGE_PKGS = sage.env.SAGE_PKGS if not SAGE_PKGS: @@ -289,33 +318,29 @@ def list_packages(*pkg_types, **opts): else: src = 'script' - pkg = pkgs.get(p, dict()) - pkgs[p] = pkg - if typ not in pkg_types or src not in pkg_sources: - del pkgs[p] + try: + del pkgs[p] + except KeyError: + pass continue - pkg.update({'name': p, 'type': typ, 'source': src}) - if pkg.get('installed_version', None): - pkg['installed'] = True - else: - pkg['installed'] = False - pkg['installed_version'] = None - - if pkg['source'] == 'pip': + if src == 'pip': if not local: - pkg['remote_version'] = pip_remote_version(p, ignore_URLError=ignore_URLError) + remote_version = pip_remote_version(p, ignore_URLError=ignore_URLError) else: - pkg['remote_version'] = None - elif pkg['source'] == 'normal': + remote_version = None + elif src == 'normal': # If package-version.txt does not exist, that is an error # in the build system => we just propagate the exception package_filename = os.path.join(SAGE_PKGS, p, "package-version.txt") with open(package_filename) as f: - pkg['remote_version'] = f.read().strip() + remote_version = f.read().strip() else: - pkg['remote_version'] = 'none' + remote_version = None + + pkg = pkgs.get(p, PackageInfo(name=p)) + pkgs[p] = PackageInfo(p, typ, src, pkg.installed_version, remote_version) return pkgs @@ -444,7 +469,7 @@ def package_versions(package_type, local=False): sage: std['zn_poly'] # optional - build, random ('0.9.p12', '0.9.p12') """ - return {pkg['name']: (pkg['installed_version'], pkg['remote_version']) for pkg in list_packages(package_type, local=local).values()} + return {pkg.name: (pkg.installed_version, pkg.remote_version) for pkg in list_packages(package_type, local=local).values()} def standard_packages(): @@ -477,8 +502,8 @@ def standard_packages(): 'the functions standard_packages, optional_packages, experimental_packages' 'are deprecated, use sage.features instead') pkgs = list_packages('standard', local=True).values() - return (sorted(pkg['name'] for pkg in pkgs if pkg['installed']), - sorted(pkg['name'] for pkg in pkgs if not pkg['installed'])) + return (sorted(pkg.name for pkg in pkgs if pkg.is_installed()), + sorted(pkg.name for pkg in pkgs if not pkg.is_installed())) def optional_packages(): @@ -515,8 +540,8 @@ def optional_packages(): 'are deprecated, use sage.features instead') pkgs = list_packages('optional', local=True) pkgs = pkgs.values() - return (sorted(pkg['name'] for pkg in pkgs if pkg['installed']), - sorted(pkg['name'] for pkg in pkgs if not pkg['installed'])) + return (sorted(pkg.name for pkg in pkgs if pkg.is_installed()), + sorted(pkg.name for pkg in pkgs if not pkg.is_installed())) def experimental_packages(): @@ -547,8 +572,8 @@ def experimental_packages(): 'the functions standard_packages, optional_packages, experimental_packages' 'are deprecated, use sage.features instead') pkgs = list_packages('experimental', local=True).values() - return (sorted(pkg['name'] for pkg in pkgs if pkg['installed']), - sorted(pkg['name'] for pkg in pkgs if not pkg['installed'])) + return (sorted(pkg.name for pkg in pkgs if pkg.is_installed()), + sorted(pkg.name for pkg in pkgs if not pkg.is_installed())) def package_manifest(package): """ From ebc4f82361cb640446683ba22e155d80085ab005 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 10 Dec 2020 09:44:56 -0800 Subject: [PATCH 027/378] sage.misc.package.PackageInfo: Improve wording of deprecation message, fix doctests --- src/sage/misc/package.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index e37f63862b2..6c684a535b6 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -184,30 +184,35 @@ class PackageInfo(NamedTuple): remote_version: Optional[str] = None def is_installed(self) -> bool: + r""" + Whether the package is installed in the system. + """ return self.installed_version is not None def __getitem__(self, key: Union[int, str]): - """ + r""" Only for backwards compatibility to allow dict-like access. TESTS:: + sage: from sage.misc.package import PackageInfo sage: package = PackageInfo("test_package") sage: package["name"] - doctest:...: DeprecationWarning: dict-like access is deprecated, use e.g `pkg.name` instead of `pkg[name]` - See https://trac.sagemath.org/31013 for details. - test_package + doctest:warning... + dict-like access is deprecated, use pkg.name instead of pkg['name'], for example + See https://trac.sagemath.org/31013 for details. + 'test_package' sage: package[0] - test_package + 'test_package' """ if isinstance(key, str): from sage.misc.superseded import deprecation if key == "installed": - deprecation(31013, "dict-like access via `installed` is deprecated, use `is_installed` instead") + deprecation(31013, "dict-like access via 'installed' is deprecated, use method is_installed instead") return self.is_installed() else: - deprecation(31013, "dict-like access is deprecated, use e.g `pkg.name` instead of `pkg[name]`") + deprecation(31013, "dict-like access is deprecated, use pkg.name instead of pkg['name'], for example") return self.__getattribute__(key) else: return tuple.__getitem__(self, key) From 18bcf003b88a98f6a33a98d2849a257b3ae9067b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 10 Dec 2020 09:45:34 -0800 Subject: [PATCH 028/378] sage.misc.package.list_packages: Align optional tags in doctests --- src/sage/misc/package.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index 6c684a535b6..df003eb7e73 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -255,26 +255,26 @@ def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 's EXAMPLES:: sage: from sage.misc.package import list_packages - sage: L = list_packages('standard') # optional - build - sage: sorted(L.keys()) # optional - build, random + sage: L = list_packages('standard') # optional - build + sage: sorted(L.keys()) # optional - build, random ['alabaster', 'arb', 'babel', ... 'zn_poly'] sage: sage_conf_info = L['sage_conf'] # optional - build - sage: sage_conf_info.type # optional - build + sage: sage_conf_info.type # optional - build 'standard' - sage: sage_conf_info.installed # optional - build + sage: sage_conf_info.is_installed() # optional - build True - sage: sage_conf_info.source # optional - build + sage: sage_conf_info.source # optional - build 'script' sage: L = list_packages(pkg_sources=['pip'], local=True) # optional - build internet sage: bs4_info = L['beautifulsoup4'] # optional - build internet - sage: bs4_info.type # optional - build internet + sage: bs4_info.type # optional - build internet 'optional' - sage: bs4_info.source # optional - build internet + sage: bs4_info.source # optional - build internet 'pip' Check the option ``exclude_pip``:: From 8b06dc85e95a2d23c52390d55f04baedd399aa3b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Jan 2021 22:40:24 +0100 Subject: [PATCH 029/378] Code cleanup --- src/sage/misc/package.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package.py b/src/sage/misc/package.py index df003eb7e73..0d2c2f5818f 100644 --- a/src/sage/misc/package.py +++ b/src/sage/misc/package.py @@ -40,7 +40,7 @@ # (at your option) any later version. # https://www.gnu.org/licenses/ # **************************************************************************** -from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union +from typing import Dict, List, NamedTuple, Optional, Union import sage.env @@ -160,7 +160,8 @@ def pip_installed_packages(normalization=None): stderr=devnull, ) stdout = proc.communicate()[0].decode() - def normalize(name: str): + + def normalize(name: str) -> str: if normalization is None: return name elif normalization == 'spkg': @@ -175,6 +176,7 @@ def normalize(name: str): # This may happen if pip is not correctly installed. return {} + class PackageInfo(NamedTuple): """Represents information about a package.""" name: str @@ -334,7 +336,7 @@ def list_packages(*pkg_types: str, pkg_sources: List[str] = ['normal', 'pip', 's if not local: remote_version = pip_remote_version(p, ignore_URLError=ignore_URLError) else: - remote_version = None + remote_version = None elif src == 'normal': # If package-version.txt does not exist, that is an error # in the build system => we just propagate the exception From ebfb13c9868424e685a1462c1755137777a96640 Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Thu, 30 Sep 2021 12:54:26 -0700 Subject: [PATCH 030/378] trac 31385: fix sage_setup to use the new package attributes --- src/sage_setup/optional_extension.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage_setup/optional_extension.py b/src/sage_setup/optional_extension.py index 06586f1d393..f2528493846 100644 --- a/src/sage_setup/optional_extension.py +++ b/src/sage_setup/optional_extension.py @@ -48,7 +48,7 @@ def is_package_installed_and_updated(pkg): # Might be an installed old-style package condition = is_package_installed(pkg) else: - condition = (pkginfo["installed_version"] == pkginfo["remote_version"]) + condition = (pkginfo.installed_version == pkginfo.remote_version) return condition From b02da5e7045d4038f7fba0392982db9b2f278b5d Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Fri, 1 Oct 2021 13:51:01 -0400 Subject: [PATCH 031/378] fix failing doctests --- src/sage/modular/quasimodform/element.py | 4 ++-- src/sage/modular/quasimodform/ring.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/modular/quasimodform/element.py b/src/sage/modular/quasimodform/element.py index 77333acceda..b174e4c979b 100644 --- a/src/sage/modular/quasimodform/element.py +++ b/src/sage/modular/quasimodform/element.py @@ -368,7 +368,7 @@ def to_polynomial(self, names='E2, E4, E6'): P = self.parent().polynomial_ring(names) g0, g1 = self.parent().modular_forms_subring().polynomial_ring(names='x').gens() E2, E4, E6 = P.gens() - return sum(f.to_polynomial().subs({g0:E4, g1:E6}) * E2 ** exp for exp, f in enumerate(self._coefficients)) + return sum(f.to_polynomial().subs({g0:E4, g1:E6}) * E2 ** exp for exp, f in enumerate(self._polynomial.coefficients(sparse=False))) def weights_list(self): r""" @@ -503,7 +503,7 @@ def serre_derivative(self): # = A + B - C der = QM.zero() u6 = R(6).inverse_of_unit() - for n, f in enumerate(self._coefficients): + for n, f in enumerate(self._polynomial.coefficients(sparse=False)): if n == 0: der += QM(f.serre_derivative()) else: diff --git a/src/sage/modular/quasimodform/ring.py b/src/sage/modular/quasimodform/ring.py index 3cbf94a7ec8..8845d090765 100644 --- a/src/sage/modular/quasimodform/ring.py +++ b/src/sage/modular/quasimodform/ring.py @@ -75,7 +75,7 @@ from sage.modular.modform.space import ModularFormsSpace from sage.modular.modform.ring import ModularFormsRing -from sage.rings.all import Integer, QQ +from sage.rings.all import Integer, QQ, ZZ from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.multi_polynomial import MPolynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing From 69784190e03a32daeaa675709840ca30ebbf539d Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 4 Oct 2021 18:27:25 +0200 Subject: [PATCH 032/378] First attempt for transcendental extensions. Ring creation seems to work sa2si is broken si2sa not started --- src/sage/libs/singular/decl.pxd | 13 ++++++++++ src/sage/libs/singular/ring.pyx | 40 ++++++++++++++++++++++++++++- src/sage/libs/singular/singular.pyx | 37 +++++++++++++++++++++++++- 3 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 806937ff6e1..54c3fd36e58 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -401,6 +401,8 @@ cdef extern from "singular/Singular/libsingular.h": cdef omBin *slists_bin + cdef omBin *fractionObjectBin + # integer conversion constant cdef long SR_INT @@ -1136,3 +1138,14 @@ cdef extern from "singular/kernel/GBEngine/kstd1.h": cdef extern from "singular/kernel/GBEngine/syz.h": ctypedef struct syStrategy "ssyStrategy": short references + +cdef extern from "singular/polys/ext_fields/transext.h": + ctypedef struct TransExtInfo: + ring * r + ctypedef struct fraction "fractionObject": + poly *numerator + poly *denominator + int complexity + + + diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 63b63070cd2..4c95653d3ed 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -26,7 +26,9 @@ from sage.libs.singular.decl cimport ringorder_dp, ringorder_Dp, ringorder_lp, r from sage.libs.singular.decl cimport p_Copy, prCopyR from sage.libs.singular.decl cimport n_unknown, n_Zp, n_Q, n_R, n_GF, n_long_R, n_algExt,n_transExt,n_long_C, n_Z, n_Zn, n_Znm, n_Z2m, n_CF from sage.libs.singular.decl cimport n_coeffType, cfInitCharProc -from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, nRegister, naInitChar +from sage.libs.singular.decl cimport rDefault, GFInfo, ZnmInfo, nInitChar, AlgExtInfo, nRegister, naInitChar, TransExtInfo + + from sage.rings.integer cimport Integer from sage.rings.integer_ring cimport IntegerRing_class @@ -40,11 +42,19 @@ from sage.rings.polynomial.term_order import TermOrder from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, MPolynomialRing_libsingular from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing +from sage.rings.polynomial.polynomial_ring import PolynomialRing_field + +from sage.rings.fraction_field import FractionField_generic, FractionField_1poly_field + from cpython.object cimport Py_EQ, Py_NE from collections import defaultdict + + + + # mapping str --> SINGULAR representation order_dict = { "dp": ringorder_dp, @@ -143,10 +153,13 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: cdef int ringorder_column_pos cdef int ringorder_column_asc + cdef int ngens + cdef n_coeffType ringtype = n_unknown cdef MPolynomialRing_libsingular k cdef MPolynomial_libsingular minpoly cdef AlgExtInfo extParam + cdef TransExtInfo trextParam cdef n_coeffType _type = n_unknown #cdef cfInitCharProc myfunctionptr; @@ -249,6 +262,31 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: characteristic = 0 _ring = rDefault( characteristic ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + elif isinstance(base_ring, FractionField_generic) and isinstance(base_ring.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base_ring.base().base_ring(), RationalField): + characteristic = 1 + k = PolynomialRing(RationalField(), + names=base_ring.variable_names(), order="lex", implementation="singular") + + ngens = len(k.gens()) + + _ext_names = omAlloc0(ngens*sizeof(char*)) + for i in range(ngens): + _name = str_to_bytes(k._names[i]) + _ext_names[i] = omStrDup(_name) + + _cfr = rDefault( 0, 1, _ext_names ) + + trextParam.r = _cfr + + _cf = nInitChar(n_transExt, &trextParam) + + + if (_cf is NULL): + raise RuntimeError("Failed to allocate _cf ring.") + + _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + + elif isinstance(base_ring, NumberField) and base_ring.is_absolute(): characteristic = 1 k = PolynomialRing(RationalField(), diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index c736d56b0c0..3f9d86812c3 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -31,6 +31,9 @@ from sage.rings.rational_field import RationalField from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic from sage.rings.finite_rings.finite_field_base import FiniteField +from sage.rings.polynomial.polynomial_ring import PolynomialRing_field +from sage.rings.fraction_field import FractionField_generic, FractionField_1poly_field + from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn from sage.rings.finite_rings.finite_field_givaro import FiniteField_givaro from sage.rings.finite_rings.finite_field_ntl_gf2e import FiniteField_ntl_gf2e @@ -40,7 +43,12 @@ from sage.libs.gmp.all cimport * from sage.cpython.string import FS_ENCODING from sage.cpython.string cimport str_to_bytes, char_to_str, bytes_to_str -from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular +from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, MPolynomialRing_libsingular + +cdef extern from "singular/coeffs/coeffs.h": + ctypedef struct coeffs "n_Procs_s" + + _saved_options = (int(0),0,0) @@ -477,6 +485,30 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): return n1 +cdef number *sa2si_transext(object elem, ring *_ring): + + cdef poly *pnumer + cdef poly *pdenom + + cdef fraction *result + + numer = elem.numerator() + pnumer = p_Copy(numer._poly, _ring) + + denom = elem.denominator() + pdenom = p_Copy(denom._poly, _ring) + + nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function + + result = omAlloc0Bin(fractionObjectBin) + + result.numerator = pnumer + result.denominator = pdenom + result.complexity = 1 + + return result + + cdef number *sa2si_NF(object elem, ring *_ring): """ """ @@ -692,6 +724,9 @@ cdef number *sa2si(Element elem, ring * _ring): if _ring.cf.type == n_unknown: return n_Init(int(elem),_ring) return sa2si_ZZmod(elem, _ring) + elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), RationalField): + return sa2si_transext(elem, _ring) + else: raise ValueError("cannot convert to SINGULAR number") From 3de10e6c271db7eefb41ce3447cae99c013c3a9d Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 5 Oct 2021 22:08:33 +0200 Subject: [PATCH 033/378] Hacky solution for sa2si (coefficients that fit in int size only) --- src/sage/libs/singular/ring.pyx | 3 +- src/sage/libs/singular/singular.pyx | 87 +++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 4c95653d3ed..64fceeaff88 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -274,7 +274,8 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _name = str_to_bytes(k._names[i]) _ext_names[i] = omStrDup(_name) - _cfr = rDefault( 0, 1, _ext_names ) + _cfr = rDefault( 0, ngens, _ext_names ) + rComplete(_cfr, 1) trextParam.r = _cfr diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 3f9d86812c3..2bd887646f1 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -487,26 +487,89 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): cdef number *sa2si_transext(object elem, ring *_ring): - cdef poly *pnumer - cdef poly *pdenom + cdef int i + cdef int j + cdef number *n1 + cdef number *n2 + cdef number *a + cdef number *nlCoeff + cdef number *naCoeff + cdef number *apow1 + cdef number *apow2 + cdef number *numerator + cdef number *denominator + cdef number *cfnum + cdef number *cfden + cdef mpz_t mpz_num + cdef mpz_t mpz_den + cdef int ngens + + cdef int ex - cdef fraction *result - numer = elem.numerator() - pnumer = p_Copy(numer._poly, _ring) - denom = elem.denominator() - pdenom = p_Copy(denom._poly, _ring) + cdef nMapFunc nMapFuncPtr = NULL; + + ngens = elem.parent().ngens() nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function - result = omAlloc0Bin(fractionObjectBin) + if (nMapFuncPtr is NULL): + raise RuntimeError("Failed to determine nMapFuncPtr") + + numerdic = elem.numerator().dict() + denomdic = elem.denominator().dict() + + if _ring != currRing: + rChangeCurrRing(_ring) + n1 = _ring.cf.cfInit(0, _ring.cf) - result.numerator = pnumer - result.denominator = pdenom - result.complexity = 1 + apow2 = _ring.cf.cfInit(1, _ring.cf) - return result + + numerator = _ring.cf.cfInit(0, _ring.cf) + + for (exponents, coef) in numerdic.items(): + cfnum = _ring.cf.cfInit((int(coef.numerator())), _ring.cf) + cfden = _ring.cf.cfInit((int(coef.denominator())), _ring.cf) + naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + + + for (j, ex) in enumerate(exponents): + a = _ring.cf.cfParameter(j+1, _ring.cf) + for k in range(ex): + naCoeff = _ring.cf.cfMult(naCoeff, a ,_ring.cf) + numerator = _ring.cf.cfAdd(numerator, naCoeff,_ring.cf) + + if elem.denominator() != 1: + denominator = _ring.cf.cfInit(0, _ring.cf) + + for (exponents, coef) in denomdic.items(): + cfnum = _ring.cf.cfInit((int(coef.numerator())), _ring.cf) + cfden = _ring.cf.cfInit((int(coef.denominator())), _ring.cf) + naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + + for (j, ex) in enumerate(exponents): + a = _ring.cf.cfParameter(j+1, _ring.cf) + for k in range(ex): + naCoeff = _ring.cf.cfMult(naCoeff, a ,_ring.cf) + denominator = _ring.cf.cfAdd(denominator, naCoeff,_ring.cf) + + else: + denominator = _ring.cf.cfInit(1, _ring.cf) + + n1 = _ring.cf.cfDiv(numerator, denominator, _ring.cf) + + _ring.cf.cfDelete(&numerator, _ring.cf) + _ring.cf.cfDelete(&denominator, _ring.cf) + + _ring.cf.cfDelete(&apow2, _ring.cf) + _ring.cf.cfDelete(&naCoeff, _ring.cf) + + + + + return n1 cdef number *sa2si_NF(object elem, ring *_ring): From 2d89757c619b17fe4d090fdd0bb1178fa996cab4 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 5 Oct 2021 22:25:50 +0200 Subject: [PATCH 034/378] Use mpz to create coefficients --- src/sage/libs/singular/decl.pxd | 1 + src/sage/libs/singular/singular.pyx | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 54c3fd36e58..4f387914784 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -127,6 +127,7 @@ cdef extern from "singular/Singular/libsingular.h": number* cfMult(number *, number *, const n_Procs_s* r) # algebraic number multiplication number* (*cfInit)(int i, const n_Procs_s* r ) # algebraic number from int + number* (*cfInitMPZ)(mpz_t i, const n_Procs_s* r) number* (*cfParameter)(int i, const n_Procs_s* r) int (*cfParDeg)(number* n, const n_Procs_s* r) int (*cfSize)(number* n, const n_Procs_s* r) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 2bd887646f1..d066c0a5824 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -500,8 +500,6 @@ cdef number *sa2si_transext(object elem, ring *_ring): cdef number *denominator cdef number *cfnum cdef number *cfden - cdef mpz_t mpz_num - cdef mpz_t mpz_den cdef int ngens cdef int ex @@ -530,8 +528,11 @@ cdef number *sa2si_transext(object elem, ring *_ring): numerator = _ring.cf.cfInit(0, _ring.cf) for (exponents, coef) in numerdic.items(): - cfnum = _ring.cf.cfInit((int(coef.numerator())), _ring.cf) - cfden = _ring.cf.cfInit((int(coef.denominator())), _ring.cf) + numer = coef.numerator() + cfnum = _ring.cf.cfInitMPZ((numer).value, _ring.cf) + denom = coef.denominator() + cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) + naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) @@ -545,8 +546,10 @@ cdef number *sa2si_transext(object elem, ring *_ring): denominator = _ring.cf.cfInit(0, _ring.cf) for (exponents, coef) in denomdic.items(): - cfnum = _ring.cf.cfInit((int(coef.numerator())), _ring.cf) - cfden = _ring.cf.cfInit((int(coef.denominator())), _ring.cf) + numer = coef.numerator() + cfnum = _ring.cf.cfInitMPZ((numer).value, _ring.cf) + denom = coef.denominator() + cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) for (j, ex) in enumerate(exponents): From 64f4f572985875fe5e4a5eeda4409a1f3fb8e6fd Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 6 Oct 2021 17:30:51 +0200 Subject: [PATCH 035/378] Working implementation. Still needs cleanup, documentation, and checking for memory leaks --- src/sage/libs/singular/decl.pxd | 5 +- src/sage/libs/singular/singular.pyx | 105 ++++++++++++++++++++++++++-- 2 files changed, 102 insertions(+), 8 deletions(-) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 4f387914784..935d85b90b3 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -1143,10 +1143,7 @@ cdef extern from "singular/kernel/GBEngine/syz.h": cdef extern from "singular/polys/ext_fields/transext.h": ctypedef struct TransExtInfo: ring * r - ctypedef struct fraction "fractionObject": - poly *numerator - poly *denominator - int complexity + diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index d066c0a5824..8f687b6b6e2 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -45,10 +45,10 @@ from sage.cpython.string cimport str_to_bytes, char_to_str, bytes_to_str from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, MPolynomialRing_libsingular -cdef extern from "singular/coeffs/coeffs.h": - ctypedef struct coeffs "n_Procs_s" - - +ctypedef struct fraction "fractionObject": + poly *numerator + poly *denominator + int complexity _saved_options = (int(0),0,0) @@ -253,6 +253,80 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): z = pNext(z) return ret +cdef object si2sa_transext(number *n, ring *_ring, object base): + """ + TESTS:: + + sage: F = PolynomialRing(QQ,'a,b').fraction_field() + sage: F.inject_variables() + Defining a, b + sage: R. = F[] + sage: a*x + (a)*x + sage: I = R.ideal([a*x]) + sage: I + Ideal ((a)*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field + sage: I.groebner_basis() + [x] + sage: I = R.ideal([a*x+b*y^2, (b+a)/(b-a)*x^3-3*y*x]) + sage: I.groebner_basis() + [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + (a)/(b)*x] + sage: R.term_order() + Degree reverse lexicographic term order + + """ + + cdef poly *numer + cdef poly *denom + cdef number *c + cdef int e + cdef fraction *frac + cdef object snumer + cdef object sdenom + + cdef ring *cfRing = _ring.cf.extRing + + if _ring.cf.cfIsZero(n,_ring.cf): + return base._zero_element + elif _ring.cf.cfIsOne(n,_ring.cf): + return base._one_element + + snumer = base(0) + sdenom = base(0) + + frac = n + + numer = frac.numerator + denom = frac.denominator + + while numer: + c = p_GetCoeff(numer, cfRing) + coeff = si2sa_QQ(c, &c, cfRing) + numer.coef = c + for i in range(base.ngens()): + e = p_GetExp(numer, i+1, cfRing) + if e!= 0: + coeff *= base.gen(i)**e + snumer += coeff + numer = pNext(numer) + + if not denom: + sdenom = base(1) + else: + while denom: + c = p_GetCoeff(denom, cfRing) + coeff = si2sa_QQ(c, &c, cfRing) + denom.coef = c + for i in range(base.ngens()): + e = p_GetExp(denom, i+1, cfRing) + if e!= 0: + coeff *= base.gen(i)**e + sdenom += coeff + denom = pNext(denom) + + return snumer/sdenom + + cdef object si2sa_NF(number *n, ring *_ring, object base): """ TESTS:: @@ -486,6 +560,26 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): return n1 cdef number *sa2si_transext(object elem, ring *_ring): + """ + TESTS:: + + sage: F = PolynomialRing(QQ,'a,b').fraction_field() + sage: F.inject_variables() + Defining a, b + sage: R. = F[] + sage: a*x + (a)*x + sage: I = R.ideal([a*x]) + sage: I + Ideal ((a)*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field + sage: I.groebner_basis() + [x] + sage: I = R.ideal([a*x+b*y^2, (b+a)/(b-a)*x^3-3*y*x]) + sage: I.groebner_basis() + [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + (a)/(b)*x] + sage: R.term_order() + Degree reverse lexicographic term order + """ cdef int i cdef int j @@ -756,6 +850,9 @@ cdef object si2sa(number *n, ring *_ring, object base): elif isinstance(base, NumberField) and base.is_absolute(): return si2sa_NF(n, _ring, base) + elif isinstance(base, FractionField_generic) and isinstance(base.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base.base_ring(), RationalField): + return si2sa_transext(n, _ring, base) + elif isinstance(base, IntegerModRing_generic): if _ring.cf.type == n_unknown: return base(_ring.cf.cfInt(n, _ring.cf)) From 3d3419faf0f3115c7f89e4ce73a2231265ef26ff Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 6 Oct 2021 18:00:13 +0200 Subject: [PATCH 036/378] Fixed case with just one parameter --- src/sage/libs/singular/singular.pyx | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 8f687b6b6e2..c58cfdc577b 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -579,6 +579,21 @@ cdef number *sa2si_transext(object elem, ring *_ring): [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + (a)/(b)*x] sage: R.term_order() Degree reverse lexicographic term order + + :: + + sage: F = PolynomialRing(QQ,'a').fraction_field() + sage: R. = F[] + sage: F.inject_variables() + Defining a + sage: a*x + (a)*x + sage: I = R.ideal([a*x+5*y^2, (1+a)/(1-a)*x^3-3*y*x]) + sage: I + Ideal (5*y^2 + (a)*x, (-a - 1)/(a - 1)*x^3 - 3*x*y) of Multivariate Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring in a over Rational Field + sage: I.groebner_basis() + [x^3 + (3*a - 3)/(a + 1)*x*y, y^2 + (a)/5*x] + """ cdef int i @@ -598,8 +613,6 @@ cdef number *sa2si_transext(object elem, ring *_ring): cdef int ex - - cdef nMapFunc nMapFuncPtr = NULL; ngens = elem.parent().ngens() @@ -612,6 +625,14 @@ cdef number *sa2si_transext(object elem, ring *_ring): numerdic = elem.numerator().dict() denomdic = elem.denominator().dict() + if numerdic and type(list(numerdic)[0]) is not tuple: + numerdic = {(k,):b for k,b in numerdic.items()} + + if denomdic and type(list(denomdic)[0]) is not tuple: + denomdic = {(k,):b for k,b in denomdic.items()} + + + if _ring != currRing: rChangeCurrRing(_ring) n1 = _ring.cf.cfInit(0, _ring.cf) From 136a89a19aa1e476447ea5c88a66e6accb530f77 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 6 Oct 2021 19:17:21 +0200 Subject: [PATCH 037/378] Fix problem with several parameters introduced by previous fix --- src/sage/libs/singular/decl.pxd | 2 -- src/sage/libs/singular/singular.pyx | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sage/libs/singular/decl.pxd b/src/sage/libs/singular/decl.pxd index 935d85b90b3..997cb631dd1 100644 --- a/src/sage/libs/singular/decl.pxd +++ b/src/sage/libs/singular/decl.pxd @@ -402,8 +402,6 @@ cdef extern from "singular/Singular/libsingular.h": cdef omBin *slists_bin - cdef omBin *fractionObjectBin - # integer conversion constant cdef long SR_INT diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index c58cfdc577b..bbfba5039cb 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -27,6 +27,8 @@ import os from libc.stdint cimport int64_t from sage.libs.singular.decl cimport * +from sage.rings.polynomial.polydict import ETuple + from sage.rings.rational_field import RationalField from sage.rings.integer_ring cimport IntegerRing_class from sage.rings.finite_rings.integer_mod_ring import IntegerModRing_generic @@ -625,14 +627,12 @@ cdef number *sa2si_transext(object elem, ring *_ring): numerdic = elem.numerator().dict() denomdic = elem.denominator().dict() - if numerdic and type(list(numerdic)[0]) is not tuple: + if numerdic and not isinstance(list(numerdic)[0], (tuple, ETuple)): numerdic = {(k,):b for k,b in numerdic.items()} - if denomdic and type(list(denomdic)[0]) is not tuple: + if denomdic and not isinstance(list(denomdic)[0], (tuple, ETuple)): denomdic = {(k,):b for k,b in denomdic.items()} - - if _ring != currRing: rChangeCurrRing(_ring) n1 = _ring.cf.cfInit(0, _ring.cf) From 6271a79f532ade95f46c70f0afe48cee1aeb4914 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 6 Oct 2021 23:10:45 +0200 Subject: [PATCH 038/378] Hack in plural.pyx to construct elements from numbers (through the base field) --- src/sage/rings/polynomial/plural.pyx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 349871f5086..0d90a2fbfa3 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -419,7 +419,7 @@ cdef class NCPolynomialRing_plural(Ring): """ singular_ring_delete(self._ring) - def _element_constructor_(self, element): + def _element_constructor_(self, elem): """ Make sure element is a valid member of self, and return the constructed element. @@ -487,11 +487,22 @@ cdef class NCPolynomialRing_plural(Ring): Traceback (most recent call last): ... ValueError: unable to construct an element of this ring + + Check that it works for rings with parameters:: + + sage: F = PolynomialRing(QQ,'t1,t2').fraction_field() + sage: A = FreeAlgebra(F, 2, 'x,y') + sage: A.inject_variables() + Defining x, y + sage: B = A.g_algebra({y*x:-x*y}) + sage: B(2) + 2 + """ - if element == 0: + if elem == 0: return self._zero_element - if element == 1: + if elem == 1: return self._one_element cdef poly *_p @@ -502,6 +513,11 @@ cdef class NCPolynomialRing_plural(Ring): base_ring = self.base_ring() + try: + element = base_ring(elem) + except: + element = elem + if(_ring != currRing): rChangeCurrRing(_ring) if isinstance(element, NCPolynomial_plural): @@ -721,7 +737,7 @@ cdef class NCPolynomialRing_plural(Ring): -x*y """ from sage.repl.rich_output.backend_base import BackendBase - from sage.repl.display.pretty_print import SagePrettyPrinter + from sage.repl.display.pretty_print import SagePrettyPrinter varstr = ", ".join(char_to_str(rRingVar(i, self._ring)) for i in range(self.__ngens)) backend = BackendBase() From 2989430b29afb1e5499a6af3723967092ab4224b Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 6 Oct 2021 23:58:26 +0200 Subject: [PATCH 039/378] Make coercion to base ring in plural less agresive --- src/sage/rings/polynomial/plural.pyx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 0d90a2fbfa3..89d4e47d76b 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -138,6 +138,8 @@ from sage.structure.parent cimport Parent from sage.structure.parent_gens cimport ParentWithGens from sage.rings.polynomial.term_order import TermOrder +from sage.misc.functional import coerce + class G_AlgFactory(UniqueFactory): """ @@ -514,7 +516,7 @@ cdef class NCPolynomialRing_plural(Ring): base_ring = self.base_ring() try: - element = base_ring(elem) + element = coerce(base_ring, elem) except: element = elem From 50ac936b1477128b2676f8ec7b058caf403a78ae Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Fri, 8 Oct 2021 11:47:00 +0200 Subject: [PATCH 040/378] Force tail reduction in NCGroebnerStrategy --- src/sage/libs/singular/groebner_strategy.pyx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/libs/singular/groebner_strategy.pyx b/src/sage/libs/singular/groebner_strategy.pyx index a14df93ad42..1d4f7f0cdd5 100644 --- a/src/sage/libs/singular/groebner_strategy.pyx +++ b/src/sage/libs/singular/groebner_strategy.pyx @@ -372,6 +372,7 @@ cdef class NCGroebnerStrategy(SageObject): self._strat.enterS = enterSBba #- set S self._strat.sl = -1 + self._strat.noTailReduction = False #- init local data struct initS(i, NULL, self._strat) From 7ba8fc561b06207d2c2f377cd3cb1c7f1705583c Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Fri, 8 Oct 2021 11:52:16 +0200 Subject: [PATCH 041/378] Doctest the tail reduction fix --- src/sage/libs/singular/groebner_strategy.pyx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/sage/libs/singular/groebner_strategy.pyx b/src/sage/libs/singular/groebner_strategy.pyx index 1d4f7f0cdd5..20751eafa71 100644 --- a/src/sage/libs/singular/groebner_strategy.pyx +++ b/src/sage/libs/singular/groebner_strategy.pyx @@ -341,6 +341,17 @@ cdef class NCGroebnerStrategy(SageObject): ... TypeError: First parameter must be an ideal in a g-algebra. + Check that tail reduction is applied too:: + + sage: F = PolynomialRing(QQ,'t').fraction_field() + sage: FA = FreeAlgebra(F, 6, 'x1,x2,x3,x4,x5,x6') + sage: N = FA.g_algebra({FA.gen(j)*FA.gen(i):-FA.gen(i)*FA.gen(j) for i in range(5) for j in range(i+1,6)}) + sage: I = N.ideal([g^2 for g in N.gens()],side='twosided') + sage: N.inject_variables() + Defining x1, x2, x3, x4, x5, x6 + sage: I.reduce(x1*x2*x3 + x2^2*x4) + x1*x2*x3 + """ if not isinstance(L, NCPolynomialIdeal): raise TypeError("First parameter must be an ideal in a g-algebra.") From 0ea5dc006fbc1256825546aa2cf4baa989967395 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 26 Aug 2021 12:19:19 -0700 Subject: [PATCH 042/378] set target for dynamic_arch --- build/pkgs/openblas/spkg-install.in | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/build/pkgs/openblas/spkg-install.in b/build/pkgs/openblas/spkg-install.in index b06a55d3130..b72eb06ff84 100644 --- a/build/pkgs/openblas/spkg-install.in +++ b/build/pkgs/openblas/spkg-install.in @@ -14,6 +14,23 @@ fi if [ "x$SAGE_FAT_BINARY" = "xyes" ]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE DYNAMIC_ARCH=1" + machine=$(uname -m) + os=$(uname) + if [[ $os-$machine =~ darwin-x86_64 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=CORE2" + elif [[ $os-$machine =~ darwin-arm64 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=VORTEX" + elif [[ $machine =~ x86_64|amd64 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=PRESCOTT" + elif [[ $machine =~ i386|i486|i586|i686 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=KATMAI" + elif [[ $machine =~ ppc64le ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=POWER8" + elif [[ $machine =~ ppc64 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=POWER6" + elif [[ $machine =~ aarch64 ]]; then + OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=ARMV8" + fi fi echo "Building OpenBLAS: $MAKE $OPENBLAS_CONFIGURE" From 121dda1a3e38b8390db392fcf46039afee29d70f Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Thu, 26 Aug 2021 12:20:57 -0700 Subject: [PATCH 043/378] AVX512 support is now much better --- build/pkgs/openblas/spkg-install.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/build/pkgs/openblas/spkg-install.in b/build/pkgs/openblas/spkg-install.in index b72eb06ff84..31b12d0a462 100644 --- a/build/pkgs/openblas/spkg-install.in +++ b/build/pkgs/openblas/spkg-install.in @@ -38,9 +38,6 @@ echo "Building OpenBLAS: $MAKE $OPENBLAS_CONFIGURE" # Ensure USE_TLS=1 ; see https://trac.sagemath.org/ticket/27256 OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE USE_TLS=1" -# Disable AVX512 for now, see https://trac.sagemath.org/ticket/27961 -OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE NO_AVX512=1" - if ! (sdh_make libs netlib shared $OPENBLAS_CONFIGURE); then if [[ $OPENBLAS_CONFIGURE == *"TARGET"* ]]; then sdh_die "Error building OpenBLAS" From d48c8ab7ad10bee813bfc168ce30044517dad0ac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 26 Aug 2021 13:03:43 -0700 Subject: [PATCH 044/378] build/pkgs/openblas: Update to 0.3.17 --- build/pkgs/openblas/checksums.ini | 6 +++--- build/pkgs/openblas/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/openblas/checksums.ini b/build/pkgs/openblas/checksums.ini index 36ae2621198..ee5d356f31b 100644 --- a/build/pkgs/openblas/checksums.ini +++ b/build/pkgs/openblas/checksums.ini @@ -1,5 +1,5 @@ tarball=openblas-VERSION.tar.gz -sha1=685537a821819ef4dae5901998a57f0eec5bddad -md5=2ca05b9cee97f0d1a8ab15bd6ea2b747 -cksum=2414941668 +sha1=0de2c8a2feb12183cce6222f1e963f7e254a23a2 +md5=5429954163bcbaccaa13e11fe30ca5b6 +cksum=2917470732 upstream_url=https://github.com/xianyi/OpenBLAS/archive/vVERSION.tar.gz diff --git a/build/pkgs/openblas/package-version.txt b/build/pkgs/openblas/package-version.txt index e4737652ca5..e5a9958c328 100644 --- a/build/pkgs/openblas/package-version.txt +++ b/build/pkgs/openblas/package-version.txt @@ -1 +1 @@ -0.3.13 +0.3.17 From d49adc02338fcb25e240ae9d310614ce5a929326 Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Wed, 1 Sep 2021 13:55:24 -0700 Subject: [PATCH 045/378] use compiler triplet --- build/pkgs/openblas/spkg-install.in | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/build/pkgs/openblas/spkg-install.in b/build/pkgs/openblas/spkg-install.in index 31b12d0a462..f6ac7753838 100644 --- a/build/pkgs/openblas/spkg-install.in +++ b/build/pkgs/openblas/spkg-install.in @@ -14,21 +14,20 @@ fi if [ "x$SAGE_FAT_BINARY" = "xyes" ]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE DYNAMIC_ARCH=1" - machine=$(uname -m) - os=$(uname) - if [[ $os-$machine =~ darwin-x86_64 ]]; then + machine=$($CC -dumpmachine) + if [[ $machine =~ x86_64-apple-darwin* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=CORE2" - elif [[ $os-$machine =~ darwin-arm64 ]]; then + elif [[ $os-$machine =~ arm64-apple-darwin* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=VORTEX" - elif [[ $machine =~ x86_64|amd64 ]]; then + elif [[ $machine =~ (x86_64|amd64)-* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=PRESCOTT" - elif [[ $machine =~ i386|i486|i586|i686 ]]; then + elif [[ $machine =~ (i386|i486|i586|i686)-* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=KATMAI" - elif [[ $machine =~ ppc64le ]]; then + elif [[ $machine =~ (ppc64le|powerpc64le)-* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=POWER8" - elif [[ $machine =~ ppc64 ]]; then + elif [[ $machine =~ ppc64-* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=POWER6" - elif [[ $machine =~ aarch64 ]]; then + elif [[ $machine =~ aarch64-* ]]; then OPENBLAS_CONFIGURE="$OPENBLAS_CONFIGURE TARGET=ARMV8" fi fi From 5d6f68b7edd2ed151dce45f4df0b7413b61efb00 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Fri, 8 Oct 2021 14:23:10 +0100 Subject: [PATCH 046/378] version bump --- build/pkgs/openblas/checksums.ini | 6 +++--- build/pkgs/openblas/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/openblas/checksums.ini b/build/pkgs/openblas/checksums.ini index ee5d356f31b..2c76f1e8471 100644 --- a/build/pkgs/openblas/checksums.ini +++ b/build/pkgs/openblas/checksums.ini @@ -1,5 +1,5 @@ tarball=openblas-VERSION.tar.gz -sha1=0de2c8a2feb12183cce6222f1e963f7e254a23a2 -md5=5429954163bcbaccaa13e11fe30ca5b6 -cksum=2917470732 +sha1=a9d5ce86908657f002c6566cd8f35fe882709be4 +md5=5cd5df5a1541ad414f5874aaae17730f +cksum=2075619020 upstream_url=https://github.com/xianyi/OpenBLAS/archive/vVERSION.tar.gz diff --git a/build/pkgs/openblas/package-version.txt b/build/pkgs/openblas/package-version.txt index e5a9958c328..8355eafc6fe 100644 --- a/build/pkgs/openblas/package-version.txt +++ b/build/pkgs/openblas/package-version.txt @@ -1 +1 @@ -0.3.17 +0.3.18 From 74189813946b263856cacb88e0e8386a79be473e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 13:51:33 -0700 Subject: [PATCH 047/378] src/sage/interfaces/polymake.py: Mark more doctests # optional - polymake_expect --- src/sage/interfaces/polymake.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/interfaces/polymake.py b/src/sage/interfaces/polymake.py index 06092472a17..5b61ab70ab5 100644 --- a/src/sage/interfaces/polymake.py +++ b/src/sage/interfaces/polymake.py @@ -2131,7 +2131,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if If polymake raises an error, the polymake *interface* raises a :class:`PolymakeError`:: - sage: polymake.eval('FOOBAR(3);') # optional - polymake + sage: polymake.eval('FOOBAR(3);') # optional - polymake_expect Traceback (most recent call last): ... PolymakeError: Undefined subroutine &Polymake::User::FOOBAR called... @@ -2139,17 +2139,17 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if If a command is incomplete, then polymake returns a continuation prompt. In that case, we raise an error:: - sage: polymake.eval('print 3') # optional - polymake + sage: polymake.eval('print 3') # optional - polymake_expect Traceback (most recent call last): ... SyntaxError: Incomplete polymake command 'print 3' - sage: polymake.eval('print 3;') # optional - polymake + sage: polymake.eval('print 3;') # optional - polymake_expect '3' However, if the command contains line breaks but eventually is complete, no error is raised:: - sage: print(polymake.eval('$tmp="abc";\nprint $tmp;')) # optional - polymake + sage: print(polymake.eval('$tmp="abc";\nprint $tmp;')) # optional - polymake_expect abc When requesting help, polymake sometimes expect the user to choose @@ -2157,7 +2157,7 @@ def _eval_line(self, line, allow_use_file=True, wait_for_prompt=True, restart_if the list from which the user can choose; we could demonstrate this using the :meth:`help` method, but here we use an explicit code evaluation:: - sage: print(polymake.eval('help "TRIANGULATION";')) # optional - polymake # random + sage: print(polymake.eval('help "TRIANGULATION";')) # optional - polymake_expect # random doctest:warning ... UserWarning: Polymake expects user interaction. We abort and return From 83a98bec74e09f0965341feb65c12f2bc74304f1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 14:05:26 -0700 Subject: [PATCH 048/378] src/sage/features/polymake.py: New --- src/sage/features/polymake.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/sage/features/polymake.py diff --git a/src/sage/features/polymake.py b/src/sage/features/polymake.py new file mode 100644 index 00000000000..1e6d7b81b99 --- /dev/null +++ b/src/sage/features/polymake.py @@ -0,0 +1,25 @@ +from . import PythonModule +from .join_feature import JoinFeature + + +class JuPyMake(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of the ``JuPyMake`` + module, a Python interface to the polymake library. + + EXAMPLES:: + + sage: from sage.features.polymake import JuPyMake + sage: JuPyMake().is_present() # optional: jupymake + FeatureTestResult('jupymake', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.polymake import JuPyMake + sage: isinstance(JuPyMake(), JuPyMake) + True + """ + JoinFeature.__init__(self, "jupymake", + [PythonModule("JuPyMake", spkg="jupymake")]) From d2cbfe7e0f79782c4ebb51a2daf9a0b3a97cb2af Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 14:20:06 -0700 Subject: [PATCH 049/378] build/pkgs/polymake/distros/homebrew.txt: New --- build/pkgs/polymake/distros/homebrew.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/polymake/distros/homebrew.txt diff --git a/build/pkgs/polymake/distros/homebrew.txt b/build/pkgs/polymake/distros/homebrew.txt new file mode 100644 index 00000000000..69a7629040a --- /dev/null +++ b/build/pkgs/polymake/distros/homebrew.txt @@ -0,0 +1 @@ +apaffenholz/polymake/polymake From 328dcc7b4333fa20ba30cddce8349bd21e6a8638 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Fri, 8 Oct 2021 23:23:06 +0200 Subject: [PATCH 050/378] Make sure we are in the correct libsingular ring when creating the object --- src/sage/libs/singular/singular.pyx | 3 +++ src/sage/rings/polynomial/plural.pyx | 10 +++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index bbfba5039cb..084592507f6 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -617,6 +617,9 @@ cdef number *sa2si_transext(object elem, ring *_ring): cdef nMapFunc nMapFuncPtr = NULL; + if _ring != currRing: + rChangeCurrRing(_ring) + ngens = elem.parent().ngens() nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 89d4e47d76b..80c905c0cef 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -421,7 +421,7 @@ cdef class NCPolynomialRing_plural(Ring): """ singular_ring_delete(self._ring) - def _element_constructor_(self, elem): + def _element_constructor_(self, element): """ Make sure element is a valid member of self, and return the constructed element. @@ -502,9 +502,9 @@ cdef class NCPolynomialRing_plural(Ring): """ - if elem == 0: + if element == 0: return self._zero_element - if elem == 1: + if element == 1: return self._one_element cdef poly *_p @@ -516,9 +516,9 @@ cdef class NCPolynomialRing_plural(Ring): base_ring = self.base_ring() try: - element = coerce(base_ring, elem) + element = coerce(base_ring, element) except: - element = elem + pass if(_ring != currRing): rChangeCurrRing(_ring) From 57d9d7d60208d83ebb949e32c3c39e019d0a4f4d Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sat, 9 Oct 2021 00:01:26 +0200 Subject: [PATCH 051/378] Cleanup variables --- src/sage/libs/singular/singular.pyx | 31 +++++++++++------------------ 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 084592507f6..810597e40d6 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -596,25 +596,28 @@ cdef number *sa2si_transext(object elem, ring *_ring): sage: I.groebner_basis() [x^3 + (3*a - 3)/(a + 1)*x*y, y^2 + (a)/5*x] + :: + + sage: F = PolynomialRing(QQ,'a,b').fraction_field() + sage: R. = PolynomialRing(F) + sage: S. = QQ[] + sage: f = x + y + 1 + sage: R(f) + x + y + 1 + """ cdef int i cdef int j cdef number *n1 - cdef number *n2 cdef number *a - cdef number *nlCoeff cdef number *naCoeff - cdef number *apow1 - cdef number *apow2 cdef number *numerator cdef number *denominator cdef number *cfnum cdef number *cfden cdef int ngens - cdef int ex - cdef nMapFunc nMapFuncPtr = NULL; if _ring != currRing: @@ -639,21 +642,13 @@ cdef number *sa2si_transext(object elem, ring *_ring): if _ring != currRing: rChangeCurrRing(_ring) n1 = _ring.cf.cfInit(0, _ring.cf) - - apow2 = _ring.cf.cfInit(1, _ring.cf) - - numerator = _ring.cf.cfInit(0, _ring.cf) - for (exponents, coef) in numerdic.items(): numer = coef.numerator() cfnum = _ring.cf.cfInitMPZ((numer).value, _ring.cf) denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) - naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) - - for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): @@ -683,12 +678,10 @@ cdef number *sa2si_transext(object elem, ring *_ring): _ring.cf.cfDelete(&numerator, _ring.cf) _ring.cf.cfDelete(&denominator, _ring.cf) - - _ring.cf.cfDelete(&apow2, _ring.cf) + _ring.cf.cfDelete(&cfnum, _ring.cf) + _ring.cf.cfDelete(&cfden, _ring.cf) _ring.cf.cfDelete(&naCoeff, _ring.cf) - - - + _ring.cf.cfDelete(&a, _ring.cf) return n1 From f1f362d207b2b72ae37c199133abd4b094b3e222 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 17:21:49 -0700 Subject: [PATCH 052/378] build/pkgs/polymake/spkg-configure.m4: Actually use POLYMAKE_VERSION_MIN --- build/pkgs/polymake/spkg-configure.m4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/pkgs/polymake/spkg-configure.m4 b/build/pkgs/polymake/spkg-configure.m4 index 3f631403dbe..2d142c701a0 100644 --- a/build/pkgs/polymake/spkg-configure.m4 +++ b/build/pkgs/polymake/spkg-configure.m4 @@ -5,7 +5,7 @@ SAGE_SPKG_CONFIGURE([polymake], [ AC_PATH_PROGS_FEATURE_CHECK([POLYMAKE_CONFIG], [polymake-config], [ polymake_config_version=$($ac_path_POLYMAKE_CONFIG --version 2>&1) AS_IF([test -n "$polymake_config_version"], [ - AX_COMPARE_VERSION([$polymake_config_version], [ge], [1.7.2], [ + AX_COMPARE_VERSION([$polymake_config_version], [ge], POLYMAKE_VERSION_MIN, [ ac_cv_path_POLYMAKE_CONFIG="$ac_path_POLYMAKE_CONFIG" ]) ]) @@ -15,4 +15,5 @@ SAGE_SPKG_CONFIGURE([polymake], [ [sage_spkg_install_polymake=yes], [sage_require_perl_cpan_polymake_prereq=no sage_require_perl_term_readline_gnu=no]) + m4_popdef([POLYMAKE_VERSION_MIN]) ]) From c6b5f8cf5cabe3beb7da6edab5d2faf95425c6a0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 17:48:26 -0700 Subject: [PATCH 053/378] build/pkgs/polymake/spkg-configure.m4: Link and run a test program with libpolymake --- build/pkgs/polymake/spkg-configure.m4 | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/build/pkgs/polymake/spkg-configure.m4 b/build/pkgs/polymake/spkg-configure.m4 index 2d142c701a0..e081356478d 100644 --- a/build/pkgs/polymake/spkg-configure.m4 +++ b/build/pkgs/polymake/spkg-configure.m4 @@ -13,7 +13,31 @@ SAGE_SPKG_CONFIGURE([polymake], [ ]) AS_IF([test -z "$ac_cv_path_POLYMAKE_CONFIG"], [sage_spkg_install_polymake=yes], - [sage_require_perl_cpan_polymake_prereq=no - sage_require_perl_term_readline_gnu=no]) + [AC_MSG_CHECKING([whether libpolymake works]) + AC_LANG_PUSH([C++]) + saved_CXX="$CXX" + saved_CPPFLAGS="$CPPFLAGS" + saved_LDFLAGS="$LDFLAGS" + CXX="$($ac_cv_path_POLYMAKE_CONFIG --cc)" + CPPFLAGS="$($ac_cv_path_POLYMAKE_CONFIG --includes) $($ac_cv_path_POLYMAKE_CONFIG --cflags) $CPPFLAGS" + LDFLAGS="-lpolymake $($ac_cv_path_POLYMAKE_CONFIG --ldflags) $LDFLAGS" + AC_RUN_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + polymake::Main* main_polymake_session = new polymake::Main; + ]] + )], [ + AC_MSG_RESULT([yes]) + sage_require_perl_cpan_polymake_prereq=no + sage_require_perl_term_readline_gnu=no + ], [ + AC_MSG_RESULT([no]) + sage_spkg_install_polymake=yes + ]) + CXX="$saved_CXX" + CPPFLAGS="$saved_CPPFLAGS" + LDFLAGS="$saved_LDFLAGS" + AC_LANG_POP([C++]) + ]) m4_popdef([POLYMAKE_VERSION_MIN]) ]) From d9fc03e7c039d697247220fd527ec7d2bbf8f588 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 18:10:01 -0700 Subject: [PATCH 054/378] build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt: perl-TermReadKey, not perl-Term-ReadKey --- build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt b/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt index c7390e63993..da97cd97866 100644 --- a/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt +++ b/build/pkgs/perl_cpan_polymake_prereq/distros/fedora.txt @@ -2,7 +2,7 @@ perl-ExtUtils-Embed perl-File-Slurp perl-JSON perl-Term-ReadLine-Gnu -perl-Term-ReadKey +perl-TermReadKey perl-XML-Writer perl-XML-LibXML perl-XML-LibXSLT From 777d1b8d20aa23c69faa7f7da7cb31c7c8078aa1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 8 Oct 2021 19:45:33 -0700 Subject: [PATCH 055/378] build/pkgs/polymake/distros/nix.txt: New --- build/pkgs/polymake/distros/nix.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/polymake/distros/nix.txt diff --git a/build/pkgs/polymake/distros/nix.txt b/build/pkgs/polymake/distros/nix.txt new file mode 100644 index 00000000000..2a9cc70b2f5 --- /dev/null +++ b/build/pkgs/polymake/distros/nix.txt @@ -0,0 +1 @@ +polymake From e57f349e21bd48b00caa7cd18d5cfd96545f833e Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sat, 9 Oct 2021 21:45:08 +0200 Subject: [PATCH 056/378] Make sure we free memory during coefficient creation --- src/sage/libs/singular/singular.pyx | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 810597e40d6..48073b73353 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -616,6 +616,8 @@ cdef number *sa2si_transext(object elem, ring *_ring): cdef number *denominator cdef number *cfnum cdef number *cfden + cdef number *aux1 + cdef number *aux2 cdef int ngens cdef int ex cdef nMapFunc nMapFuncPtr = NULL; @@ -652,8 +654,13 @@ cdef number *sa2si_transext(object elem, ring *_ring): for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): - naCoeff = _ring.cf.cfMult(naCoeff, a ,_ring.cf) - numerator = _ring.cf.cfAdd(numerator, naCoeff,_ring.cf) + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfDelete(&a, _ring.cf) + aux2 = numerator + numerator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) + _ring.cf.cfDelete(&aux2, _ring.cf) if elem.denominator() != 1: denominator = _ring.cf.cfInit(0, _ring.cf) @@ -664,12 +671,16 @@ cdef number *sa2si_transext(object elem, ring *_ring): denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) - for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): - naCoeff = _ring.cf.cfMult(naCoeff, a ,_ring.cf) - denominator = _ring.cf.cfAdd(denominator, naCoeff,_ring.cf) + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfDelete(&a, _ring.cf) + aux2 = denominator + denominator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) + _ring.cf.cfDelete(&aux2, _ring.cf) else: denominator = _ring.cf.cfInit(1, _ring.cf) From d2e4ff7722ff5a33240ea51928156b4980d62149 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 10 Oct 2021 11:24:42 +0200 Subject: [PATCH 057/378] Make sure single variables are represented consistently, and fix doctests broken because of the change in representation --- .../non_symmetric_macdonald_polynomials.py | 28 ++-- src/sage/combinat/sf/ns_macdonald.py | 12 +- src/sage/combinat/species/product_species.py | 2 +- .../combinat/species/recursive_species.py | 2 +- src/sage/combinat/species/species.py | 2 +- src/sage/combinat/species/sum_species.py | 4 +- ...otics_multivariate_generating_functions.py | 4 +- src/sage/rings/fraction_field.py | 4 +- src/sage/rings/invariants/invariant_theory.py | 6 +- .../multi_polynomial_libsingular.pyx | 8 +- src/sage/rings/polynomial/polydict.pyx | 4 +- .../rings/polynomial/polynomial_element.pyx | 3 +- src/sage/schemes/plane_conics/con_field.py | 6 +- .../schemes/projective/projective_morphism.py | 2 +- .../projective/projective_subscheme.py | 2 +- src/sage/schemes/toric/fano_variety.py | 122 +++++++++--------- 16 files changed, 110 insertions(+), 101 deletions(-) diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index f1dc9f608b4..5d406c1dd44 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -91,11 +91,11 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: E = NonSymmetricMacdonaldPolynomials(["A",2,1], q=q, q1=t, q2=-1) sage: vars = K['x0,x1,x2'].gens() sage: E[L0([2,0,1])].expand(vars) - ((-t + 1)/(-q*t + 1))*x0^2*x1 + x0^2*x2 + ((-q*t + q)/(-q*t + 1))*x0*x1*x2 + (t - 1)/(q*t - 1)*x0^2*x1 + x0^2*x2 + (q*t - q)/(q*t - 1)*x0*x1*x2 sage: from sage.combinat.sf.ns_macdonald import E sage: E([2,0,1]) - ((-t + 1)/(-q*t + 1))*x0^2*x1 + x0^2*x2 + ((-q*t + q)/(-q*t + 1))*x0*x1*x2 + (t - 1)/(q*t - 1)*x0^2*x1 + x0^2*x2 + (q*t - q)/(q*t - 1)*x0*x1*x2 Here is a type `G_2^{(1)}` nonsymmetric Macdonald polynomial:: @@ -431,14 +431,14 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: NS.E([1,0]) x0 sage: EE([0,1]) - ((-t + 1)/(-q*t + 1))*x0 + x1 + (t - 1)/(q*t - 1)*x0 + x1 sage: NS.E([0,1]) - ((-t + 1)/(-q*t + 1))*x0 + x1 + (t - 1)/(q*t - 1)*x0 + x1 sage: NS.E([2,0]) - x0^2 + ((-q*t + q)/(-q*t + 1))*x0*x1 + x0^2 + (q*t - q)/(q*t - 1)*x0*x1 sage: EE([2,0]) - x0^2 + ((-q*t + q)/(-q*t + 1))*x0*x1 + x0^2 + (q*t - q)/(q*t - 1)*x0*x1 The same, directly in the ambient lattice with several shifts:: @@ -948,20 +948,20 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: EE([1,0,0]) x1 sage: EE([0,1,0]) - ((-t + 1)/(-q*t^2 + 1))*x1 + x2 + (t - 1)/(q*t^2 - 1)*x1 + x2 sage: EE([0,0,1]) - ((-t + 1)/(-q*t + 1))*x1 + ((-t + 1)/(-q*t + 1))*x2 + x3 + (t - 1)/(q*t - 1)*x1 + (t - 1)/(q*t - 1)*x2 + x3 sage: EE([1,1,0]) x1*x2 sage: EE([1,0,1]) - ((-t + 1)/(-q*t^2 + 1))*x1*x2 + x1*x3 + (t - 1)/(q*t^2 - 1)*x1*x2 + x1*x3 sage: EE([0,1,1]) - ((-t + 1)/(-q*t + 1))*x1*x2 + ((-t + 1)/(-q*t + 1))*x1*x3 + x2*x3 + (t - 1)/(q*t - 1)*x1*x2 + (t - 1)/(q*t - 1)*x1*x3 + x2*x3 sage: EE([2,0,0]) - x1^2 + ((-q*t + q)/(-q*t + 1))*x1*x2 + ((-q*t + q)/(-q*t + 1))*x1*x3 + x1^2 + (q*t - q)/(q*t - 1)*x1*x2 + (q*t - q)/(q*t - 1)*x1*x3 sage: EE([0,2,0]) - ((-t + 1)/(-q^2*t^2 + 1))*x1^2 + ((-q^2*t^3 + q^2*t^2 - q*t^2 + 2*q*t - q + t - 1)/(-q^3*t^3 + q^2*t^2 + q*t - 1))*x1*x2 + x2^2 + ((q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1))*x1*x3 + ((-q*t + q)/(-q*t + 1))*x2*x3 + (t - 1)/(q^2*t^2 - 1)*x1^2 + (q^2*t^3 - q^2*t^2 + q*t^2 - 2*q*t + q - t + 1)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x1*x2 + x2^2 + (q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x1*x3 + (q*t - q)/(q*t - 1)*x2*x3 Systematic checks with Sage's implementation of [HHL06]_:: @@ -1781,9 +1781,9 @@ def symmetric_macdonald_polynomial(self, mu): sage: P = SymmetricFunctions(K).macdonald().P() sage: g = P[2,1].expand(3); g - x0^2*x1 + x0*x1^2 + x0^2*x2 + ((-2*q*t^2 + q*t - t^2 + q - t + 2)/(-q*t^2 + 1))*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x0^2*x1 + x0*x1^2 + x0^2*x2 + (2*q*t^2 - q*t - q + t^2 + t - 2)/(q*t^2 - 1)*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 sage: fe = f.expand(g.parent().gens()); fe - x0^2*x1 + x0*x1^2 + x0^2*x2 + ((2*q*v^4 + v^4 - q*v^2 + v^2 - q - 2)/(q*v^4 - 1))*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 + x0^2*x1 + x0*x1^2 + x0^2*x2 + (2*q*v^4 - q*v^2 - q + v^4 + v^2 - 2)/(q*v^4 - 1)*x0*x1*x2 + x1^2*x2 + x0*x2^2 + x1*x2^2 sage: g.map_coefficients(lambda x: x.subs(t=v*v)) == fe True diff --git a/src/sage/combinat/sf/ns_macdonald.py b/src/sage/combinat/sf/ns_macdonald.py index 7ac278837c8..2ca5a957fd1 100644 --- a/src/sage/combinat/sf/ns_macdonald.py +++ b/src/sage/combinat/sf/ns_macdonald.py @@ -863,19 +863,19 @@ def E(mu, q=None, t=None, pi=None): sage: E([1,0,0]) x0 sage: E([0,1,0]) - ((-t + 1)/(-q*t^2 + 1))*x0 + x1 + (t - 1)/(q*t^2 - 1)*x0 + x1 sage: E([0,0,1]) - ((-t + 1)/(-q*t + 1))*x0 + ((-t + 1)/(-q*t + 1))*x1 + x2 + (t - 1)/(q*t - 1)*x0 + (t - 1)/(q*t - 1)*x1 + x2 sage: E([1,1,0]) x0*x1 sage: E([1,0,1]) - ((-t + 1)/(-q*t^2 + 1))*x0*x1 + x0*x2 + (t - 1)/(q*t^2 - 1)*x0*x1 + x0*x2 sage: E([0,1,1]) - ((-t + 1)/(-q*t + 1))*x0*x1 + ((-t + 1)/(-q*t + 1))*x0*x2 + x1*x2 + (t - 1)/(q*t - 1)*x0*x1 + (t - 1)/(q*t - 1)*x0*x2 + x1*x2 sage: E([2,0,0]) - x0^2 + ((-q*t + q)/(-q*t + 1))*x0*x1 + ((-q*t + q)/(-q*t + 1))*x0*x2 + x0^2 + (q*t - q)/(q*t - 1)*x0*x1 + (q*t - q)/(q*t - 1)*x0*x2 sage: E([0,2,0]) - ((-t + 1)/(-q^2*t^2 + 1))*x0^2 + ((-q^2*t^3 + q^2*t^2 - q*t^2 + 2*q*t - q + t - 1)/(-q^3*t^3 + q^2*t^2 + q*t - 1))*x0*x1 + x1^2 + ((q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1))*x0*x2 + ((-q*t + q)/(-q*t + 1))*x1*x2 + (t - 1)/(q^2*t^2 - 1)*x0^2 + (q^2*t^3 - q^2*t^2 + q*t^2 - 2*q*t + q - t + 1)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x0*x1 + x1^2 + (q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x0*x2 + (q*t - q)/(q*t - 1)*x1*x2 """ P, q, t, n, R, x = _check_muqt(mu, q, t, pi) res = 0 diff --git a/src/sage/combinat/species/product_species.py b/src/sage/combinat/species/product_species.py index 4bbee606925..5295e3a87c9 100644 --- a/src/sage/combinat/species/product_species.py +++ b/src/sage/combinat/species/product_species.py @@ -409,7 +409,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X * X sage: S.algebraic_equation_system() - [node0 - z^2] + [node0 + (-z^2)] """ from sage.misc.all import prod return prod(var_mapping[operand] for operand in self._state_info) diff --git a/src/sage/combinat/species/recursive_species.py b/src/sage/combinat/species/recursive_species.py index 7af1a0dee36..5bbc93d014d 100644 --- a/src/sage/combinat/species/recursive_species.py +++ b/src/sage/combinat/species/recursive_species.py @@ -467,7 +467,7 @@ def _equation(self, var_mapping): sage: B = species.BinaryTreeSpecies() sage: B.algebraic_equation_system() - [-node3^2 + node1, -node1 + node3 - z] + [-node3^2 + node1, -node1 + node3 + (-z)] """ try: return var_mapping[self._reference] diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index aa5e29356d2..06efe0ab329 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -769,7 +769,7 @@ def algebraic_equation_system(self): sage: B = species.BinaryTreeSpecies() sage: B.algebraic_equation_system() - [-node3^2 + node1, -node1 + node3 - z] + [-node3^2 + node1, -node1 + node3 + (-z)] :: diff --git a/src/sage/combinat/species/sum_species.py b/src/sage/combinat/species/sum_species.py index a7f0a616fdc..9168ffa76bc 100644 --- a/src/sage/combinat/species/sum_species.py +++ b/src/sage/combinat/species/sum_species.py @@ -84,7 +84,7 @@ def right_summand(self): sage: F = P + P*P sage: F.right_summand() Product of (Permutation species) and (Permutation species) - """ + """ return self._G def _name(self): @@ -214,7 +214,7 @@ def _equation(self, var_mapping): sage: X = species.SingletonSpecies() sage: S = X + X sage: S.algebraic_equation_system() - [node1 - 2*z] + [node1 + (-2*z)] """ return sum(var_mapping[operand] for operand in self._state_info) diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index 06301c7633c..b37e597e214 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -2725,7 +2725,7 @@ def smooth_critical_ideal(self, alpha): sage: F = FFPD(G, Hfac) sage: alpha = var('a1, a2') sage: F.smooth_critical_ideal(alpha) - Ideal (y^2 + 2*a1/a2*y - 1, x + ((-a2)/a1)*y + (-a1 + a2)/a1) of + Ideal (y^2 + (2*a1)/(a2)*y - 1, x + (-a2)/(a1)*y + (-a1 + a2)/(a1)) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a1, a2 over Rational Field @@ -2735,7 +2735,7 @@ def smooth_critical_ideal(self, alpha): sage: F = FFPD(G, Hfac) sage: alpha = [7/3, var('a')] sage: F.smooth_critical_ideal(alpha) - Ideal (y^2 + 14/3/a*y - 1, x + (-3/7*a)*y + 3/7*a - 1) of Multivariate Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring in a over Rational Field + Ideal (y^2 + 14/(3*a)*y - 1, x + (-3*a)/7*y + (3*a - 7)/7) of Multivariate Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring in a over Rational Field """ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index c5b5c55a785..27e6277ad1b 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -586,7 +586,7 @@ def _element_constructor_(self, x, y=None, coerce=True): sage: B. = PolynomialRing(A,'d,e') sage: R. = PolynomialRing(B,'x') sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1) - a*d + 16*c^4*e + 16*a*c^4 + 16*c^4 + (a)*d + (16*c^4)*e + (16*a*c^4 + 16*c^4) Check that :trac:`24539` is fixed:: @@ -618,6 +618,8 @@ def _element_constructor_(self, x, y=None, coerce=True): sage: F(x) -1/2/(a^2 + a) """ + if isinstance(x, (list, tuple)) and len(x) == 1: + x = x[0] if y is None: if parent(x) is self: return x diff --git a/src/sage/rings/invariants/invariant_theory.py b/src/sage/rings/invariants/invariant_theory.py index 059a774025b..245bfdbee11 100644 --- a/src/sage/rings/invariants/invariant_theory.py +++ b/src/sage/rings/invariants/invariant_theory.py @@ -256,9 +256,9 @@ def transvectant(f, g, h=1, scale='default'): sage: S. = R[] sage: quintic = invariant_theory.binary_quintic(x^5+x^3+2*x^2+y^5, x) sage: transvectant(quintic, quintic, 2) - Binary sextic given by 1/5*x^6 + 6/5*x^5*h + (-3/25)*x^4*h^2 - + (2*y^5 - 8/25)*x^3*h^3 + (-12/25)*x^2*h^4 + 3/5*y^5*x*h^5 - + 2/5*y^5*h^6 + Binary sextic given by 1/5*x^6 + 6/5*x^5*h - 3/25*x^4*h^2 + + (50*y^5 - 8)/25*x^3*h^3 - 12/25*x^2*h^4 + (3*y^5)/5*x*h^5 + + (2*y^5)/5*h^6 """ f = f.homogenized() g = g.homogenized() diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index ec706f3129d..655987381fb 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -251,6 +251,8 @@ from sage.interfaces.macaulay2 import macaulay2 as macaulay2_default, is_Macaula from sage.misc.all import prod as mul from sage.misc.sage_eval import sage_eval +import re + cimport cypari2.gen from . import polynomial_element @@ -559,7 +561,7 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: k. = GF(2^8) sage: P. = PolynomialRing(k,2) sage: P._coerce_(a) - (a) + a sage: z = QQ['z'].0 sage: K. = NumberField(z^2 - 2) @@ -2481,6 +2483,10 @@ cdef class MPolynomial_libsingular(MPolynomial): """ cdef ring *_ring = self._parent_ring s = singular_polynomial_str(self._poly, _ring) + regexp = re.compile(r'\([a-zA-Z][a-zA-Z0-9]*\)') + res = regexp.fullmatch(s) + if res: + return s[1:-1] return s cpdef _repr_short_(self): diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index 98b663a029d..651d4041272 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -1624,11 +1624,11 @@ cdef class ETuple: sage: R. = Frac(QQ['x'])[] sage: type(y) - + sage: y^(2^32) Traceback (most recent call last): ... - OverflowError: exponent overflow (2147483648) + OverflowError: exponent overflow (...) """ if self._length!=other._length: raise ArithmeticError diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index dabc030c828..6d1d6c7f626 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -6508,7 +6508,8 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: p = ((1/b^2*d^2+1/a)*x*y^2+a*b/c*y+e+x^2) sage: q = -4*c^2*y^3+1 sage: p.resultant(q) - 16*c^4*x^6 + 48*c^4*e*x^4 + (1/b^6*d^6 + 3/(a*b^4)*d^4 + ((-12*a^3*b*c + 3)/(a^2*b^2))*d^2 + (-12*a^3*b*c + 1)/a^3)*x^3 + 48*c^4*e^2*x^2 + (((-12*a*c)/b)*d^2*e + (-12*b*c)*e)*x + 16*c^4*e^3 + 4*a^3*b^3/c + (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + (48*c^4)*e^2*x^2 + ((-12*a*c)/(b)*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/(c) + Test for :trac:`10978`:: diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index 04ee419f880..929ff0dccb6 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -683,10 +683,10 @@ def hom(self, x, Y=None): sage: T = Matrix([[t,0,1],[0,1,0],[0,0,1]]) sage: C.hom(T, D) Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by x^2 + t*y^2 + 1/t*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by 1/t^2*x^2 + t*y^2 + (-2/t^2)*x*z + ((t + 1)/t^2)*z^2 + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by x^2 + (t)*y^2 + 1/(t)*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by 1/(t^2)*x^2 + (t)*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - (t*x + z : y : z) + ((t)*x + z : y : z) """ if is_Matrix(x): diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index adbffd9008e..056eb076b28 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -1114,7 +1114,7 @@ def dehomogenize(self, n): Scheme endomorphism of Affine Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: Defined on coordinates by sending (x, y) to - (1/t*x^2 + y^2, y^2 - 1/t) + (1/(t)*x^2 + y^2, y^2 - 1/(t)) :: diff --git a/src/sage/schemes/projective/projective_subscheme.py b/src/sage/schemes/projective/projective_subscheme.py index 8b91a17accf..609dd9bafac 100644 --- a/src/sage/schemes/projective/projective_subscheme.py +++ b/src/sage/schemes/projective/projective_subscheme.py @@ -663,7 +663,7 @@ def _forward_image(self, f, check = True): sage: f([t^2*y-z]) Closed subscheme of Projective Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by: - y + (-1/t^2)*z + y - 1/(t^2)*z :: diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index 20b15e3fc66..579fd4821f2 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -57,10 +57,10 @@ ....: monomial_points="all") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 - + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 - + a4*z1^2*z2 + a5*z0*z2^2 - + a3*z1*z2^2 + a2*z2^3 + (a0)*z0^3 + (a9)*z0^2*z1 + (a7)*z0*z1^2 + + (a1)*z1^3 + (a8)*z0^2*z2 + (a6)*z0*z1*z2 + + (a4)*z1^2*z2 + (a5)*z0*z2^2 + + (a3)*z1*z2^2 + (a2)*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: @@ -69,7 +69,7 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 + (a0)*z0^3 + (a1)*z1^3 + (a6)*z0*z1*z2 + (a2)*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of ``Delta_polar``:: @@ -80,10 +80,10 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: - a2*z2^3*z3^2*z4*z5^2*z8 - + a1*z1^3*z3*z4^2*z7^2*z9 - + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + a0*z0^3*z5*z7*z8^2*z9^2 + (a2)*z2^3*z3^2*z4*z5^2*z8 + + (a1)*z1^3*z3*z4^2*z7^2*z9 + + (a3)*z0*z1*z2*z3*z4*z5*z7*z8*z9 + + (a0)*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities @@ -96,7 +96,7 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 + (a0)*z0^3 + (a1)*z1^3 + (a3)*z0*z1*z2 + (a2)*z2^3 This looks very similar to our second version of the anticanonical hypersurface of the projective plane, as expected, since all @@ -110,8 +110,8 @@ sage: FTV.anticanonical_hypersurface() Closed subscheme of 3-d CPR-Fano toric variety covered by 4 affine patches defined by: - a0*z2^12 + a4*z2^6*z3^6 + a3*z3^12 - + a8*z0*z1*z2*z3 + a2*z1^3 + a1*z0^2 + (a0)*z2^12 + (a4)*z2^6*z3^6 + (a3)*z3^12 + + (a8)*z0*z1*z2*z3 + (a2)*z1^3 + (a1)*z0^2 Below you will find detailed descriptions of available functions. Current functionality of this module is very basic, but it is under active @@ -806,10 +806,10 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="all") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 - + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 - + a4*z1^2*z2 + a5*z0*z2^2 - + a3*z1*z2^2 + a2*z2^3 + (a0)*z0^3 + (a9)*z0^2*z1 + (a7)*z0*z1^2 + + (a1)*z1^3 + (a8)*z0^2*z2 + (a6)*z0*z1*z2 + + (a4)*z1^2*z2 + (a5)*z0*z2^2 + + (a3)*z1*z2^2 + (a2)*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: @@ -818,7 +818,7 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 + (a0)*z0^3 + (a1)*z1^3 + (a6)*z0*z1*z2 + (a2)*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of @@ -830,10 +830,10 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: - a2*z2^3*z3^2*z4*z5^2*z8 - + a1*z1^3*z3*z4^2*z7^2*z9 - + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + a0*z0^3*z5*z7*z8^2*z9^2 + (a2)*z2^3*z3^2*z4*z5^2*z8 + + (a1)*z1^3*z3*z4^2*z7^2*z9 + + (a3)*z0*z1*z2*z3*z4*z5*z7*z8*z9 + + (a0)*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities @@ -846,7 +846,7 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 + (a0)*z0^3 + (a1)*z1^3 + (a3)*z0*z1*z2 + (a2)*z2^3 This looks very similar to our second anticanonical hypersurface of the projective plane, as expected, since all @@ -860,7 +860,7 @@ def anticanonical_hypersurface(self, **kwds): ....: coefficient_names="a b c d") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - a*z0^3 + b*z1^3 + d*z0*z1*z2 + c*z2^3 + (a)*z0^3 + (b)*z1^3 + (d)*z0*z1*z2 + (c)*z2^3 or give concrete coefficients :: @@ -877,7 +877,7 @@ def anticanonical_hypersurface(self, **kwds): sage: H Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - t*z1^3 + (psi/(psi^2 + phi))*z0*z1*z2 + 1/t*z2^3 + (t)*z1^3 + (psi)/(phi + psi^2)*z0*z1*z2 + 1/(t)*z2^3 sage: R = H.ambient_space().base_ring() sage: R Fraction Field of @@ -1124,21 +1124,21 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 - + a3*z2*z3*z4*z7*z8 + a1*z0*z2, - b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 - + b5*z1*z3*z4*z5*z6*z7*z8 + b2*z2*z3*z6^2*z8^3 - + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 + (a0)*z1*z4^2*z5^2*z7^3 + (a2)*z2*z4*z5*z6*z7^2*z8^2 + + (a3)*z2*z3*z4*z7*z8 + (a1)*z0*z2, + (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2 + (b0)*z2*z5*z6^3*z7*z8^4 + + (b5)*z1*z3*z4*z5*z6*z7*z8 + (b2)*z2*z3*z6^2*z8^3 + + (b1)*z1*z3^2*z4 + (b4)*z0*z1*z5*z6 Now we include only monomials associated to vertices of `\Delta_i`:: sage: X.nef_complete_intersection(np, monomial_points="vertices") Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 - + a3*z2*z3*z4*z7*z8 + a1*z0*z2, - b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 - + b2*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 + (a0)*z1*z4^2*z5^2*z7^3 + (a2)*z2*z4*z5*z6*z7^2*z8^2 + + (a3)*z2*z3*z4*z7*z8 + (a1)*z0*z2, + (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2 + (b0)*z2*z5*z6^3*z7*z8^4 + + (b2)*z2*z3*z6^2*z8^3 + (b1)*z1*z3^2*z4 + (b4)*z0*z1*z5*z6 (effectively, we set ``b5=0``). Next we provide coefficients explicitly instead of using default generic names:: @@ -1148,8 +1148,8 @@ def nef_complete_intersection(self, nef_partition, **kwds): ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))]) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - a*z1*z4^2*z5^2*z7^3 + a/e*z2*z4*z5*z6*z7^2*z8^2 - + c_i*z2*z3*z4*z7*z8 + a^2*z0*z2, + (a)*z1*z4^2*z5^2*z7^3 + (a)/(e)*z2*z4*z5*z6*z7^2*z8^2 + + (c_i)*z2*z3*z4*z7*z8 + (a^2)*z0*z2, 4*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4 + 3*z2*z3*z6^2*z8^3 + 2*z1*z3^2*z4 + 5*z0*z1*z5*z6 @@ -1161,14 +1161,14 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 22 affine patches defined by: - a2*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 - + a0*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 - + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a1*z0*z2, - b0*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2 - + b3*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 - + b2*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 - + b5*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 - + b1*z1*z3^2*z4*z11*z12 + b4*z0*z1*z5*z6*z13 + (a2)*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 + + (a0)*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 + + (a3)*z2*z3*z4*z7*z8*z9*z10*z11*z12 + (a1)*z0*z2, + (b0)*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2 + + (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 + + (b2)*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 + + (b5)*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 + + (b1)*z1*z3^2*z4*z11*z12 + (b4)*z0*z1*z5*z6*z13 """ return NefCompleteIntersection(self, nef_partition, **kwds) @@ -1356,7 +1356,7 @@ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric): sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 + (a0)*s^2*x^2 + (a3)*t^2*x^2 + (a6)*s*t*x*y + (a1)*s^2*y^2 + (a2)*t^2*y^2 See :meth:`~CPRFanoToricVariety_field.anticanonical_hypersurface()` for a more elaborate example. @@ -1374,7 +1374,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 + (a0)*s^2*x^2 + (a3)*t^2*x^2 + (a6)*s*t*x*y + (a1)*s^2*y^2 + (a2)*t^2*y^2 Check that finite fields are handled correctly :trac:`14899`:: @@ -1473,10 +1473,10 @@ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 + + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, + (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 + + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for a more elaborate example. @@ -1499,10 +1499,10 @@ def __init__(self, P_Delta, nef_partition, sage: NefCompleteIntersection(X, np) Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 + + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, + (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 + + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 """ if not is_CPRFanoToricVariety(P_Delta): raise TypeError("nef complete intersections can only be " @@ -1597,10 +1597,10 @@ def cohomology_class(self): sage: CI Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 + + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, + (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 + + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 sage: CI.cohomology_class() [2*z3*z4 + 4*z3*z5 + 2*z4*z5] """ @@ -1630,10 +1630,10 @@ def nef_partition(self): sage: CI Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 - + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, - b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 - + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 + (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 + + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, + (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 + + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 sage: CI.nef_partition() Nef-partition {0, 1, 3} U {2, 4, 5} sage: CI.nef_partition() is np From 58f528c55f996ccebf47dca3c8d7935476cb56d1 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 10 Oct 2021 20:57:29 +0200 Subject: [PATCH 058/378] Clean unnecessary parenthesis in single variables. --- src/sage/arith/misc.py | 2 +- src/sage/crypto/mq/rijndael_gf.py | 22 ++-- .../arithmetic_dynamics/generic_ds.py | 2 +- .../arithmetic_dynamics/projective_ds.py | 4 +- .../groups/matrix_gps/finitely_generated.py | 2 +- src/sage/libs/singular/polynomial.pyx | 3 + src/sage/libs/singular/singular.pyx | 18 +-- src/sage/quadratic_forms/quadratic_form.py | 2 +- ...otics_multivariate_generating_functions.py | 2 +- src/sage/rings/finite_rings/residue_field.pyx | 2 +- src/sage/rings/fraction_field.py | 2 +- .../rings/multi_power_series_ring_element.py | 2 +- src/sage/rings/polynomial/flatten.py | 2 +- .../multi_polynomial_libsingular.pyx | 13 +- src/sage/rings/polynomial/plural.pyx | 2 +- .../rings/polynomial/polynomial_element.pyx | 2 +- src/sage/schemes/affine/affine_morphism.py | 6 +- src/sage/schemes/curves/affine_curve.py | 2 +- src/sage/schemes/curves/closed_point.py | 14 +- src/sage/schemes/curves/projective_curve.py | 4 +- .../elliptic_curves/ell_curve_isogeny.py | 4 +- src/sage/schemes/generic/algebraic_scheme.py | 2 +- src/sage/schemes/plane_conics/con_field.py | 10 +- .../schemes/plane_conics/con_finite_field.py | 2 +- .../schemes/projective/projective_morphism.py | 10 +- src/sage/schemes/toric/fano_variety.py | 120 +++++++++--------- src/sage/structure/coerce.pyx | 2 +- .../mpoly_doctest.py | 2 +- 28 files changed, 129 insertions(+), 131 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 039e786aff7..ed918732ba7 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -1933,7 +1933,7 @@ def xgcd(a, b): sage: xgcd(y^2, a*y+b) (1, a^2/b^2, ((-a)/b^2)*y + 1/b) sage: xgcd((b+g)*y^2, (a+g)*y+b) - (1, (a^2 + (2*g)*a + 3)/(b^3 + (g)*b^2), ((-a + (-g))/b^2)*y + 1/b) + (1, (a^2 + (2*g)*a + 3)/(b^3 + g*b^2), ((-a + (-g))/b^2)*y + 1/b) Here is an example of a xgcd for two polynomials over the integers, where the linear combination is not the gcd but the gcd multiplied by the resultant:: diff --git a/src/sage/crypto/mq/rijndael_gf.py b/src/sage/crypto/mq/rijndael_gf.py index eb6119bafe0..619026bfe96 100644 --- a/src/sage/crypto/mq/rijndael_gf.py +++ b/src/sage/crypto/mq/rijndael_gf.py @@ -119,7 +119,7 @@ sage: mc_pc = rgf.mix_columns_poly_constr() sage: mc_pc(1, 2) - a02 + (x)*a12 + (x + 1)*a22 + a32 + a02 + x*a12 + (x + 1)*a22 + a32 sage: mc_pc(2, 3, algorithm='decrypt') (x^3 + x^2 + 1)*a03 + (x^3 + 1)*a13 + (x^3 + x^2 + x)*a23 + (x^3 + x + 1)*a33 @@ -274,7 +274,7 @@ sage: rcpc A polynomial constructor of a round component of Rijndael-GF block cipher with block length 4, key length 6, and 12 rounds. sage: rcpc(2, 1) - a01 + a12 + (x)*a23 + (x + 1)*a30 + a01 + a12 + x*a23 + (x + 1)*a30 sage: state = rgf._hex_to_GF('afb73eeb1cd1b85162280f27fb20d585') sage: result = rgf.apply_poly(state, rcpc) @@ -303,7 +303,7 @@ sage: poly = rgf.mix_columns_poly_constr()(0, 3) sage: poly - (x)*a03 + (x + 1)*a13 + a23 + a33 + x*a03 + (x + 1)*a13 + a23 + a33 sage: rgf.compose(rgf.sub_bytes_poly_constr(), poly) (x^3 + x)*a03^254 + (x^3 + x^2 + x + 1)*a13^254 + @@ -325,7 +325,7 @@ (x^2 + x + 1)*a13^239 + (x^7 + x^6 + x^5 + x^4 + x^2)*a23^239 + (x^7 + x^6 + x^5 + x^4 + x^2)*a33^239 + - (x)*a03^223 + + x*a03^223 + (x + 1)*a13^223 + a23^223 + a33^223 + @@ -462,7 +462,7 @@ def __init__(self, Nb, Nk, state_chr='a', key_chr='k'): sage: rgf = RijndaelGF(4, 6, state_chr='myChr') sage: rgf.mix_columns_poly_constr()(3, 2) - (x + 1)*myChr02 + myChr12 + myChr22 + (x)*myChr32 + (x + 1)*myChr02 + myChr12 + myChr22 + x*myChr32 We can also alter the name of variables in polynomials representing elements from round keys by changing ``key_chr``. :: @@ -1483,10 +1483,10 @@ def compose(self, f, g, algorithm='encrypt', f_attr=None, g_attr=None): sage: from sage.crypto.mq.rijndael_gf import RijndaelGF sage: rgf = RijndaelGF(4, 4) sage: mcp = rgf.mix_columns_poly_constr()(1, 3); mcp - a03 + (x)*a13 + (x + 1)*a23 + a33 + a03 + x*a13 + (x + 1)*a23 + a33 sage: result = rgf.compose(rgf.shift_rows_poly_constr(), mcp) sage: result - a03 + (x)*a10 + (x + 1)*a21 + a32 + a03 + x*a10 + (x + 1)*a21 + a32 We can test the correctness of this:: @@ -1503,7 +1503,7 @@ def compose(self, f, g, algorithm='encrypt', f_attr=None, g_attr=None): sage: fn = rgf.compose(rgf.shift_rows_poly_constr(), ....: rgf.mix_columns_poly_constr()) sage: fn(1, 3) - a03 + (x)*a10 + (x + 1)*a21 + a32 + a03 + x*a10 + (x + 1)*a21 + a32 If we use ``compose`` to make a new ``Round_Component_Poly_Constr`` object, we can use that object as input to ``apply_poly`` and @@ -1958,7 +1958,7 @@ def mix_columns_poly_constr(self): sage: mc_pc A polynomial constructor for the function 'Mix Columns' of Rijndael-GF block cipher with block length 4, key length 4, and 10 rounds. sage: mc_pc(1, 2) - a02 + (x)*a12 + (x + 1)*a22 + a32 + a02 + x*a12 + (x + 1)*a22 + a32 sage: mc_pc(1, 0, algorithm='decrypt') (x^3 + 1)*a00 + (x^3 + x^2 + x)*a10 + (x^3 + x + 1)*a20 + (x^3 + x^2 + 1)*a30 @@ -1994,7 +1994,7 @@ def _mix_columns_pc(self, row, col, algorithm='encrypt'): sage: from sage.crypto.mq.rijndael_gf import RijndaelGF sage: rgf = RijndaelGF(4, 4) sage: rgf._mix_columns_pc(3, 1) - (x + 1)*a01 + a11 + a21 + (x)*a31 + (x + 1)*a01 + a11 + a21 + x*a31 We can use this to calculate individual entries of a state matrix after the decryption version of MixColumns has been applied to it as such:: @@ -2197,7 +2197,7 @@ def __init__(self, polynomial_constr, rgf, round_component_name=None): sage: rcpc = RijndaelGF.Round_Component_Poly_Constr( ....: rgf._mix_columns_pc, rgf, "Mix Columns") sage: poly = rcpc(1, 2); poly - a02 + (x)*a12 + (x + 1)*a22 + a32 + a02 + x*a12 + (x + 1)*a22 + a32 sage: state = rgf._hex_to_GF('d1876c0f79c4300ab45594add66ff41f') sage: result = rgf.mix_columns(state) sage: result[1,2] == poly(state.list()) diff --git a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py index 0ad4d747f94..6a80a88ed0b 100644 --- a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py @@ -142,7 +142,7 @@ class DynamicalSystem(SchemeMorphism_polynomial, sage: DynamicalSystem([GF(5)(3)*x^2, K(t)*y^2]) Dynamical System of Projective Space of dimension 1 over Finite Field in t of size 5^2 Defn: Defined on coordinates by sending (x : y) to - (-2*x^2 : (t)*y^2) + (-2*x^2 : t*y^2) """ @staticmethod diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 164c4c35f47..5fba51056f0 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -499,7 +499,7 @@ def _number_field_from_algebraics(self): sage: f._number_field_from_algebraics() Dynamical System of Projective Space of dimension 1 over Number Field in a with defining polynomial y^2 - 2 with a = 1.414213562373095? Defn: Defined on coordinates by sending (x : y) to - (x^2 + (a)*y^2 : y^2) + (x^2 + a*y^2 : y^2) """ return self.as_scheme_morphism()._number_field_from_algebraics().as_dynamical_system() @@ -5251,7 +5251,7 @@ def reduced_form(self, **kwds): ( Dynamical System of Projective Space of dimension 1 over Number Field in w with defining polynomial x^2 - 2 with w = 1.414213562373095? Defn: Defined on coordinates by sending (x : y) to - (x^3 : (w)*y^3) , + (x^3 : w*y^3) , [ 1 -12] [ 0 1] diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index a69e5bfd325..45f86f6fe9b 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -1152,7 +1152,7 @@ def reynolds_operator(self, poly, chi=None): sage: R. = K[] sage: f = -K.gen()*x sage: G.reynolds_operator(f) - (t)*x + (t)*y + t*x + t*y """ if poly.parent().ngens() != self.degree(): raise TypeError("number of variables in polynomial must match size of matrices") diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index 7687de8f2d8..eed1967ca9e 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -23,6 +23,8 @@ cdef extern from *: # hack to get at cython macro import re plusminus_pattern = re.compile("([^\(^])([\+\-])") +parenthvar_pattern = re.compile(r"\(([a-zA-Z][a-zA-Z0-9]*)\)") + from sage.cpython.string cimport bytes_to_str, str_to_bytes @@ -441,6 +443,7 @@ cdef object singular_polynomial_str(poly *p, ring *r): s = bytes_to_str(p_String(p, r, r)) s = plusminus_pattern.sub("\\1 \\2 ", s) + s = parenthvar_pattern.sub("\\1", s) return s diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 48073b73353..b576c7e9719 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -264,15 +264,15 @@ cdef object si2sa_transext(number *n, ring *_ring, object base): Defining a, b sage: R. = F[] sage: a*x - (a)*x + a*x sage: I = R.ideal([a*x]) sage: I - Ideal ((a)*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field + Ideal (a*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field sage: I.groebner_basis() [x] sage: I = R.ideal([a*x+b*y^2, (b+a)/(b-a)*x^3-3*y*x]) sage: I.groebner_basis() - [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + (a)/(b)*x] + [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + a/b*x] sage: R.term_order() Degree reverse lexicographic term order @@ -570,15 +570,15 @@ cdef number *sa2si_transext(object elem, ring *_ring): Defining a, b sage: R. = F[] sage: a*x - (a)*x + a*x sage: I = R.ideal([a*x]) sage: I - Ideal ((a)*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field + Ideal (a*x) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field sage: I.groebner_basis() [x] sage: I = R.ideal([a*x+b*y^2, (b+a)/(b-a)*x^3-3*y*x]) sage: I.groebner_basis() - [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + (a)/(b)*x] + [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + a/b*x] sage: R.term_order() Degree reverse lexicographic term order @@ -589,12 +589,12 @@ cdef number *sa2si_transext(object elem, ring *_ring): sage: F.inject_variables() Defining a sage: a*x - (a)*x + a*x sage: I = R.ideal([a*x+5*y^2, (1+a)/(1-a)*x^3-3*y*x]) sage: I - Ideal (5*y^2 + (a)*x, (-a - 1)/(a - 1)*x^3 - 3*x*y) of Multivariate Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring in a over Rational Field + Ideal (5*y^2 + a*x, (-a - 1)/(a - 1)*x^3 - 3*x*y) of Multivariate Polynomial Ring in x, y over Fraction Field of Univariate Polynomial Ring in a over Rational Field sage: I.groebner_basis() - [x^3 + (3*a - 3)/(a + 1)*x*y, y^2 + (a)/5*x] + [x^3 + (3*a - 3)/(a + 1)*x*y, y^2 + a/5*x] :: diff --git a/src/sage/quadratic_forms/quadratic_form.py b/src/sage/quadratic_forms/quadratic_form.py index e53203c66d9..02df1fe76ba 100644 --- a/src/sage/quadratic_forms/quadratic_form.py +++ b/src/sage/quadratic_forms/quadratic_form.py @@ -1288,7 +1288,7 @@ def polynomial(self,names='x'): 2*a*y0^2 + 3*a*y0*y1 + (-a + 1)*y1^2 + (2*a + 4)*y2^2 sage: Q = QuadraticForm(F,4,[a, 3*a, 0, 1 - a, a - 3, 0, 2*a + 4, 4 + a, 0, 1]) sage: Q.polynomial(names='z') - (a)*z0^2 + (3*a)*z0*z1 + (a - 3)*z1^2 + (a + 4)*z2^2 + (-a + 1)*z0*z3 + (2*a + 4)*z1*z3 + z3^2 + a*z0^2 + (3*a)*z0*z1 + (a - 3)*z1^2 + (a + 4)*z2^2 + (-a + 1)*z0*z3 + (2*a + 4)*z1*z3 + z3^2 sage: B. = QuaternionAlgebra(F,-1,-1) sage: Q = QuadraticForm(B, 3, [2*a, 3*a, i, 1 - a, 0, 2*a + 4]) sage: Q.polynomial() diff --git a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py index b37e597e214..3f43a3197aa 100644 --- a/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +++ b/src/sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py @@ -2725,7 +2725,7 @@ def smooth_critical_ideal(self, alpha): sage: F = FFPD(G, Hfac) sage: alpha = var('a1, a2') sage: F.smooth_critical_ideal(alpha) - Ideal (y^2 + (2*a1)/(a2)*y - 1, x + (-a2)/(a1)*y + (-a1 + a2)/(a1)) of + Ideal (y^2 + (2*a1)/a2*y - 1, x + (-a2)/a1*y + (-a1 + a2)/a1) of Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in a1, a2 over Rational Field diff --git a/src/sage/rings/finite_rings/residue_field.pyx b/src/sage/rings/finite_rings/residue_field.pyx index 007a68e4c0f..09de1cb3c0f 100644 --- a/src/sage/rings/finite_rings/residue_field.pyx +++ b/src/sage/rings/finite_rings/residue_field.pyx @@ -109,7 +109,7 @@ First over a small non-prime field:: sage: R. = PolynomialRing(Rf) sage: ubar = Rf(u) sage: I = ideal([ubar*X + Y]); I - Ideal ((ubar)*X + Y) of Multivariate Polynomial Ring in X, Y over Residue field in ubar of Fractional ideal (47, 517/55860*u^5 + 235/3724*u^4 + 9829/13965*u^3 + 54106/13965*u^2 + 64517/27930*u + 755696/13965) + Ideal (ubar*X + Y) of Multivariate Polynomial Ring in X, Y over Residue field in ubar of Fractional ideal (47, 517/55860*u^5 + 235/3724*u^4 + 9829/13965*u^3 + 54106/13965*u^2 + 64517/27930*u + 755696/13965) sage: I.groebner_basis() [X + (-19*ubar^2 - 5*ubar - 17)*Y] diff --git a/src/sage/rings/fraction_field.py b/src/sage/rings/fraction_field.py index 27e6277ad1b..acf1ffa8f60 100644 --- a/src/sage/rings/fraction_field.py +++ b/src/sage/rings/fraction_field.py @@ -586,7 +586,7 @@ def _element_constructor_(self, x, y=None, coerce=True): sage: B. = PolynomialRing(A,'d,e') sage: R. = PolynomialRing(B,'x') sage: (a*d*x^2+a+e+1).resultant(-4*c^2*x+1) - (a)*d + (16*c^4)*e + (16*a*c^4 + 16*c^4) + a*d + (16*c^4)*e + (16*a*c^4 + 16*c^4) Check that :trac:`24539` is fixed:: diff --git a/src/sage/rings/multi_power_series_ring_element.py b/src/sage/rings/multi_power_series_ring_element.py index 782a6f077a3..4d85381b9df 100644 --- a/src/sage/rings/multi_power_series_ring_element.py +++ b/src/sage/rings/multi_power_series_ring_element.py @@ -462,7 +462,7 @@ def __call__(self, *x, **kwds): sage: cc = K.hom([-i]) sage: R. = PowerSeriesRing(K) sage: f = s^2 + i*s*t + (3+4*i)*s^3 + R.O(4); f - s^2 + (i)*s*t + (4*i + 3)*s^3 + O(s, t)^4 + s^2 + i*s*t + (4*i + 3)*s^3 + O(s, t)^4 sage: f(t, s, base_map=cc) (-i)*s*t + t^2 + (-4*i + 3)*t^3 + O(s, t)^4 """ diff --git a/src/sage/rings/polynomial/flatten.py b/src/sage/rings/polynomial/flatten.py index b7dadef0b51..4ffe29f9ebe 100644 --- a/src/sage/rings/polynomial/flatten.py +++ b/src/sage/rings/polynomial/flatten.py @@ -113,7 +113,7 @@ def __init__(self, domain): sage: from sage.rings.polynomial.flatten import FlatteningMorphism sage: f = FlatteningMorphism(R) sage: f(R('v*a*x^2 + b^2 + 1/v*y')) - (v)*x^2*a + b^2 + (1/2*v^2)*y + v*x^2*a + b^2 + (1/2*v^2)*y :: diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index 655987381fb..591e72c88c7 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -251,7 +251,6 @@ from sage.interfaces.macaulay2 import macaulay2 as macaulay2_default, is_Macaula from sage.misc.all import prod as mul from sage.misc.sage_eval import sage_eval -import re cimport cypari2.gen from . import polynomial_element @@ -1967,7 +1966,7 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: F. = GF(7^2) sage: R. = F[] sage: p = a*x^2 + y + a^3; p - (a)*x^2 + y + (-2*a - 3) + a*x^2 + y + (-2*a - 3) sage: q = copy(p) sage: p == q True @@ -2483,10 +2482,6 @@ cdef class MPolynomial_libsingular(MPolynomial): """ cdef ring *_ring = self._parent_ring s = singular_polynomial_str(self._poly, _ring) - regexp = re.compile(r'\([a-zA-Z][a-zA-Z0-9]*\)') - res = regexp.fullmatch(s) - if res: - return s[1:-1] return s cpdef _repr_short_(self): @@ -4233,10 +4228,10 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: K. = NumberField(p^3-2) sage: KXY. = K[] sage: factor(x^3 - 2*y^3) - (x + (-s)*y) * (x^2 + (s)*x*y + (s^2)*y^2) + (x + (-s)*y) * (x^2 + s*x*y + (s^2)*y^2) sage: k = (x^3-2*y^3)^5*(x+s*y)^2*(2/3 + s^2) sage: k.factor() - ((s^2 + 2/3)) * (x + (s)*y)^2 * (x + (-s)*y)^5 * (x^2 + (s)*x*y + (s^2)*y^2)^5 + ((s^2 + 2/3)) * (x + s*y)^2 * (x + (-s)*y)^5 * (x^2 + s*x*y + (s^2)*y^2)^5 This shows that ticket :trac:`2780` is fixed, i.e. that the unit part of the factorization is set correctly:: @@ -4327,7 +4322,7 @@ cdef class MPolynomial_libsingular(MPolynomial): sage: q=y^11 + (a)*y^10 + (a + 1)*x*y^3 sage: f = p*q sage: f.factor() - x * y^3 * (y^8 + (a)*y^7 + (a + 1)*x) * (x^7*y^3 + x*y^9 + (a)*x^8 + (a)*y^4) + x * y^3 * (y^8 + a*y^7 + (a + 1)*x) * (x^7*y^3 + x*y^9 + a*x^8 + a*y^4) We test several examples which were known to return wrong results in the past (see :trac:`10902`):: diff --git a/src/sage/rings/polynomial/plural.pyx b/src/sage/rings/polynomial/plural.pyx index 80c905c0cef..972d22049da 100644 --- a/src/sage/rings/polynomial/plural.pyx +++ b/src/sage/rings/polynomial/plural.pyx @@ -2272,7 +2272,7 @@ cdef class NCPolynomial_plural(RingElement): sage: phi(x*y - x^2*z) a^2*b^3 - a^2*b^2*c sage: phi(x*y - z2*x^2*z) - (z2)*a^2*b^3 - a^2*b^2*c + z2*a^2*b^3 - a^2*b^2*c sage: phi = R.hom([a*b, b, a*b*c], base_map=GF(9).frobenius_endomorphism(), check=False) sage: phi(x*y - x^2*z) a^2*b^3 - a^2*b^2*c diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 6d1d6c7f626..4ce01469a99 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -6508,7 +6508,7 @@ cdef class Polynomial(CommutativeAlgebraElement): sage: p = ((1/b^2*d^2+1/a)*x*y^2+a*b/c*y+e+x^2) sage: q = -4*c^2*y^3+1 sage: p.resultant(q) - (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + (48*c^4)*e^2*x^2 + ((-12*a*c)/(b)*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/(c) + (16*c^4)*x^6 + (48*c^4)*e*x^4 + (1/(b^6)*d^6 + 3/(a*b^4)*d^4 + (-12*a^3*b*c + 3)/(a^2*b^2)*d^2 + (-12*a^3*b*c + 1)/(a^3))*x^3 + (48*c^4)*e^2*x^2 + ((-12*a*c)/b*d^2*e + (-12*b*c)*e)*x + (16*c^4)*e^3 + (4*a^3*b^3)/c Test for :trac:`10978`:: diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index 63a4f348af9..fa9e7ed51d3 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -950,7 +950,7 @@ def reduce_base_field(self): From: Affine Space of dimension 2 over Finite Field in t of size 5^4 To: Affine Space of dimension 1 over Finite Field in t of size 5^4 Defn: Defined on coordinates by sending (a, b) to - (a^2 + (t)*b) + (a^2 + t*b) :: @@ -961,7 +961,7 @@ def reduce_base_field(self): sage: g = f.reduce_base_field();g Scheme endomorphism of Affine Space of dimension 1 over Cyclotomic Field of order 4 and degree 2 Defn: Defined on coordinates by sending (x) to - (x^2 + (v)) + (x^2 + v) sage: g.base_ring() is K True @@ -1005,7 +1005,7 @@ def reduce_base_field(self): To: Affine Space of dimension 2 over Number Field in a with defining polynomial x^3 - x + 1 with a = -1.324717957244746? Defn: Defined on coordinates by sending (x) to - (x^2 + (a)*x + 3, 5*x) + (x^2 + a*x + 3, 5*x) :: diff --git a/src/sage/schemes/curves/affine_curve.py b/src/sage/schemes/curves/affine_curve.py index 9fd99a3b3fc..52fa2cb4419 100644 --- a/src/sage/schemes/curves/affine_curve.py +++ b/src/sage/schemes/curves/affine_curve.py @@ -2404,7 +2404,7 @@ def places_on(self, point): Point (x + (a + 1), y + (-a + 1)), Point (x - 1, y + (a + 1)), Point (x - 1, y + (-a - 1)), - Point (x + (-a - 1), y + (a)), + Point (x + (-a - 1), y + a), Point (x + (-a - 1), y + (-a)), Point (x + 1, y + 1), Point (x + 1, y - 1)] diff --git a/src/sage/schemes/curves/closed_point.py b/src/sage/schemes/curves/closed_point.py index 718b8a20c76..d35ad60b35e 100644 --- a/src/sage/schemes/curves/closed_point.py +++ b/src/sage/schemes/curves/closed_point.py @@ -105,11 +105,11 @@ class IntegralCurveClosedPoint(CurveClosedPoint): sage: C.closed_points() [Point (x, y), Point (x, y + 1), - Point (x + (a), y + (a)), - Point (x + (a), y + (a + 1)), - Point (x + (a + 1), y + (a)), + Point (x + a, y + a), + Point (x + a, y + (a + 1)), + Point (x + (a + 1), y + a), Point (x + (a + 1), y + (a + 1)), - Point (x + 1, y + (a)), + Point (x + 1, y + a), Point (x + 1, y + (a + 1))] """ def __init__(self, curve, prime_ideal, degree): @@ -269,7 +269,7 @@ def rational_point(self): Point (x + (z2 + 1), y + (-z2 + 1)), Point (x - 1, y + (z2 + 1)), Point (x - 1, y + (-z2 - 1)), - Point (x + (-z2 - 1), y + (z2)), + Point (x + (-z2 - 1), y + z2), Point (x + (-z2 - 1), y + (-z2)), Point (x + 1, y + 1), Point (x + 1, y - 1)] @@ -356,8 +356,8 @@ def rational_point(self): [Point (x, z), Point (x, y), Point (y, z), - Point (x + (a)*z, y + (a + 1)*z), - Point (x + (a + 1)*z, y + (a)*z)] + Point (x + a*z, y + (a + 1)*z), + Point (x + (a + 1)*z, y + a*z)] sage: [p.rational_point() for p in _] [(0 : 1 : 0), (0 : 0 : 1), (1 : 0 : 0), (a : a + 1 : 1), (a + 1 : a : 1)] sage: set(_) == set(C.rational_points()) diff --git a/src/sage/schemes/curves/projective_curve.py b/src/sage/schemes/curves/projective_curve.py index 0e6ba6a1e4b..8433f27ddbf 100644 --- a/src/sage/schemes/curves/projective_curve.py +++ b/src/sage/schemes/curves/projective_curve.py @@ -2628,11 +2628,11 @@ def closed_points(self, degree=1): [Point (x0, x1), Point (x0 + (-z2 - 1)*x2, x1), Point (x0 + (z2 + 1)*x2, x1), - Point (x0 + (z2)*x2, x1 + (z2 - 1)*x2), + Point (x0 + z2*x2, x1 + (z2 - 1)*x2), Point (x0 + (-z2)*x2, x1 + (-z2 + 1)*x2), Point (x0 + (-z2 - 1)*x2, x1 + (-z2 - 1)*x2), Point (x0 + (z2 + 1)*x2, x1 + (z2 + 1)*x2), - Point (x0 + (z2 - 1)*x2, x1 + (z2)*x2), + Point (x0 + (z2 - 1)*x2, x1 + z2*x2), Point (x0 + (-z2 + 1)*x2, x1 + (-z2)*x2), Point (x0 + x2, x1 - x2), Point (x0 - x2, x1 + x2)] diff --git a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py index 4cb6514053a..d9c494a249b 100644 --- a/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py +++ b/src/sage/schemes/elliptic_curves/ell_curve_isogeny.py @@ -2418,7 +2418,7 @@ def __init_odd_kernel_polynomial(self, E, psi): sage: R. = F[] sage: f = x + alpha^2 + 1 sage: phi._EllipticCurveIsogeny__init_odd_kernel_polynomial(E, f) - (x^3 + (alpha^2 + 1)*x + alpha^3 + alpha^2 + alpha, x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + (alpha)*y + (alpha), alpha^2 + alpha + 1, alpha^3 + alpha^2 + alpha, 1, 3) + (x^3 + (alpha^2 + 1)*x + alpha^3 + alpha^2 + alpha, x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + alpha*y + alpha, alpha^2 + alpha + 1, alpha^3 + alpha^2 + alpha, 1, 3) sage: E = EllipticCurve(j=-262537412640768000) sage: f = (E.isogenies_prime_degree()[0]).kernel_polynomial() @@ -2567,7 +2567,7 @@ def __compute_omega_general(self, E, psi, psi_pr, phi, phi_pr): sage: fi = phi._EllipticCurveIsogeny__phi sage: fi_pr = fi.derivative() sage: phi._EllipticCurveIsogeny__compute_omega_general(E, psi, psi_pr, fi, fi_pr) - x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + (alpha)*y + (alpha) + x^3*y + (alpha^2 + 1)*x^2*y + (alpha^2 + alpha + 1)*x^2 + (alpha^2 + 1)*x*y + (alpha^2 + alpha)*x + alpha*y + alpha A bug fixed in :trac:`7907`:: diff --git a/src/sage/schemes/generic/algebraic_scheme.py b/src/sage/schemes/generic/algebraic_scheme.py index 164826d9b5a..f0d73d0dcd3 100644 --- a/src/sage/schemes/generic/algebraic_scheme.py +++ b/src/sage/schemes/generic/algebraic_scheme.py @@ -1982,7 +1982,7 @@ def weil_restriction(self): Closed subscheme of Affine Space of dimension 4 over Number Field in w with defining polynomial x^5 - 2 defined by: (-w)*z0^3 + (3*w)*z0*z1^2 + z2^2 - z3^2, - (-3*w)*z0^2*z1 + (w)*z1^3 + 2*z2*z3 - 1 + (-3*w)*z0^2*z1 + w*z1^3 + 2*z2*z3 - 1 sage: X.weil_restriction().ambient_space() is A.weil_restriction() True diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index 929ff0dccb6..5ecce3b3168 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -683,10 +683,10 @@ def hom(self, x, Y=None): sage: T = Matrix([[t,0,1],[0,1,0],[0,0,1]]) sage: C.hom(T, D) Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by x^2 + (t)*y^2 + 1/(t)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by 1/(t^2)*x^2 + (t)*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by x^2 + t*y^2 + 1/t*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Rational Field defined by 1/(t^2)*x^2 + t*y^2 - 2/(t^2)*x*z + (t + 1)/(t^2)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - ((t)*x + z : y : z) + (t*x + z : y : z) """ if is_Matrix(x): @@ -760,7 +760,7 @@ def _magma_init_(self, magma): sage: F. = GF(25) sage: C = Conic([3,0,1,4,a,2]) sage: C - Projective Conic Curve over Finite Field in a of size 5^2 defined by -2*x^2 - y^2 + x*z + (a)*y*z + 2*z^2 + Projective Conic Curve over Finite Field in a of size 5^2 defined by -2*x^2 - y^2 + x*z + a*y*z + 2*z^2 sage: magma(C) # optional - magma Conic over GF(5^2) defined by 3*X^2 + 4*Y^2 + X*Z + a*Y*Z + 2*Z^2 @@ -1077,7 +1077,7 @@ def rational_point(self, algorithm = 'default', read_cache = True): sage: F. = FiniteField(7^20) sage: C = Conic([1, a, -5]); C - Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + (a)*y^2 + 2*z^2 + Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + a*y^2 + 2*z^2 sage: C.rational_point() # output is random (4*a^19 + 5*a^18 + 4*a^17 + a^16 + 6*a^15 + 3*a^13 + 6*a^11 + a^9 + 3*a^8 + 2*a^7 + 4*a^6 + 3*a^5 + 3*a^4 + a^3 + a + 6 : 5*a^18 + a^17 + a^16 + 6*a^15 + 4*a^14 + a^13 + 5*a^12 + 5*a^10 + 2*a^9 + 6*a^8 + 6*a^7 + 6*a^6 + 2*a^4 + 3 : 1) diff --git a/src/sage/schemes/plane_conics/con_finite_field.py b/src/sage/schemes/plane_conics/con_finite_field.py index 82f71c815d1..86a7e168259 100644 --- a/src/sage/schemes/plane_conics/con_finite_field.py +++ b/src/sage/schemes/plane_conics/con_finite_field.py @@ -108,7 +108,7 @@ def has_rational_point(self, point=False, read_cache=True, sage: F. = FiniteField(7^20) sage: C = Conic([1, a, -5]); C - Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + (a)*y^2 + 2*z^2 + Projective Conic Curve over Finite Field in a of size 7^20 defined by x^2 + a*y^2 + 2*z^2 sage: C.has_rational_point(point = True) # output is random (True, (a^18 + 2*a^17 + 4*a^16 + 6*a^13 + a^12 + 6*a^11 + 3*a^10 + 4*a^9 + 2*a^8 + 4*a^7 + a^6 + 4*a^4 + 6*a^2 + 3*a + 6 : 5*a^19 + 5*a^18 + 5*a^17 + a^16 + 2*a^15 + 3*a^14 + 4*a^13 + 5*a^12 + a^11 + 3*a^10 + 2*a^8 + 3*a^7 + 4*a^6 + 4*a^5 + 6*a^3 + 5*a^2 + 2*a + 4 : 1)) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 056eb076b28..a4fd0ec575c 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -601,7 +601,7 @@ def _matrix_times_polymap_(self, mat, h): sage: matrix([[i,0], [0,i]]) * f Scheme endomorphism of Projective Space of dimension 1 over Number Field in i with defining polynomial x^2 + 1 Defn: Defined on coordinates by sending (x : y) to - ((1/3*i)*x^2 + (1/2*i)*y^2 : (i)*y^2) + ((1/3*i)*x^2 + (1/2*i)*y^2 : i*y^2) """ from sage.modules.free_module_element import vector from sage.dynamics.arithmetic_dynamics.generic_ds import DynamicalSystem @@ -1114,7 +1114,7 @@ def dehomogenize(self, n): Scheme endomorphism of Affine Space of dimension 2 over Fraction Field of Univariate Polynomial Ring in t over Rational Field Defn: Defined on coordinates by sending (x, y) to - (1/(t)*x^2 + y^2, y^2 - 1/(t)) + (1/t*x^2 + y^2, y^2 - 1/t) :: @@ -1969,7 +1969,7 @@ def reduce_base_field(self): sage: f.reduce_base_field() Scheme endomorphism of Projective Space of dimension 1 over Finite Field in t2 of size 3^2 Defn: Defined on coordinates by sending (x : y) to - (x^2 + (t2)*y^2 : y^2) + (x^2 + t2*y^2 : y^2) sage: f2 = H2([x^2 + 5*y^2,y^2, 2*x*y]) sage: f2.reduce_base_field() Scheme morphism: @@ -1983,7 +1983,7 @@ def reduce_base_field(self): From: Projective Space of dimension 2 over Finite Field in t of size 3^4 To: Projective Space of dimension 1 over Finite Field in t of size 3^4 Defn: Defined on coordinates by sending (a : b : c) to - (a^2 + (t)*b^2 : c^2) + (a^2 + t*b^2 : c^2) :: @@ -2006,7 +2006,7 @@ def reduce_base_field(self): sage: f.reduce_base_field() Scheme endomorphism of Projective Space of dimension 1 over Finite Field in z4 of size 5^4 Defn: Defined on coordinates by sending (x : y) to - ((z4^3 + z4^2 + z4 - 2)*x^2 + (z4)*y^2 : x*y) + ((z4^3 + z4^2 + z4 - 2)*x^2 + z4*y^2 : x*y) sage: f=DynamicalSystem_projective([L.gen(3)*x^2 + L.gen(2)*y^2, x*y]) sage: f.reduce_base_field() Dynamical System of Projective Space of dimension 1 over Finite Field in z6 of size 5^6 diff --git a/src/sage/schemes/toric/fano_variety.py b/src/sage/schemes/toric/fano_variety.py index 579fd4821f2..8935197298d 100644 --- a/src/sage/schemes/toric/fano_variety.py +++ b/src/sage/schemes/toric/fano_variety.py @@ -57,10 +57,10 @@ ....: monomial_points="all") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a9)*z0^2*z1 + (a7)*z0*z1^2 - + (a1)*z1^3 + (a8)*z0^2*z2 + (a6)*z0*z1*z2 - + (a4)*z1^2*z2 + (a5)*z0*z2^2 - + (a3)*z1*z2^2 + (a2)*z2^3 + a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 + + a4*z1^2*z2 + a5*z0*z2^2 + + a3*z1*z2^2 + a2*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: @@ -69,7 +69,7 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a1)*z1^3 + (a6)*z0*z1*z2 + (a2)*z2^3 + a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of ``Delta_polar``:: @@ -80,10 +80,10 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: - (a2)*z2^3*z3^2*z4*z5^2*z8 - + (a1)*z1^3*z3*z4^2*z7^2*z9 - + (a3)*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + (a0)*z0^3*z5*z7*z8^2*z9^2 + a2*z2^3*z3^2*z4*z5^2*z8 + + a1*z1^3*z3*z4^2*z7^2*z9 + + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + + a0*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities @@ -96,7 +96,7 @@ ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a1)*z1^3 + (a3)*z0*z1*z2 + (a2)*z2^3 + a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 This looks very similar to our second version of the anticanonical hypersurface of the projective plane, as expected, since all @@ -110,8 +110,8 @@ sage: FTV.anticanonical_hypersurface() Closed subscheme of 3-d CPR-Fano toric variety covered by 4 affine patches defined by: - (a0)*z2^12 + (a4)*z2^6*z3^6 + (a3)*z3^12 - + (a8)*z0*z1*z2*z3 + (a2)*z1^3 + (a1)*z0^2 + a0*z2^12 + a4*z2^6*z3^6 + a3*z3^12 + + a8*z0*z1*z2*z3 + a2*z1^3 + a1*z0^2 Below you will find detailed descriptions of available functions. Current functionality of this module is very basic, but it is under active @@ -806,10 +806,10 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="all") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a9)*z0^2*z1 + (a7)*z0*z1^2 - + (a1)*z1^3 + (a8)*z0^2*z2 + (a6)*z0*z1*z2 - + (a4)*z1^2*z2 + (a5)*z0*z2^2 - + (a3)*z1*z2^2 + (a2)*z2^3 + a0*z0^3 + a9*z0^2*z1 + a7*z0*z1^2 + + a1*z1^3 + a8*z0^2*z2 + a6*z0*z1*z2 + + a4*z1^2*z2 + a5*z0*z2^2 + + a3*z1*z2^2 + a2*z2^3 In many cases it is sufficient to work with the "simplified polynomial moduli space" of anticanonical hypersurfaces:: @@ -818,7 +818,7 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a1)*z1^3 + (a6)*z0*z1*z2 + (a2)*z2^3 + a0*z0^3 + a1*z1^3 + a6*z0*z1*z2 + a2*z2^3 The mirror family to these hypersurfaces lives inside the Fano toric variety obtained using ``simplex`` as ``Delta`` instead of @@ -830,10 +830,10 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 9 affine patches defined by: - (a2)*z2^3*z3^2*z4*z5^2*z8 - + (a1)*z1^3*z3*z4^2*z7^2*z9 - + (a3)*z0*z1*z2*z3*z4*z5*z7*z8*z9 - + (a0)*z0^3*z5*z7*z8^2*z9^2 + a2*z2^3*z3^2*z4*z5^2*z8 + + a1*z1^3*z3*z4^2*z7^2*z9 + + a3*z0*z1*z2*z3*z4*z5*z7*z8*z9 + + a0*z0^3*z5*z7*z8^2*z9^2 Here we have taken the resolved version of the ambient space for the mirror family, but in fact we don't have to resolve singularities @@ -846,7 +846,7 @@ def anticanonical_hypersurface(self, **kwds): ....: monomial_points="simplified") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a0)*z0^3 + (a1)*z1^3 + (a3)*z0*z1*z2 + (a2)*z2^3 + a0*z0^3 + a1*z1^3 + a3*z0*z1*z2 + a2*z2^3 This looks very similar to our second anticanonical hypersurface of the projective plane, as expected, since all @@ -860,7 +860,7 @@ def anticanonical_hypersurface(self, **kwds): ....: coefficient_names="a b c d") Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (a)*z0^3 + (b)*z1^3 + (d)*z0*z1*z2 + (c)*z2^3 + a*z0^3 + b*z1^3 + d*z0*z1*z2 + c*z2^3 or give concrete coefficients :: @@ -877,7 +877,7 @@ def anticanonical_hypersurface(self, **kwds): sage: H Closed subscheme of 2-d CPR-Fano toric variety covered by 3 affine patches defined by: - (t)*z1^3 + (psi)/(phi + psi^2)*z0*z1*z2 + 1/(t)*z2^3 + t*z1^3 + psi/(phi + psi^2)*z0*z1*z2 + 1/t*z2^3 sage: R = H.ambient_space().base_ring() sage: R Fraction Field of @@ -1124,21 +1124,21 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - (a0)*z1*z4^2*z5^2*z7^3 + (a2)*z2*z4*z5*z6*z7^2*z8^2 - + (a3)*z2*z3*z4*z7*z8 + (a1)*z0*z2, - (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2 + (b0)*z2*z5*z6^3*z7*z8^4 - + (b5)*z1*z3*z4*z5*z6*z7*z8 + (b2)*z2*z3*z6^2*z8^3 - + (b1)*z1*z3^2*z4 + (b4)*z0*z1*z5*z6 + a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + + a3*z2*z3*z4*z7*z8 + a1*z0*z2, + b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 + + b5*z1*z3*z4*z5*z6*z7*z8 + b2*z2*z3*z6^2*z8^3 + + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 Now we include only monomials associated to vertices of `\Delta_i`:: sage: X.nef_complete_intersection(np, monomial_points="vertices") Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - (a0)*z1*z4^2*z5^2*z7^3 + (a2)*z2*z4*z5*z6*z7^2*z8^2 - + (a3)*z2*z3*z4*z7*z8 + (a1)*z0*z2, - (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2 + (b0)*z2*z5*z6^3*z7*z8^4 - + (b2)*z2*z3*z6^2*z8^3 + (b1)*z1*z3^2*z4 + (b4)*z0*z1*z5*z6 + a0*z1*z4^2*z5^2*z7^3 + a2*z2*z4*z5*z6*z7^2*z8^2 + + a3*z2*z3*z4*z7*z8 + a1*z0*z2, + b3*z1*z4*z5^2*z6^2*z7^2*z8^2 + b0*z2*z5*z6^3*z7*z8^4 + + b2*z2*z3*z6^2*z8^3 + b1*z1*z3^2*z4 + b4*z0*z1*z5*z6 (effectively, we set ``b5=0``). Next we provide coefficients explicitly instead of using default generic names:: @@ -1148,7 +1148,7 @@ def nef_complete_intersection(self, nef_partition, **kwds): ....: coefficients=[("a", "a^2", "a/e", "c_i"), list(range(1,6))]) Closed subscheme of 3-d CPR-Fano toric variety covered by 10 affine patches defined by: - (a)*z1*z4^2*z5^2*z7^3 + (a)/(e)*z2*z4*z5*z6*z7^2*z8^2 + a*z1*z4^2*z5^2*z7^3 + a/e*z2*z4*z5*z6*z7^2*z8^2 + (c_i)*z2*z3*z4*z7*z8 + (a^2)*z0*z2, 4*z1*z4*z5^2*z6^2*z7^2*z8^2 + z2*z5*z6^3*z7*z8^4 + 3*z2*z3*z6^2*z8^3 + 2*z1*z3^2*z4 + 5*z0*z1*z5*z6 @@ -1161,14 +1161,14 @@ def nef_complete_intersection(self, nef_partition, **kwds): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 22 affine patches defined by: - (a2)*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 - + (a0)*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 - + (a3)*z2*z3*z4*z7*z8*z9*z10*z11*z12 + (a1)*z0*z2, - (b0)*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2 - + (b3)*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 - + (b2)*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 - + (b5)*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 - + (b1)*z1*z3^2*z4*z11*z12 + (b4)*z0*z1*z5*z6*z13 + a2*z2*z4*z5*z6*z7^2*z8^2*z9^2*z10^2*z11*z12*z13 + + a0*z1*z4^2*z5^2*z7^3*z9*z10^2*z12*z13 + + a3*z2*z3*z4*z7*z8*z9*z10*z11*z12 + a1*z0*z2, + b0*z2*z5*z6^3*z7*z8^4*z9^3*z10^2*z11^2*z12*z13^2 + + b3*z1*z4*z5^2*z6^2*z7^2*z8^2*z9^2*z10^2*z11*z12*z13^2 + + b2*z2*z3*z6^2*z8^3*z9^2*z10*z11^2*z12*z13 + + b5*z1*z3*z4*z5*z6*z7*z8*z9*z10*z11*z12*z13 + + b1*z1*z3^2*z4*z11*z12 + b4*z0*z1*z5*z6*z13 """ return NefCompleteIntersection(self, nef_partition, **kwds) @@ -1356,7 +1356,7 @@ class AnticanonicalHypersurface(AlgebraicScheme_subscheme_toric): sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - (a0)*s^2*x^2 + (a3)*t^2*x^2 + (a6)*s*t*x*y + (a1)*s^2*y^2 + (a2)*t^2*y^2 + a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 See :meth:`~CPRFanoToricVariety_field.anticanonical_hypersurface()` for a more elaborate example. @@ -1374,7 +1374,7 @@ def __init__(self, P_Delta, monomial_points=None, coefficient_names=None, sage: ftv.AnticanonicalHypersurface(P1xP1) Closed subscheme of 2-d CPR-Fano toric variety covered by 4 affine patches defined by: - (a0)*s^2*x^2 + (a3)*t^2*x^2 + (a6)*s*t*x*y + (a1)*s^2*y^2 + (a2)*t^2*y^2 + a0*s^2*x^2 + a3*t^2*x^2 + a6*s*t*x*y + a1*s^2*y^2 + a2*t^2*y^2 Check that finite fields are handled correctly :trac:`14899`:: @@ -1473,10 +1473,10 @@ class NefCompleteIntersection(AlgebraicScheme_subscheme_toric): sage: X.nef_complete_intersection(np) Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 - + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, - (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 - + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 See :meth:`CPRFanoToricVariety_field.nef_complete_intersection` for a more elaborate example. @@ -1499,10 +1499,10 @@ def __init__(self, P_Delta, nef_partition, sage: NefCompleteIntersection(X, np) Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 - + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, - (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 - + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 """ if not is_CPRFanoToricVariety(P_Delta): raise TypeError("nef complete intersections can only be " @@ -1597,10 +1597,10 @@ def cohomology_class(self): sage: CI Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 - + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, - (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 - + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 sage: CI.cohomology_class() [2*z3*z4 + 4*z3*z5 + 2*z4*z5] """ @@ -1630,10 +1630,10 @@ def nef_partition(self): sage: CI Closed subscheme of 3-d CPR-Fano toric variety covered by 8 affine patches defined by: - (a2)*z0^2*z1 + (a5)*z0*z1*z3 + (a1)*z1*z3^2 - + (a3)*z0^2*z4 + (a4)*z0*z3*z4 + (a0)*z3^2*z4, - (b1)*z1*z2^2 + (b2)*z2^2*z4 + (b5)*z1*z2*z5 - + (b4)*z2*z4*z5 + (b3)*z1*z5^2 + (b0)*z4*z5^2 + a2*z0^2*z1 + a5*z0*z1*z3 + a1*z1*z3^2 + + a3*z0^2*z4 + a4*z0*z3*z4 + a0*z3^2*z4, + b1*z1*z2^2 + b2*z2^2*z4 + b5*z1*z2*z5 + + b4*z2*z4*z5 + b3*z1*z5^2 + b0*z4*z5^2 sage: CI.nef_partition() Nef-partition {0, 1, 3} U {2, 4, 5} sage: CI.nef_partition() is np diff --git a/src/sage/structure/coerce.pyx b/src/sage/structure/coerce.pyx index 7dc6cbd59ff..4d9069725ae 100644 --- a/src/sage/structure/coerce.pyx +++ b/src/sage/structure/coerce.pyx @@ -484,7 +484,7 @@ cdef class CoercionModel: EXAMPLES:: sage: f = ZZ['t','x'].0 + QQ['x'].0 + CyclotomicField(13).gen(); f - t + x + (zeta13) + t + x + zeta13 sage: f.parent() Multivariate Polynomial Ring in t, x over Cyclotomic Field of order 13 and degree 12 sage: ZZ['x','y'].0 + ~Frac(QQ['y']).0 diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/mpoly_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/mpoly_doctest.py index bb56738cd50..0e6cad57fee 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/mpoly_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/mpoly_doctest.py @@ -93,7 +93,7 @@ sage: (x^10 + y^5).gcd(x^4 - y^2) x^2 + y sage: (x^10 + y^5).factor() - (x^2 + y) * (x^2 + (a^3)*y) * (x^2 + (a^2)*y) * (x^2 + (a)*y) * (x^2 + (-a^3 - a^2 - a - 1)*y) + (x^2 + y) * (x^2 + (a^3)*y) * (x^2 + (a^2)*y) * (x^2 + a*y) * (x^2 + (-a^3 - a^2 - a - 1)*y) Sage example in ./mpoly.tex, line 564:: From b45fc7e3f206cad0078ad259d5e951a1feb3fdfb Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Tue, 12 Oct 2021 18:02:46 +0200 Subject: [PATCH 059/378] Clean intermediate coefficients too --- src/sage/libs/singular/singular.pyx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index b576c7e9719..aadc0d244f8 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -651,6 +651,8 @@ cdef number *sa2si_transext(object elem, ring *_ring): denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + _ring.cf.cfDelete(&cfnum, _ring.cf) + _ring.cf.cfDelete(&cfden, _ring.cf) for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): @@ -671,6 +673,8 @@ cdef number *sa2si_transext(object elem, ring *_ring): denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + _ring.cf.cfDelete(&cfnum, _ring.cf) + _ring.cf.cfDelete(&cfden, _ring.cf) for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) for k in range(ex): @@ -689,8 +693,6 @@ cdef number *sa2si_transext(object elem, ring *_ring): _ring.cf.cfDelete(&numerator, _ring.cf) _ring.cf.cfDelete(&denominator, _ring.cf) - _ring.cf.cfDelete(&cfnum, _ring.cf) - _ring.cf.cfDelete(&cfden, _ring.cf) _ring.cf.cfDelete(&naCoeff, _ring.cf) _ring.cf.cfDelete(&a, _ring.cf) From 717f98bdb79b5a00820673e94e3096df66c12dab Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Oct 2021 14:02:11 -0700 Subject: [PATCH 060/378] build/pkgs/polymake/distros/gentoo.txt: Remove --- build/pkgs/polymake/distros/gentoo.txt | 1 - 1 file changed, 1 deletion(-) delete mode 100644 build/pkgs/polymake/distros/gentoo.txt diff --git a/build/pkgs/polymake/distros/gentoo.txt b/build/pkgs/polymake/distros/gentoo.txt deleted file mode 100644 index 2a9cc70b2f5..00000000000 --- a/build/pkgs/polymake/distros/gentoo.txt +++ /dev/null @@ -1 +0,0 @@ -polymake From f04ad5a9ea0c81e39ea600999d76343d4747e21e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 12 Oct 2021 16:05:48 -0700 Subject: [PATCH 061/378] src/sage/rings/real_double.pyx: Replace gsl_{isnan,isinf,finite} by libc.math functions --- src/sage/rings/real_double.pyx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 7356600a482..dd6c5591a44 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -858,9 +858,9 @@ cdef class RealDoubleElement(FieldElement): # First, check special values if self._value == 0: return RealDoubleElement(libc.math.ldexp(1.0, -1074)) - if gsl_isnan(self._value): + if libc.math.isnan(self._value): return self - if gsl_isinf(self._value): + if libc.math.isinf(self._value): return self.abs() # Normal case @@ -1022,8 +1022,8 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(22/7)._sage_input_(sib, False) {call: {atomic:RDF}({atomic:3.1428571428571428})} """ - cdef int isinf = gsl_isinf(self._value) - cdef bint isnan = gsl_isnan(self._value) + cdef int isinf = libc.math.isinf(self._value) + cdef bint isnan = libc.math.isnan(self._value) if isinf or isnan: if isnan: v = sib.name('NaN') @@ -1230,7 +1230,7 @@ cdef class RealDoubleElement(FieldElement): ... TypeError: Attempt to get integer part of NaN """ - if gsl_isnan(self._value): + if libc.math.isnan(self._value): raise TypeError("Attempt to get integer part of NaN") else: return Integer(int(self._value)) @@ -1688,7 +1688,7 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_NaN() True """ - return gsl_isnan(self._value) + return libc.math.isnan(self._value) def is_positive_infinity(self): r""" @@ -1703,7 +1703,7 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_positive_infinity() False """ - return gsl_isinf(self._value) > 0 + return libc.math.isinf(self._value) > 0 def is_negative_infinity(self): r""" @@ -1718,7 +1718,7 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_negative_infinity() True """ - return gsl_isinf(self._value) < 0 + return libc.math.isinf(self._value) < 0 def is_infinity(self): r""" @@ -1732,7 +1732,7 @@ cdef class RealDoubleElement(FieldElement): sage: (b/a).is_infinity() False """ - return gsl_isinf(self._value) + return libc.math.isinf(self._value) cpdef _richcmp_(left, right, int op): """ @@ -2925,9 +2925,9 @@ cdef double_repr(double x): """ Convert a double to a string with maximum precision. """ - if gsl_finite(x): + if libc.math.isfinite(x): return repr(x) - cdef int v = gsl_isinf(x) + cdef int v = libc.math.isinf(x) if v > 0: return "+infinity" if v < 0: From 4a02d25877f187d78a0f748847daa580f27adda7 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Thu, 14 Oct 2021 13:28:59 +0200 Subject: [PATCH 062/378] Improve documentation --- src/sage/libs/singular/ring.pyx | 7 + src/sage/libs/singular/singular.pyx | 340 +++++++++++++++++++++++++++- 2 files changed, 343 insertions(+), 4 deletions(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 64fceeaff88..f8cd183bb00 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -6,6 +6,8 @@ AUTHORS: - Martin Albrecht (2009-07): initial implementation - Kwankyu Lee (2010-06): added matrix term order support + +- Miguel Marco (2021): added transcendental extensions over Q """ #***************************************************************************** # Copyright (C) 2009 Martin Albrecht @@ -127,6 +129,11 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: sage: P. = Zmod(25213521351515232)[]; P Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232 + sage: K = PolynomialRing(QQ, 's,t').fraction_field() + sage: P. = K[]; P + Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in s, t over Rational Field + + TESTS: Check that ``degneglex`` and ``degrevlex`` are the same up to reversal of diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index aadc0d244f8..cb8a1b6aad0 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -4,6 +4,8 @@ libSingular: Conversion Routines and Initialisation AUTHOR: - Martin Albrecht + +- Miguel Marco (2021): added transcendental extensions over Q """ # **************************************************************************** @@ -56,6 +58,21 @@ _saved_options = (int(0),0,0) cdef Rational si2sa_QQ(number *n, number **nn, ring *_ring): """ + Create a sage rational number from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular rational number + + - ``*n`` - a pointer to a pointer like before + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + OUTPUT: + + - A sage Rational + TESTS:: sage: P. = QQ[] @@ -113,6 +130,20 @@ cdef Rational si2sa_QQ(number *n, number **nn, ring *_ring): cdef Integer si2sa_ZZ(number *n, ring *_ring): """ + Create a sage integer number from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular integer number + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + OUTPUT: + + - A sage Integer + + TESTS:: sage: P. = ZZ[] @@ -134,6 +165,21 @@ cdef Integer si2sa_ZZ(number *n, ring *_ring): cdef FFgivE si2sa_GFqGivaro(number *n, ring *_ring, Cache_givaro cache): """ + Create a sage element of a small finite field from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a finite field + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``cache`` - A Givaro number field + + OUTPUT: + + - A sage element of ``cache`` + TESTS:: sage: K. = GF(5^3) @@ -174,6 +220,23 @@ cdef FFgivE si2sa_GFqGivaro(number *n, ring *_ring, Cache_givaro cache): cdef FFgf2eE si2sa_GFqNTLGF2E(number *n, ring *_ring, Cache_ntl_gf2e cache): """ + Create a sage element of a finite field of characteristic 2 from a + singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a finite field + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``cache`` - A ntl_gf2e number field + + OUTPUT: + + - A sage element of ``cache`` + + TESTS:: sage: K. = GF(2^20) @@ -209,6 +272,21 @@ cdef FFgf2eE si2sa_GFqNTLGF2E(number *n, ring *_ring, Cache_ntl_gf2e cache): cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): """ + Create a sage element of a generic finite field from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a finite field + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``base`` - A sage finite field + + OUTPUT: + + - A sage element of ``base`` + TESTS:: sage: K. = GF(3^16) @@ -255,8 +333,25 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): z = pNext(z) return ret -cdef object si2sa_transext(number *n, ring *_ring, object base): +cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): """ + Create a sage element of a transcendental extension of ``QQ`` from a + singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a transcendental extension + of the rationals + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``base`` - A sage FractionField + + OUTPUT: + + - A sage element of ``base`` + TESTS:: sage: F = PolynomialRing(QQ,'a,b').fraction_field() @@ -331,6 +426,23 @@ cdef object si2sa_transext(number *n, ring *_ring, object base): cdef object si2sa_NF(number *n, ring *_ring, object base): """ + Create a sage element of a number field from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in an algebraic extension of + the rationals + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``base`` - A sage NumberField + + OUTPUT: + + - A sage element of ``base`` + + TESTS:: sage: K. = NumberField(x^2 - 2) @@ -379,6 +491,21 @@ cdef object si2sa_NF(number *n, ring *_ring, object base): cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base): """ + Create a sage element of a ring of integers modulo n from a singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a ring of integers modulo n + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``base`` - A sage IntegerModRing + + OUTPUT: + + - A sage element of ``base`` + TESTS:: sage: P. = Integers(10)[] @@ -425,6 +552,20 @@ cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base): cdef number *sa2si_QQ(Rational r, ring *_ring): """ + Create a singular number from a sage rational. + + INPUT: + + - ``r`` - a sage rational number + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: sage: P. = QQ[] @@ -442,6 +583,37 @@ cdef number *sa2si_QQ(Rational r, ring *_ring): cdef number *sa2si_GFqGivaro(int quo, ring *_ring): """ + Create a singular number in a small finite field. + + INPUT: + + - ``quo`` - a sage integer + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + Number field elements are represented as polynomials in the number field + generator. In this case, ``quo`` is the integer resulting from evaluating + that polynomial in the characteristic of the field. + + + TESTS:: + + sage: F = FiniteField(5^2) + sage: type(F) + + sage: R. = F[] + sage: R(0) + 1 + 1 + sage: R(F.gen()) + 1 + (z2 + 1) + sage: R(F.gen()^2) + 1 + (z2 - 1) + """ if _ring != currRing: rChangeCurrRing(_ring) @@ -481,6 +653,33 @@ cdef number *sa2si_GFqGivaro(int quo, ring *_ring): cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): """ + Create a singular number from a sage element of a finite field of + characteristic 2. + + INPUT: + + - ``elem`` - a sage element of a ntl_gf2e finite field + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: + + sage: F = FiniteField(2^20) + sage: type(F) + + sage: R. = F[] + sage: R(0)+1 + 1 + sage: R(F.gen()) + 1 + (z20 + 1) + sage: R(F.gen()^21) + 1 + (z20^11 + z20^10 + z20^8 + z20^7 + z20^6 + z20^5 + z20^2 + z20 + 1) + """ if _ring != currRing: rChangeCurrRing(_ring) cdef int i @@ -522,6 +721,32 @@ cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): cdef number *sa2si_GFq_generic(object elem, ring *_ring): """ + Create a singular number from a sage element of a generic finite field. + + INPUT: + + - ``elem`` - a sage element of a generic finite field + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: + + sage: F = FiniteField(3^20) + sage: type(F) + + sage: R. = F[] + sage: R(0) + 1 + 1 + sage: R(F.gen()) + 1 + (z20 + 1) + sage: R(F.gen()^21) + 1 + (z20^14 - z20^12 - z20^11 - z20^10 - z20^9 + z20^6 + z20^5 + z20^4 - z20^2 + z20 + 1) + """ cdef int i cdef number *n1 @@ -561,8 +786,23 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): return n1 -cdef number *sa2si_transext(object elem, ring *_ring): +cdef number *sa2si_transext_QQ(object elem, ring *_ring): """ + Create a singular number from a sage element of a transcendental extension + of the rationals. + + INPUT: + + - ``elem`` - a sage element of a FractionField of polynomials over the rationals + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: sage: F = PolynomialRing(QQ,'a,b').fraction_field() @@ -701,6 +941,34 @@ cdef number *sa2si_transext(object elem, ring *_ring): cdef number *sa2si_NF(object elem, ring *_ring): """ + Create a singular number from a sage element of a number field. + + INPUT: + + - ``elem`` - a sage element of a NumberField + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: + + sage: F = NumberField(x^3+x+1, 'a') + sage: type(F) + + sage: R. = F[] + sage: R(0) + 1 + 1 + sage: R(1) + 1 + sage: R(F.gen()) + 1 + (a + 1) + sage: R(F.gen()^5) + 1 + (-a^2 + a + 2) + """ cdef int i cdef number *n1 @@ -767,6 +1035,20 @@ cdef number *sa2si_NF(object elem, ring *_ring): cdef number *sa2si_ZZ(Integer d, ring *_ring): """ + Create a singular number from a sage Integer. + + INPUT: + + - ``elem`` - a sage Integer + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + TESTS:: sage: P. = ZZ[] @@ -786,6 +1068,16 @@ cdef number *sa2si_ZZ(Integer d, ring *_ring): cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring): """ + Create a singular number from a sage element of a IntegerModRing. + + INPUT: + + - ``elem`` - a sage IntegerMod + + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + TESTS:: sage: P. = Integers(10)[] @@ -859,6 +1151,21 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring): raise ValueError cdef object si2sa(number *n, ring *_ring, object base): + r""" + Create a sage number from a singular one + + INPUT: + + - ``n`` - a (pointer to) a singular number + + - ``_ring`` - a (pointer to) the singular ring where ``n`` lives + + - ``object`` - the sage parent where the result will live + + OUTPUT: + + An element of ``base`` + """ if isinstance(base, FiniteField_prime_modn): return base(_ring.cf.cfInt(n, _ring.cf)) @@ -881,7 +1188,7 @@ cdef object si2sa(number *n, ring *_ring, object base): return si2sa_NF(n, _ring, base) elif isinstance(base, FractionField_generic) and isinstance(base.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base.base_ring(), RationalField): - return si2sa_transext(n, _ring, base) + return si2sa_transext_QQ(n, _ring, base) elif isinstance(base, IntegerModRing_generic): if _ring.cf.type == n_unknown: @@ -892,6 +1199,20 @@ cdef object si2sa(number *n, ring *_ring, object base): raise ValueError("cannot convert from SINGULAR number") cdef number *sa2si(Element elem, ring * _ring): + r""" + Create a singular number from a sage one. + + INPUT: + + - ``elem`` - a sage element from a parent. The parent must have a + corresponding singular coefficient type. + + - ``_ring`` - a (pointer to) the singular ring where the result will live. + + OUTPUT: + + a (pointer to) a singular number + """ cdef int i = 0 if isinstance(elem._parent, FiniteField_prime_modn): return n_Init(int(elem),_ring) @@ -918,13 +1239,24 @@ cdef number *sa2si(Element elem, ring * _ring): return n_Init(int(elem),_ring) return sa2si_ZZmod(elem, _ring) elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), RationalField): - return sa2si_transext(elem, _ring) + return sa2si_transext_QQ(elem, _ring) else: raise ValueError("cannot convert to SINGULAR number") cdef object si2sa_intvec(intvec *v): + r""" + create a sage tuple from a singular vector of integers + + INPUT: + + - ``v`` - a (pointer to) a singular intvec + + OUTPUT: + + a sage tuple + """ cdef int r cdef list l = list() for r in range(v.length()): From d3caeb4d6c48f4a17a85dd1c9a9efeef92c3b559 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 15 Oct 2021 15:06:00 -0700 Subject: [PATCH 063/378] src/sage/rings/real_double.pyx: Fixup: Replace gsl_{isnan,isinf,finite} by libc.math functions --- src/sage/rings/real_double.pyx | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index dd6c5591a44..ad9a94a7d69 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -1022,7 +1022,7 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(22/7)._sage_input_(sib, False) {call: {atomic:RDF}({atomic:3.1428571428571428})} """ - cdef int isinf = libc.math.isinf(self._value) + cdef bint isinf = libc.math.isinf(self._value) cdef bint isnan = libc.math.isnan(self._value) if isinf or isnan: if isnan: @@ -1030,7 +1030,7 @@ cdef class RealDoubleElement(FieldElement): else: v = sib.name('infinity') v = sib(self.parent())(v) - if isinf < 0: + if self._value < 0: v = -v return v @@ -1688,7 +1688,7 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_NaN() True """ - return libc.math.isnan(self._value) + return bool(libc.math.isnan(self._value)) def is_positive_infinity(self): r""" @@ -1703,7 +1703,9 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_positive_infinity() False """ - return libc.math.isinf(self._value) > 0 + if not libc.math.isinf(self._value): + return False + return self._value > 0 def is_negative_infinity(self): r""" @@ -1718,7 +1720,9 @@ cdef class RealDoubleElement(FieldElement): sage: a.is_negative_infinity() True """ - return libc.math.isinf(self._value) < 0 + if not libc.math.isinf(self._value): + return False + return self._value < 0 def is_infinity(self): r""" @@ -1732,7 +1736,7 @@ cdef class RealDoubleElement(FieldElement): sage: (b/a).is_infinity() False """ - return libc.math.isinf(self._value) + return bool(libc.math.isinf(self._value)) cpdef _richcmp_(left, right, int op): """ @@ -2927,9 +2931,9 @@ cdef double_repr(double x): """ if libc.math.isfinite(x): return repr(x) - cdef int v = libc.math.isinf(x) - if v > 0: - return "+infinity" - if v < 0: - return "-infinity" + if libc.math.isinf(x): + if x > 0: + return "+infinity" + if x < 0: + return "-infinity" return "NaN" From e340b2c0cffe1dc43d30122f278991682b462689 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 15 Oct 2021 19:51:20 -0700 Subject: [PATCH 064/378] sage.misc.allocator: Add cdef hook_tp_functions_type --- src/sage/misc/allocator.pxd | 2 ++ src/sage/misc/allocator.pyx | 34 ++++++++++++++++++++++------------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/sage/misc/allocator.pxd b/src/sage/misc/allocator.pxd index fce3179c626..7945a75241f 100644 --- a/src/sage/misc/allocator.pxd +++ b/src/sage/misc/allocator.pxd @@ -1,3 +1,5 @@ from cpython.object cimport * +cdef hook_tp_functions_type(object t, newfunc tp_new, destructor tp_dealloc, bint useGC) + cdef hook_tp_functions(object global_dummy, newfunc tp_new, destructor tp_dealloc, bint useGC) diff --git a/src/sage/misc/allocator.pyx b/src/sage/misc/allocator.pyx index 1277f5a61d3..b7fafdce286 100644 --- a/src/sage/misc/allocator.pyx +++ b/src/sage/misc/allocator.pyx @@ -1,22 +1,11 @@ from cpython.ref cimport Py_INCREF -cdef hook_tp_functions(object global_dummy, newfunc tp_new, destructor tp_dealloc, bint useGC): +cdef _hook_tp_functions_type(PyTypeObject *t, newfunc tp_new, destructor tp_dealloc, bint useGC): """ Initialize the fast integer creation functions. """ cdef long flag - cdef PyObject* o = global_dummy - cdef PyTypeObject* t = Py_TYPE(global_dummy) - - # Make sure this never, ever gets collected. - # This is not necessary for cdef'ed variables as the global - # dummy integer, as such objects do not get automatically collected. - # In fact there is no obvious reason to prevent collection when Sage quits - # and we are certain no further call to the allocation function will be - # made; so this could be removed when the code is clean enough. - Py_INCREF(global_dummy) - # By default every object created in Pyrex is garbage # collected. This means it may have references to other objects # the Garbage collector has to look out for. We remove this flag @@ -34,3 +23,24 @@ cdef hook_tp_functions(object global_dummy, newfunc tp_new, destructor tp_deallo # to be constructed/destructed. t.tp_new = tp_new t.tp_dealloc = tp_dealloc + + +cdef hook_tp_functions_type(object tp, newfunc tp_new, destructor tp_dealloc, bint useGC): + cdef PyTypeObject *t = tp + _hook_tp_functions_type(t, tp_new, tp_dealloc, useGC) + + +cdef hook_tp_functions(object global_dummy, newfunc tp_new, destructor tp_dealloc, bint useGC): + """ + Initialize the fast integer creation functions. + """ + # Make sure this never, ever gets collected. + # This is not necessary for cdef'ed variables as the global + # dummy integer, as such objects do not get automatically collected. + # In fact there is no obvious reason to prevent collection when Sage quits + # and we are certain no further call to the allocation function will be + # made; so this could be removed when the code is clean enough. + Py_INCREF(global_dummy) + + cdef PyTypeObject* t = Py_TYPE(global_dummy) + _hook_tp_functions_type(t, tp_new, tp_dealloc, useGC) From 31d188f92ac0ee01c81196e7b00095201f794a7a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 15 Oct 2021 19:51:43 -0700 Subject: [PATCH 065/378] sage.rings.real_double_element_gsl: Split out from sage.rings.real_double --- src/sage/rings/real_double.pxd | 3 - src/sage/rings/real_double.pyx | 786 +------------------- src/sage/rings/real_double_element_gsl.pxd | 7 + src/sage/rings/real_double_element_gsl.pyx | 789 +++++++++++++++++++++ 4 files changed, 815 insertions(+), 770 deletions(-) create mode 100644 src/sage/rings/real_double_element_gsl.pxd create mode 100644 src/sage/rings/real_double_element_gsl.pyx diff --git a/src/sage/rings/real_double.pxd b/src/sage/rings/real_double.pxd index 27889ea7f83..06d4121ef26 100644 --- a/src/sage/rings/real_double.pxd +++ b/src/sage/rings/real_double.pxd @@ -11,8 +11,5 @@ cdef class RealDoubleElement(FieldElement): cpdef _add_(self, other) cpdef _mul_(self, other) cpdef RealDoubleElement abs(RealDoubleElement self) - cdef __pow_double(self, double exponent, double sign) - cpdef _pow_(self, other) - cdef _log_base(self, double log_of_base) cdef double_repr(double x) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index ad9a94a7d69..c15288dabd4 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -50,10 +50,6 @@ from cysignals.signals cimport sig_on, sig_off from sage.ext.stdsage cimport PY_NEW from sage.cpython.python_debug cimport if_Py_TRACE_REFS_then_PyObject_INIT -from sage.libs.gsl.all cimport * - -gsl_set_error_handler_off() - import math, operator from cypari2.convert cimport new_gen_from_double @@ -578,9 +574,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): sage: RDF.factorial(100) 9.332621544394415e+157 """ - if n < 0: - raise ArithmeticError("n must be nonnegative") - return self(gsl_sf_fact(n)) + return global_dummy_element._factorial(n) def zeta(self, n=2): """ @@ -767,7 +761,6 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(0).prec() 53 """ - return 53 def ulp(self): @@ -1884,7 +1877,6 @@ cdef class RealDoubleElement(FieldElement): """ return self._value in ZZ - def cube_root(self): """ Return the cubic root (defined over the real numbers) of ``self``. @@ -1899,710 +1891,6 @@ cdef class RealDoubleElement(FieldElement): """ return self.nth_root(3) - - def nth_root(self, int n): - """ - Return the `n^{th}` root of ``self``. - - INPUT: - - - ``n`` -- an integer - - OUTPUT: - - The output is a complex double if ``self`` is negative and `n` is even, - otherwise it is a real double. - - EXAMPLES:: - - sage: r = RDF(-125.0); r.nth_root(3) - -5.000000000000001 - sage: r.nth_root(5) - -2.6265278044037674 - sage: RDF(-2).nth_root(5)^5 # rel tol 1e-15 - -2.000000000000001 - sage: RDF(-1).nth_root(5)^5 - -1.0 - sage: RDF(3).nth_root(10)^10 - 2.9999999999999982 - sage: RDF(-1).nth_root(2) - 6.123233995736757e-17 + 1.0*I - sage: RDF(-1).nth_root(4) - 0.7071067811865476 + 0.7071067811865475*I - """ - if n == 0: - return RealDoubleElement(float('nan')) - if self._value < 0: - if GSL_IS_EVEN(n): - return self._complex_double_(sage.rings.complex_double.CDF).nth_root(n) - else: - return - ( (-self) ** (float(1)/n) ) - else: - return self ** (float(1)/n) - - cdef __pow_double(self, double exponent, double sign): - """ - If ``sign == 1`` or ``self >= 0``, return ``self ^ exponent``. - If ``sign == -1`` and ``self < 0``, return ``- abs(self) ^ exponent``. - """ - cdef double v = self._value - if v >= 0: - if v == 1: - return self - elif exponent == 0: - return self._new_c(1.0) - elif v == 0: - if exponent < 0: - raise ZeroDivisionError("0.0 cannot be raised to a negative power") - return self - sign = 1.0 - else: # v < 0 - expmod2 = libc.math.fmod(exponent, 2.0) - if expmod2 == 0.0: - pass - elif expmod2 == 1.0: - sign = -1.0 - else: - raise ValueError("negative number cannot be raised to a fractional power") - v = -v - return self._new_c(sign * gsl_sf_exp(gsl_sf_log(v) * exponent)) - - cpdef _pow_(self, other): - """ - Return ``self`` raised to the real double power ``other``. - - EXAMPLES:: - - sage: a = RDF('1.23456') - sage: a^a - 1.2971114817819216 - - TESTS:: - - sage: RDF(0) ^ RDF(0.5) - 0.0 - sage: RDF(0) ^ (1/2) - 0.0 - sage: RDF(0) ^ RDF(0) - 1.0 - sage: RDF(0) ^ RDF(-1) - Traceback (most recent call last): - ... - ZeroDivisionError: 0.0 cannot be raised to a negative power - sage: RDF(-1) ^ RDF(0) - 1.0 - sage: RDF(-1) ^ RDF(1) - -1.0 - sage: RDF(-1) ^ RDF(0.5) - Traceback (most recent call last): - ... - ValueError: negative number cannot be raised to a fractional power - """ - return self.__pow_double((other)._value, 1) - - cpdef _pow_int(self, n): - """ - Return ``self`` raised to the integer power ``n``. - - TESTS:: - - sage: RDF(1) ^ (2^1000) - 1.0 - sage: RDF(1) ^ (2^1000 + 1) - 1.0 - sage: RDF(1) ^ (-2^1000) - 1.0 - sage: RDF(1) ^ (-2^1000 + 1) - 1.0 - sage: RDF(-1) ^ (2^1000) - 1.0 - sage: RDF(-1) ^ (2^1000 + 1) - -1.0 - sage: RDF(-1) ^ (-2^1000) - 1.0 - sage: RDF(-1) ^ (-2^1000 + 1) - -1.0 - - :: - - sage: base = RDF(1.0000000000000002) - sage: base._pow_int(0) - 1.0 - sage: base._pow_int(1) - 1.0000000000000002 - sage: base._pow_int(2) - 1.0000000000000004 - sage: base._pow_int(3) - 1.0000000000000007 - sage: base._pow_int(2^57) - 78962960182680.42 - sage: base._pow_int(2^57 + 1) - 78962960182680.42 - - :: - - sage: base = RDF(-1.0000000000000002) - sage: base._pow_int(0) - 1.0 - sage: base._pow_int(1) - -1.0000000000000002 - sage: base._pow_int(2) - 1.0000000000000004 - sage: base._pow_int(3) - -1.0000000000000007 - sage: base._pow_int(2^57) - 78962960182680.42 - sage: base._pow_int(2^57 + 1) - -78962960182680.42 - """ - return self.__pow_double(n, -1.0 if (n & 1) else 1.0) - - cdef _pow_long(self, long n): - """ - Compute ``self`` raised to the power ``n``. - - EXAMPLES:: - - sage: RDF('1.23456') ^ 20 - 67.64629770385... - sage: RDF(3) ^ 32 - 1853020188851841.0 - sage: RDF(2)^(-1024) - 5.562684646268003e-309 - - TESTS:: - - sage: base = RDF(1.0000000000000002) - sage: base ^ RDF(2^31) - 1.000000476837272 - sage: base ^ (2^57) - 78962960182680.42 - sage: base ^ RDF(2^57) - 78962960182680.42 - """ - if -2048 <= n <= 2048: - # For small exponents, it is possible that the powering - # is exact either because the base is a power of 2 - # (e.g. 2.0^1000) or because the exact result has few - # significant digits (e.g. 3.0^10). Here, we use the - # square-and-multiply algorithm by GSL. - return self._new_c(gsl_pow_int(self._value, n)) - # If the exponent is sufficiently large in absolute value, the - # result cannot be exact (except if the base is -1.0, 0.0 or - # 1.0 but those cases are handled by __pow_double too). The - # log-and-exp algorithm from __pow_double will be more precise - # than square-and-multiply. - - # We do need to take care of the sign since the conversion - # of n to double might change an odd number to an even number. - return self.__pow_double(n, -1.0 if (n & 1) else 1.0) - - cdef _log_base(self, double log_of_base): - if self._value == 0: - return RDF(-1)/RDF(0) - elif self._value < 0: - return RDF.NaN() - sig_on() - a = self._new_c(gsl_sf_log(self._value) / log_of_base) - sig_off() - return a - - def log(self, base=None): - """ - Return the logarithm. - - INPUT: - - - ``base`` -- integer or ``None`` (default). The base of the - logarithm. If ``None`` is specified, the base is `e` (the so-called - natural logarithm). - - OUTPUT: - - The logarithm of ``self``. If ``self`` is positive, a double - floating point number. Infinity if ``self`` is zero. A - imaginary complex floating point number if ``self`` is - negative. - - EXAMPLES:: - - sage: RDF(2).log() - 0.6931471805599453 - sage: RDF(2).log(2) - 1.0 - sage: RDF(2).log(pi) - 0.6055115613982801 - sage: RDF(2).log(10) - 0.30102999566398114 - sage: RDF(2).log(1.5) - 1.7095112913514547 - sage: RDF(0).log() - -infinity - sage: RDF(-1).log() - 3.141592653589793*I - sage: RDF(-1).log(2) # rel tol 1e-15 - 4.532360141827194*I - - TESTS: - - Make sure that we can take the log of small numbers accurately - and the fix doesn't break preexisting values (:trac:`12557`):: - - sage: R = RealField(128) - sage: def check_error(x): - ....: x = RDF(x) - ....: log_RDF = x.log() - ....: log_RR = R(x).log() - ....: diff = R(log_RDF) - log_RR - ....: if abs(diff) < log_RDF.ulp(): - ....: return True - ....: print("logarithm check failed for %s (diff = %s ulp)"% \ - ....: (x, diff/log_RDF.ulp())) - ....: return False - sage: all( check_error(2^x) for x in range(-100,100) ) - True - sage: all( check_error(x) for x in sxrange(0.01, 2.00, 0.01) ) - True - sage: all( check_error(x) for x in sxrange(0.99, 1.01, 0.001) ) - True - sage: RDF(1.000000001).log() - 1.000000082240371e-09 - sage: RDF(1e-17).log() - -39.14394658089878 - sage: RDF(1e-50).log() - -115.12925464970229 - """ - if self < 0: - from sage.rings.complex_double import CDF - return CDF(self).log(base) - if base is None: - return self._log_base(1) - else: - if isinstance(base, RealDoubleElement): - return self._log_base(base._log_base(1)) - else: - return self._log_base(gsl_sf_log(float(base))) - - def log2(self): - """ - Return log to the base 2 of ``self``. - - EXAMPLES:: - - sage: r = RDF(16.0) - sage: r.log2() - 4.0 - - :: - - sage: r = RDF(31.9); r.log2() - 4.9954845188775066 - """ - if self < 0: - from sage.rings.complex_double import CDF - return CDF(self).log(2) - sig_on() - a = self._new_c(gsl_sf_log(self._value) * M_1_LN2) - sig_off() - return a - - - def log10(self): - """ - Return log to the base 10 of ``self``. - - EXAMPLES:: - - sage: r = RDF('16.0'); r.log10() - 1.2041199826559248 - sage: r.log() / RDF(log(10)) - 1.2041199826559246 - sage: r = RDF('39.9'); r.log10() - 1.6009728956867482 - """ - if self < 0: - from sage.rings.complex_double import CDF - return CDF(self).log(10) - sig_on() - a = self._new_c(gsl_sf_log(self._value) * M_1_LN10) - sig_off() - return a - - def logpi(self): - r""" - Return log to the base `\pi` of ``self``. - - EXAMPLES:: - - sage: r = RDF(16); r.logpi() - 2.4220462455931204 - sage: r.log() / RDF(log(pi)) - 2.4220462455931204 - sage: r = RDF('39.9'); r.logpi() - 3.2203023346075152 - """ - if self < 0: - from sage.rings.complex_double import CDF - return CDF(self).log(M_PI) - sig_on() - a = self._new_c(gsl_sf_log(self._value) * M_1_LNPI) - sig_off() - return a - - def exp(self): - r""" - Return `e^\mathtt{self}`. - - EXAMPLES:: - - sage: r = RDF(0.0) - sage: r.exp() - 1.0 - - :: - - sage: r = RDF('32.3') - sage: a = r.exp(); a - 106588847274864.47 - sage: a.log() - 32.3 - - :: - - sage: r = RDF('-32.3') - sage: r.exp() - 9.381844588498685e-15 - - :: - - sage: RDF(1000).exp() - +infinity - """ - sig_on() - a = self._new_c(gsl_sf_exp(self._value)) - sig_off() - return a - - def exp2(self): - """ - Return `2^\mathtt{self}`. - - EXAMPLES:: - - sage: r = RDF(0.0) - sage: r.exp2() - 1.0 - - :: - - sage: r = RDF(32.0) - sage: r.exp2() - 4294967295.9999967 - - :: - - sage: r = RDF(-32.3) - sage: r.exp2() - 1.8911724825302065e-10 - """ - sig_on() - a = self._new_c(gsl_sf_exp(self._value * M_LN2)) - sig_off() - return a - - def exp10(self): - r""" - Return `10^\mathtt{self}`. - - EXAMPLES:: - - sage: r = RDF(0.0) - sage: r.exp10() - 1.0 - - :: - - sage: r = RDF(32.0) - sage: r.exp10() - 1.0000000000000069e+32 - - :: - - sage: r = RDF(-32.3) - sage: r.exp10() - 5.011872336272702e-33 - """ - sig_on() - a = self._new_c(gsl_sf_exp(self._value * M_LN10)) - sig_off() - return a - - def cos(self): - """ - Return the cosine of ``self``. - - EXAMPLES:: - - sage: t=RDF.pi()/2 - sage: t.cos() - 6.123233995736757e-17 - """ - return self._new_c(gsl_sf_cos(self._value)) - - def sin(self): - """ - Return the sine of ``self``. - - EXAMPLES:: - - sage: RDF(2).sin() - 0.9092974268256817 - """ - return self._new_c(gsl_sf_sin(self._value)) - - def dilog(self): - r""" - Return the dilogarithm of ``self``. - - This is defined by the - series `\sum_n x^n/n^2` for `|x| \le 1`. When the absolute - value of ``self`` is greater than 1, the returned value is the - real part of (the analytic continuation to `\CC` of) the - dilogarithm of ``self``. - - EXAMPLES:: - - sage: RDF(1).dilog() # rel tol 1.0e-13 - 1.6449340668482264 - sage: RDF(2).dilog() # rel tol 1.0e-13 - 2.46740110027234 - """ - return self._new_c(gsl_sf_dilog(self._value)) - - def restrict_angle(self): - r""" - Return a number congruent to ``self`` mod `2\pi` that lies in - the interval `(-\pi, \pi]`. - - Specifically, it is the unique `x \in (-\pi, \pi]` such - that ```self`` `= x + 2\pi n` for some `n \in \ZZ`. - - EXAMPLES:: - - sage: RDF(pi).restrict_angle() - 3.141592653589793 - sage: RDF(pi + 1e-10).restrict_angle() - -3.1415926534897936 - sage: RDF(1+10^10*pi).restrict_angle() - 0.9999977606... - """ - return self._new_c(gsl_sf_angle_restrict_symm(self._value)) - - def tan(self): - """ - Return the tangent of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/3 - sage: q.tan() - 1.7320508075688767 - sage: q = RDF.pi()/6 - sage: q.tan() - 0.5773502691896256 - """ - cdef double denom - cos = gsl_sf_cos(self._value) - a = self._new_c(gsl_sf_sin(self._value) / cos) - return a - - def sincos(self): - """ - Return a pair consisting of the sine and cosine of ``self``. - - EXAMPLES:: - - sage: t = RDF.pi()/6 - sage: t.sincos() - (0.49999999999999994, 0.8660254037844387) - """ - return self.sin(), self.cos() - - def hypot(self, other): - r""" - Computes the value `\sqrt{s^2 + o^2}` where `s` is ``self`` and `o` - is ``other`` in such a way as to avoid overflow. - - EXAMPLES:: - - sage: x = RDF(4e300); y = RDF(3e300) - sage: x.hypot(y) - 5e+300 - sage: sqrt(x^2+y^2) # overflow - +infinity - """ - sig_on() - a = self._new_c(gsl_sf_hypot(self._value, float(other))) - sig_off() - return a - - def arccos(self): - """ - Return the inverse cosine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/3 - sage: i = q.cos() - sage: i.arccos() == q - True - """ - return self._new_c(libc.math.acos(self._value)) - - def arcsin(self): - """ - Return the inverse sine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/5 - sage: i = q.sin() - sage: i.arcsin() == q - True - """ - return self._new_c(libc.math.asin(self._value)) - - def arctan(self): - """ - Return the inverse tangent of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/5 - sage: i = q.tan() - sage: i.arctan() == q - True - """ - return self._new_c(libc.math.atan(self._value)) - - - def cosh(self): - """ - Return the hyperbolic cosine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/12 - sage: q.cosh() - 1.0344656400955106 - """ - return self._new_c(gsl_ldexp( gsl_sf_exp(self._value) + gsl_sf_exp(-self._value), -1)) # (e^x + e^-x)/2 - - def sinh(self): - """ - Return the hyperbolic sine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/12 - sage: q.sinh() - 0.26480022760227073 - """ - return self._new_c(gsl_ldexp( gsl_sf_expm1(self._value) - gsl_sf_expm1(-self._value), -1)) # (e^x - e^-x)/2 - - def tanh(self): - """ - Return the hyperbolic tangent of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/12 - sage: q.tanh() - 0.25597778924568454 - """ - return self.sinh() / self.cosh() - - def acosh(self): - """ - Return the hyperbolic inverse cosine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/2 - sage: i = q.cosh(); i - 2.5091784786580567 - sage: abs(i.acosh()-q) < 1e-15 - True - """ - return self._new_c(gsl_acosh(self._value)) - - def arcsinh(self): - """ - Return the hyperbolic inverse sine of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/2 - sage: i = q.sinh(); i - 2.3012989023072947 - sage: abs(i.arcsinh()-q) < 1e-15 - True - """ - return self._new_c(gsl_asinh(self._value)) - - def arctanh(self): - """ - Return the hyperbolic inverse tangent of ``self``. - - EXAMPLES:: - - sage: q = RDF.pi()/2 - sage: i = q.tanh(); i - 0.9171523356672744 - sage: i.arctanh() - q # rel tol 1 - 4.440892098500626e-16 - """ - return self._new_c(gsl_atanh(self._value)) - - def sech(self): - r""" - Return the hyperbolic secant of ``self``. - - EXAMPLES:: - - sage: RDF(pi).sech() - 0.08626673833405443 - sage: CDF(pi).sech() - 0.08626673833405443 - """ - return 1/self.cosh() - - def csch(self): - r""" - Return the hyperbolic cosecant of ``self``. - - EXAMPLES:: - - sage: RDF(pi).csch() - 0.08658953753004694 - sage: CDF(pi).csch() # rel tol 1e-15 - 0.08658953753004696 - """ - return 1/self.sinh() - - def coth(self): - r""" - Return the hyperbolic cotangent of ``self``. - - EXAMPLES:: - - sage: RDF(pi).coth() - 1.003741873197321 - sage: CDF(pi).coth() - 1.0037418731973213 - """ - return self.cosh() / self.sinh() - def agm(self, other): r""" Return the arithmetic-geometric mean of ``self`` and ``other``. The @@ -2637,57 +1925,6 @@ cdef class RealDoubleElement(FieldElement): if abs((b1/a1)-1) < eps: return self._new_c(a1) a, b = a1, b1 - def erf(self): - """ - Return the value of the error function on ``self``. - - EXAMPLES:: - - sage: RDF(6).erf() - 1.0 - """ - return self._new_c(gsl_sf_erf(self._value)) - - def gamma(self): - """ - Return the value of the Euler gamma function on ``self``. - - EXAMPLES:: - - sage: RDF(6).gamma() - 120.0 - sage: RDF(1.5).gamma() # rel tol 1e-15 - 0.8862269254527584 - """ - sig_on() - a = self._new_c(gsl_sf_gamma(self._value)) - sig_off() - return a - - def zeta(self): - r""" - Return the Riemann zeta function evaluated at this real number. - - .. NOTE:: - - PARI is vastly more efficient at computing the Riemann zeta - function. See the example below for how to use it. - - EXAMPLES:: - - sage: RDF(2).zeta() # rel tol 1e-15 - 1.6449340668482269 - sage: RDF.pi()^2/6 - 1.6449340668482264 - sage: RDF(-2).zeta() - 0.0 - sage: RDF(1).zeta() - +infinity - """ - if self._value == 1: - return self._new_c(1)/self._new_c(0) - return self._new_c(gsl_sf_zeta(self._value)) - def algebraic_dependency(self, n): """ Return a polynomial of degree at most `n` which is @@ -2822,7 +2059,13 @@ def is_RealDoubleElement(x): # We use a global element to steal all the references # from. DO NOT INITIALIZE IT AGAIN and DO NOT REFERENCE IT! cdef RealDoubleElement global_dummy_element -global_dummy_element = RealDoubleElement(0) + +try: + from .real_double_element_gsl import RealDoubleElement_gsl +except ImportError: + global_dummy_element = RealDoubleElement(0) +else: + global_dummy_element = RealDoubleElement_gsl(0) # A global pool for performance when elements are rapidly created and destroyed. # It operates on the following principles: @@ -2890,7 +2133,7 @@ cdef PyObject* fast_tp_new(type t, args, kwds): # The global_dummy_element may have a reference count larger than # one, but it is expected that newly created objects have a # reference count of one. This is potentially unneeded if - # everybody plays nice, because the gobal_dummy_element has only + # everybody plays nice, because the global_dummy_element has only # one reference in that case. # Objects from the pool have reference count zero, so this @@ -2921,8 +2164,17 @@ cdef void fast_tp_dealloc(PyObject* o): PyObject_Free(o) -from sage.misc.allocator cimport hook_tp_functions +from sage.misc.allocator cimport hook_tp_functions, hook_tp_functions_type hook_tp_functions(global_dummy_element, (&fast_tp_new), (&fast_tp_dealloc), False) +try: + from .real_double_element_gsl import RealDoubleElement_gsl +except Exception: + pass +else: + # global_dummy_element is of type RealDoubleElement_gsl, + # so hook the base class now. + hook_tp_functions_type(RealDoubleElement, (&fast_tp_new), (&fast_tp_dealloc), False) + # From here on, calling PY_NEW(RealDoubleElement) actually creates an instance of RealDoubleElement_gsl cdef double_repr(double x): diff --git a/src/sage/rings/real_double_element_gsl.pxd b/src/sage/rings/real_double_element_gsl.pxd new file mode 100644 index 00000000000..4ddc886cdf1 --- /dev/null +++ b/src/sage/rings/real_double_element_gsl.pxd @@ -0,0 +1,7 @@ +from .real_double cimport RealDoubleElement + + +cdef class RealDoubleElement_gsl(RealDoubleElement): + cdef __pow_double(self, double exponent, double sign) + cpdef _pow_(self, other) + cdef _log_base(self, double log_of_base) diff --git a/src/sage/rings/real_double_element_gsl.pyx b/src/sage/rings/real_double_element_gsl.pyx new file mode 100644 index 00000000000..3b446998886 --- /dev/null +++ b/src/sage/rings/real_double_element_gsl.pyx @@ -0,0 +1,789 @@ +r""" +Double Precision Real Numbers, implementation using GSL +""" + +cimport libc.math + +from cysignals.signals cimport sig_on, sig_off + +import sage.rings.complex_double + +from sage.arith.constants cimport * + +from sage.libs.gsl.all cimport * + +gsl_set_error_handler_off() + + +cdef class RealDoubleElement_gsl(RealDoubleElement): + + + def nth_root(self, int n): + """ + Return the `n^{th}` root of ``self``. + + INPUT: + + - ``n`` -- an integer + + OUTPUT: + + The output is a complex double if ``self`` is negative and `n` is even, + otherwise it is a real double. + + EXAMPLES:: + + sage: r = RDF(-125.0); r.nth_root(3) + -5.000000000000001 + sage: r.nth_root(5) + -2.6265278044037674 + sage: RDF(-2).nth_root(5)^5 # rel tol 1e-15 + -2.000000000000001 + sage: RDF(-1).nth_root(5)^5 + -1.0 + sage: RDF(3).nth_root(10)^10 + 2.9999999999999982 + sage: RDF(-1).nth_root(2) + 6.123233995736757e-17 + 1.0*I + sage: RDF(-1).nth_root(4) + 0.7071067811865476 + 0.7071067811865475*I + """ + if n == 0: + return RealDoubleElement(float('nan')) + if self._value < 0: + if GSL_IS_EVEN(n): + return self._complex_double_(sage.rings.complex_double.CDF).nth_root(n) + else: + return - ( (-self) ** (float(1)/n) ) + else: + return self ** (float(1)/n) + + cdef __pow_double(self, double exponent, double sign): + """ + If ``sign == 1`` or ``self >= 0``, return ``self ^ exponent``. + If ``sign == -1`` and ``self < 0``, return ``- abs(self) ^ exponent``. + """ + cdef double v = self._value + if v >= 0: + if v == 1: + return self + elif exponent == 0: + return self._new_c(1.0) + elif v == 0: + if exponent < 0: + raise ZeroDivisionError("0.0 cannot be raised to a negative power") + return self + sign = 1.0 + else: # v < 0 + expmod2 = libc.math.fmod(exponent, 2.0) + if expmod2 == 0.0: + pass + elif expmod2 == 1.0: + sign = -1.0 + else: + raise ValueError("negative number cannot be raised to a fractional power") + v = -v + return self._new_c(sign * gsl_sf_exp(gsl_sf_log(v) * exponent)) + + cpdef _pow_(self, other): + """ + Return ``self`` raised to the real double power ``other``. + + EXAMPLES:: + + sage: a = RDF('1.23456') + sage: a^a + 1.2971114817819216 + + TESTS:: + + sage: RDF(0) ^ RDF(0.5) + 0.0 + sage: RDF(0) ^ (1/2) + 0.0 + sage: RDF(0) ^ RDF(0) + 1.0 + sage: RDF(0) ^ RDF(-1) + Traceback (most recent call last): + ... + ZeroDivisionError: 0.0 cannot be raised to a negative power + sage: RDF(-1) ^ RDF(0) + 1.0 + sage: RDF(-1) ^ RDF(1) + -1.0 + sage: RDF(-1) ^ RDF(0.5) + Traceback (most recent call last): + ... + ValueError: negative number cannot be raised to a fractional power + """ + return self.__pow_double((other)._value, 1) + + cpdef _pow_int(self, n): + """ + Return ``self`` raised to the integer power ``n``. + + TESTS:: + + sage: RDF(1) ^ (2^1000) + 1.0 + sage: RDF(1) ^ (2^1000 + 1) + 1.0 + sage: RDF(1) ^ (-2^1000) + 1.0 + sage: RDF(1) ^ (-2^1000 + 1) + 1.0 + sage: RDF(-1) ^ (2^1000) + 1.0 + sage: RDF(-1) ^ (2^1000 + 1) + -1.0 + sage: RDF(-1) ^ (-2^1000) + 1.0 + sage: RDF(-1) ^ (-2^1000 + 1) + -1.0 + + :: + + sage: base = RDF(1.0000000000000002) + sage: base._pow_int(0) + 1.0 + sage: base._pow_int(1) + 1.0000000000000002 + sage: base._pow_int(2) + 1.0000000000000004 + sage: base._pow_int(3) + 1.0000000000000007 + sage: base._pow_int(2^57) + 78962960182680.42 + sage: base._pow_int(2^57 + 1) + 78962960182680.42 + + :: + + sage: base = RDF(-1.0000000000000002) + sage: base._pow_int(0) + 1.0 + sage: base._pow_int(1) + -1.0000000000000002 + sage: base._pow_int(2) + 1.0000000000000004 + sage: base._pow_int(3) + -1.0000000000000007 + sage: base._pow_int(2^57) + 78962960182680.42 + sage: base._pow_int(2^57 + 1) + -78962960182680.42 + """ + return self.__pow_double(n, -1.0 if (n & 1) else 1.0) + + cdef _pow_long(self, long n): + """ + Compute ``self`` raised to the power ``n``. + + EXAMPLES:: + + sage: RDF('1.23456') ^ 20 + 67.64629770385... + sage: RDF(3) ^ 32 + 1853020188851841.0 + sage: RDF(2)^(-1024) + 5.562684646268003e-309 + + TESTS:: + + sage: base = RDF(1.0000000000000002) + sage: base ^ RDF(2^31) + 1.000000476837272 + sage: base ^ (2^57) + 78962960182680.42 + sage: base ^ RDF(2^57) + 78962960182680.42 + """ + if -2048 <= n <= 2048: + # For small exponents, it is possible that the powering + # is exact either because the base is a power of 2 + # (e.g. 2.0^1000) or because the exact result has few + # significant digits (e.g. 3.0^10). Here, we use the + # square-and-multiply algorithm by GSL. + return self._new_c(gsl_pow_int(self._value, n)) + # If the exponent is sufficiently large in absolute value, the + # result cannot be exact (except if the base is -1.0, 0.0 or + # 1.0 but those cases are handled by __pow_double too). The + # log-and-exp algorithm from __pow_double will be more precise + # than square-and-multiply. + + # We do need to take care of the sign since the conversion + # of n to double might change an odd number to an even number. + return self.__pow_double(n, -1.0 if (n & 1) else 1.0) + + cdef _log_base(self, double log_of_base): + if self._value == 0: + from .real_double import RDF + return RDF(-1)/RDF(0) + elif self._value < 0: + from .real_double import RDF + return RDF.NaN() + sig_on() + a = self._new_c(gsl_sf_log(self._value) / log_of_base) + sig_off() + return a + + def log(self, base=None): + """ + Return the logarithm. + + INPUT: + + - ``base`` -- integer or ``None`` (default). The base of the + logarithm. If ``None`` is specified, the base is `e` (the so-called + natural logarithm). + + OUTPUT: + + The logarithm of ``self``. If ``self`` is positive, a double + floating point number. Infinity if ``self`` is zero. A + imaginary complex floating point number if ``self`` is + negative. + + EXAMPLES:: + + sage: RDF(2).log() + 0.6931471805599453 + sage: RDF(2).log(2) + 1.0 + sage: RDF(2).log(pi) + 0.6055115613982801 + sage: RDF(2).log(10) + 0.30102999566398114 + sage: RDF(2).log(1.5) + 1.7095112913514547 + sage: RDF(0).log() + -infinity + sage: RDF(-1).log() + 3.141592653589793*I + sage: RDF(-1).log(2) # rel tol 1e-15 + 4.532360141827194*I + + TESTS: + + Make sure that we can take the log of small numbers accurately + and the fix doesn't break preexisting values (:trac:`12557`):: + + sage: R = RealField(128) + sage: def check_error(x): + ....: x = RDF(x) + ....: log_RDF = x.log() + ....: log_RR = R(x).log() + ....: diff = R(log_RDF) - log_RR + ....: if abs(diff) < log_RDF.ulp(): + ....: return True + ....: print("logarithm check failed for %s (diff = %s ulp)"% \ + ....: (x, diff/log_RDF.ulp())) + ....: return False + sage: all( check_error(2^x) for x in range(-100,100) ) + True + sage: all( check_error(x) for x in sxrange(0.01, 2.00, 0.01) ) + True + sage: all( check_error(x) for x in sxrange(0.99, 1.01, 0.001) ) + True + sage: RDF(1.000000001).log() + 1.000000082240371e-09 + sage: RDF(1e-17).log() + -39.14394658089878 + sage: RDF(1e-50).log() + -115.12925464970229 + """ + if self < 0: + from sage.rings.complex_double import CDF + return CDF(self).log(base) + if base is None: + return self._log_base(1) + else: + if isinstance(base, RealDoubleElement): + return self._log_base(base._log_base(1)) + else: + return self._log_base(gsl_sf_log(float(base))) + + def log2(self): + """ + Return log to the base 2 of ``self``. + + EXAMPLES:: + + sage: r = RDF(16.0) + sage: r.log2() + 4.0 + + :: + + sage: r = RDF(31.9); r.log2() + 4.9954845188775066 + """ + if self < 0: + from sage.rings.complex_double import CDF + return CDF(self).log(2) + sig_on() + a = self._new_c(gsl_sf_log(self._value) * M_1_LN2) + sig_off() + return a + + + def log10(self): + """ + Return log to the base 10 of ``self``. + + EXAMPLES:: + + sage: r = RDF('16.0'); r.log10() + 1.2041199826559248 + sage: r.log() / RDF(log(10)) + 1.2041199826559246 + sage: r = RDF('39.9'); r.log10() + 1.6009728956867482 + """ + if self < 0: + from sage.rings.complex_double import CDF + return CDF(self).log(10) + sig_on() + a = self._new_c(gsl_sf_log(self._value) * M_1_LN10) + sig_off() + return a + + def logpi(self): + r""" + Return log to the base `\pi` of ``self``. + + EXAMPLES:: + + sage: r = RDF(16); r.logpi() + 2.4220462455931204 + sage: r.log() / RDF(log(pi)) + 2.4220462455931204 + sage: r = RDF('39.9'); r.logpi() + 3.2203023346075152 + """ + if self < 0: + from sage.rings.complex_double import CDF + return CDF(self).log(M_PI) + sig_on() + a = self._new_c(gsl_sf_log(self._value) * M_1_LNPI) + sig_off() + return a + + def exp(self): + r""" + Return `e^\mathtt{self}`. + + EXAMPLES:: + + sage: r = RDF(0.0) + sage: r.exp() + 1.0 + + :: + + sage: r = RDF('32.3') + sage: a = r.exp(); a + 106588847274864.47 + sage: a.log() + 32.3 + + :: + + sage: r = RDF('-32.3') + sage: r.exp() + 9.381844588498685e-15 + + :: + + sage: RDF(1000).exp() + +infinity + """ + sig_on() + a = self._new_c(gsl_sf_exp(self._value)) + sig_off() + return a + + def exp2(self): + """ + Return `2^\mathtt{self}`. + + EXAMPLES:: + + sage: r = RDF(0.0) + sage: r.exp2() + 1.0 + + :: + + sage: r = RDF(32.0) + sage: r.exp2() + 4294967295.9999967 + + :: + + sage: r = RDF(-32.3) + sage: r.exp2() + 1.8911724825302065e-10 + """ + sig_on() + a = self._new_c(gsl_sf_exp(self._value * M_LN2)) + sig_off() + return a + + def exp10(self): + r""" + Return `10^\mathtt{self}`. + + EXAMPLES:: + + sage: r = RDF(0.0) + sage: r.exp10() + 1.0 + + :: + + sage: r = RDF(32.0) + sage: r.exp10() + 1.0000000000000069e+32 + + :: + + sage: r = RDF(-32.3) + sage: r.exp10() + 5.011872336272702e-33 + """ + sig_on() + a = self._new_c(gsl_sf_exp(self._value * M_LN10)) + sig_off() + return a + + def cos(self): + """ + Return the cosine of ``self``. + + EXAMPLES:: + + sage: t=RDF.pi()/2 + sage: t.cos() + 6.123233995736757e-17 + """ + return self._new_c(gsl_sf_cos(self._value)) + + def sin(self): + """ + Return the sine of ``self``. + + EXAMPLES:: + + sage: RDF(2).sin() + 0.9092974268256817 + """ + return self._new_c(gsl_sf_sin(self._value)) + + def dilog(self): + r""" + Return the dilogarithm of ``self``. + + This is defined by the + series `\sum_n x^n/n^2` for `|x| \le 1`. When the absolute + value of ``self`` is greater than 1, the returned value is the + real part of (the analytic continuation to `\CC` of) the + dilogarithm of ``self``. + + EXAMPLES:: + + sage: RDF(1).dilog() # rel tol 1.0e-13 + 1.6449340668482264 + sage: RDF(2).dilog() # rel tol 1.0e-13 + 2.46740110027234 + """ + return self._new_c(gsl_sf_dilog(self._value)) + + def restrict_angle(self): + r""" + Return a number congruent to ``self`` mod `2\pi` that lies in + the interval `(-\pi, \pi]`. + + Specifically, it is the unique `x \in (-\pi, \pi]` such + that ```self`` `= x + 2\pi n` for some `n \in \ZZ`. + + EXAMPLES:: + + sage: RDF(pi).restrict_angle() + 3.141592653589793 + sage: RDF(pi + 1e-10).restrict_angle() + -3.1415926534897936 + sage: RDF(1+10^10*pi).restrict_angle() + 0.9999977606... + """ + return self._new_c(gsl_sf_angle_restrict_symm(self._value)) + + def tan(self): + """ + Return the tangent of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/3 + sage: q.tan() + 1.7320508075688767 + sage: q = RDF.pi()/6 + sage: q.tan() + 0.5773502691896256 + """ + cdef double denom + cos = gsl_sf_cos(self._value) + a = self._new_c(gsl_sf_sin(self._value) / cos) + return a + + def sincos(self): + """ + Return a pair consisting of the sine and cosine of ``self``. + + EXAMPLES:: + + sage: t = RDF.pi()/6 + sage: t.sincos() + (0.49999999999999994, 0.8660254037844387) + """ + return self.sin(), self.cos() + + def hypot(self, other): + r""" + Computes the value `\sqrt{s^2 + o^2}` where `s` is ``self`` and `o` + is ``other`` in such a way as to avoid overflow. + + EXAMPLES:: + + sage: x = RDF(4e300); y = RDF(3e300) + sage: x.hypot(y) + 5e+300 + sage: sqrt(x^2+y^2) # overflow + +infinity + """ + sig_on() + a = self._new_c(gsl_sf_hypot(self._value, float(other))) + sig_off() + return a + + def arccos(self): + """ + Return the inverse cosine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/3 + sage: i = q.cos() + sage: i.arccos() == q + True + """ + return self._new_c(libc.math.acos(self._value)) + + def arcsin(self): + """ + Return the inverse sine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/5 + sage: i = q.sin() + sage: i.arcsin() == q + True + """ + return self._new_c(libc.math.asin(self._value)) + + def arctan(self): + """ + Return the inverse tangent of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/5 + sage: i = q.tan() + sage: i.arctan() == q + True + """ + return self._new_c(libc.math.atan(self._value)) + + + def cosh(self): + """ + Return the hyperbolic cosine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/12 + sage: q.cosh() + 1.0344656400955106 + """ + return self._new_c(gsl_ldexp( gsl_sf_exp(self._value) + gsl_sf_exp(-self._value), -1)) # (e^x + e^-x)/2 + + def sinh(self): + """ + Return the hyperbolic sine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/12 + sage: q.sinh() + 0.26480022760227073 + """ + return self._new_c(gsl_ldexp( gsl_sf_expm1(self._value) - gsl_sf_expm1(-self._value), -1)) # (e^x - e^-x)/2 + + def tanh(self): + """ + Return the hyperbolic tangent of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/12 + sage: q.tanh() + 0.25597778924568454 + """ + return self.sinh() / self.cosh() + + def acosh(self): + """ + Return the hyperbolic inverse cosine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/2 + sage: i = q.cosh(); i + 2.5091784786580567 + sage: abs(i.acosh()-q) < 1e-15 + True + """ + return self._new_c(gsl_acosh(self._value)) + + def arcsinh(self): + """ + Return the hyperbolic inverse sine of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/2 + sage: i = q.sinh(); i + 2.3012989023072947 + sage: abs(i.arcsinh()-q) < 1e-15 + True + """ + return self._new_c(gsl_asinh(self._value)) + + def arctanh(self): + """ + Return the hyperbolic inverse tangent of ``self``. + + EXAMPLES:: + + sage: q = RDF.pi()/2 + sage: i = q.tanh(); i + 0.9171523356672744 + sage: i.arctanh() - q # rel tol 1 + 4.440892098500626e-16 + """ + return self._new_c(gsl_atanh(self._value)) + + def sech(self): + r""" + Return the hyperbolic secant of ``self``. + + EXAMPLES:: + + sage: RDF(pi).sech() + 0.08626673833405443 + sage: CDF(pi).sech() + 0.08626673833405443 + """ + return 1/self.cosh() + + def csch(self): + r""" + Return the hyperbolic cosecant of ``self``. + + EXAMPLES:: + + sage: RDF(pi).csch() + 0.08658953753004694 + sage: CDF(pi).csch() # rel tol 1e-15 + 0.08658953753004696 + """ + return 1/self.sinh() + + def coth(self): + r""" + Return the hyperbolic cotangent of ``self``. + + EXAMPLES:: + + sage: RDF(pi).coth() + 1.003741873197321 + sage: CDF(pi).coth() + 1.0037418731973213 + """ + return self.cosh() / self.sinh() + + def erf(self): + """ + Return the value of the error function on ``self``. + + EXAMPLES:: + + sage: RDF(6).erf() + 1.0 + """ + return self._new_c(gsl_sf_erf(self._value)) + + @classmethod + def _factorial(cls, int n): + """ + Return the factorial of the integer `n` as a real number. + + EXAMPLES:: + + sage: RDF.factorial(100) + 9.332621544394415e+157 + """ + if n < 0: + raise ArithmeticError("n must be nonnegative") + return cls(gsl_sf_fact(n)) + + def gamma(self): + """ + Return the value of the Euler gamma function on ``self``. + + EXAMPLES:: + + sage: RDF(6).gamma() + 120.0 + sage: RDF(1.5).gamma() # rel tol 1e-15 + 0.8862269254527584 + """ + sig_on() + a = self._new_c(gsl_sf_gamma(self._value)) + sig_off() + return a + + def zeta(self): + r""" + Return the Riemann zeta function evaluated at this real number. + + .. NOTE:: + + PARI is vastly more efficient at computing the Riemann zeta + function. See the example below for how to use it. + + EXAMPLES:: + + sage: RDF(2).zeta() # rel tol 1e-15 + 1.6449340668482269 + sage: RDF.pi()^2/6 + 1.6449340668482264 + sage: RDF(-2).zeta() + 0.0 + sage: RDF(1).zeta() + +infinity + """ + if self._value == 1: + return self._new_c(1)/self._new_c(0) + return self._new_c(gsl_sf_zeta(self._value)) From 5c29e6c0d39db73c72f06e738a904d506d240f24 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 15 Oct 2021 19:55:21 -0700 Subject: [PATCH 066/378] src/sage/plot/plot3d/implicit_surface.pyx: Use libc.math.isnan instead of gsl_isnan --- src/sage/plot/plot3d/implicit_surface.pyx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sage/plot/plot3d/implicit_surface.pyx b/src/sage/plot/plot3d/implicit_surface.pyx index 6efc85eb10f..a9212bbed3a 100644 --- a/src/sage/plot/plot3d/implicit_surface.pyx +++ b/src/sage/plot/plot3d/implicit_surface.pyx @@ -88,7 +88,7 @@ from sage.rings.real_double import RDF from sage.plot.misc import setup_for_eval_on_grid from sage.plot.colors import check_color_data -from sage.libs.gsl.math cimport gsl_isnan +from libc.math cimport isnan include "point_c.pxi" @@ -99,9 +99,7 @@ DEFAULT_PLOT_POINTS = 40 cdef double nan = float(RDF('NaN')) cdef inline bint marching_has_edge(double a, double b, double contour, double *f, bint *has_nan): - # XXX Would be nicer to use isnan(), because it's inlined. - # Is it portable enough? - if gsl_isnan(a) or gsl_isnan(b): + if isnan(a) or isnan(b): has_nan[0] = True return False @@ -115,7 +113,7 @@ cdef inline bint marching_has_edge(double a, double b, double contour, double *f # Returns 0 or 1 cdef inline int marching_is_inside(double v, double contour): - return gsl_isnan(v) or v < contour + return isnan(v) or v < contour cdef void interpolate_point_c(point_c *result, double frac, point_c *inputs): result[0].x = inputs[0].x + frac*(inputs[1].x - inputs[0].x) From 13e30ad037326fd816669fc03519ac9ae2ab6a90 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sat, 16 Oct 2021 21:00:02 +0200 Subject: [PATCH 067/378] Implemented transcendental extensions over prime fields --- src/sage/libs/singular/ring.pyx | 27 +++++ src/sage/libs/singular/singular.pyx | 154 ++++++++++++++++++++++++++++ 2 files changed, 181 insertions(+) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index f8cd183bb00..7f6f2d7b22b 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -289,6 +289,33 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: _cf = nInitChar(n_transExt, &trextParam) + if (_cf is NULL): + raise RuntimeError("Failed to allocate _cf ring.") + + _ring = rDefault (_cf ,nvars, _names, nblcks, _order, _block0, _block1, _wvhdl) + + elif isinstance(base_ring, FractionField_generic) and isinstance(base_ring.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base_ring.base().base_ring(), FiniteField_generic): + if not base_ring.base_ring().is_prime_field(): + raise NotImplementedError("Transcental extension are not implemented for non-prime finite fields") + characteristic = int(base_ring.characteristic()) + k = PolynomialRing(base_ring.base_ring(), + names=base_ring.variable_names(), order="lex", implementation="singular") + + ngens = len(k.gens()) + + _ext_names = omAlloc0(ngens*sizeof(char*)) + for i in range(ngens): + _name = str_to_bytes(k._names[i]) + _ext_names[i] = omStrDup(_name) + + _cfr = rDefault( characteristic, ngens, _ext_names ) + rComplete(_cfr, 1) + + trextParam.r = _cfr + + _cf = nInitChar(n_transExt, &trextParam) + + if (_cf is NULL): raise RuntimeError("Failed to allocate _cf ring.") diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index cb8a1b6aad0..226e225bffb 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -424,6 +424,66 @@ cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): return snumer/sdenom +cdef object si2sa_transext_FF(number *n, ring *_ring, object base): + """ + + + """ + + cdef poly *numer + cdef poly *denom + cdef number *c + cdef int e + cdef fraction *frac + cdef object snumer + cdef object sdenom + + cdef ring *cfRing = _ring.cf.extRing + + if _ring.cf.cfIsZero(n,_ring.cf): + return base._zero_element + elif _ring.cf.cfIsOne(n,_ring.cf): + return base._one_element + + snumer = base(0) + sdenom = base(0) + + frac = n + + numer = frac.numerator + denom = frac.denominator + + while numer: + + + + c = p_GetCoeff(numer, cfRing) + coeff = base(cfRing.cf.cfInt(c, cfRing.cf)) + numer.coef = c + for i in range(base.ngens()): + e = p_GetExp(numer, i+1, cfRing) + if e!= 0: + coeff *= base.gen(i)**e + snumer += coeff + numer = pNext(numer) + + if not denom: + sdenom = base(1) + else: + while denom: + c = p_GetCoeff(denom, cfRing) + coeff = base(cfRing.cf.cfInt(c, cfRing.cf)) + denom.coef = c + for i in range(base.ngens()): + e = p_GetExp(denom, i+1, cfRing) + if e!= 0: + coeff *= base.gen(i)**e + sdenom += coeff + denom = pNext(denom) + + return snumer/sdenom + + cdef object si2sa_NF(number *n, ring *_ring, object base): """ Create a sage element of a number field from a singular one. @@ -939,6 +999,94 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): return n1 + +cdef number *sa2si_transext_FF(object elem, ring *_ring): + """ + + + """ + + cdef int i + cdef int j + cdef number *n1 + cdef number *a + cdef number *naCoeff + cdef number *numerator + cdef number *denominator + cdef number *cfnum + cdef number *cfden + cdef number *aux1 + cdef number *aux2 + cdef int ngens + cdef int ex + cdef nMapFunc nMapFuncPtr = NULL; + + if _ring != currRing: + rChangeCurrRing(_ring) + + ngens = elem.parent().ngens() + + nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function + + if (nMapFuncPtr is NULL): + raise RuntimeError("Failed to determine nMapFuncPtr") + + numerdic = elem.numerator().dict() + denomdic = elem.denominator().dict() + + if numerdic and not isinstance(list(numerdic)[0], (tuple, ETuple)): + numerdic = {(k,):b for k,b in numerdic.items()} + + if denomdic and not isinstance(list(denomdic)[0], (tuple, ETuple)): + denomdic = {(k,):b for k,b in denomdic.items()} + + if _ring != currRing: + rChangeCurrRing(_ring) + n1 = _ring.cf.cfInit(0, _ring.cf) + numerator = _ring.cf.cfInit(0, _ring.cf) + for (exponents, coef) in numerdic.items(): + naCoeff = _ring.cf.cfInit(coef, _ring.cf) + for (j, ex) in enumerate(exponents): + a = _ring.cf.cfParameter(j+1, _ring.cf) + for k in range(ex): + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfDelete(&a, _ring.cf) + aux2 = numerator + numerator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) + _ring.cf.cfDelete(&naCoeff, _ring.cf) + _ring.cf.cfDelete(&aux2, _ring.cf) + + if elem.denominator() != 1: + denominator = _ring.cf.cfInit(0, _ring.cf) + + for (exponents, coef) in denomdic.items(): + naCoeff = _ring.cf.cfInit(coef, _ring.cf) + for (j, ex) in enumerate(exponents): + a = _ring.cf.cfParameter(j+1, _ring.cf) + for k in range(ex): + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfDelete(&a, _ring.cf) + aux2 = denominator + denominator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) + _ring.cf.cfDelete(&naCoeff, _ring.cf) + _ring.cf.cfDelete(&aux2, _ring.cf) + + else: + denominator = _ring.cf.cfInit(1, _ring.cf) + + n1 = _ring.cf.cfDiv(numerator, denominator, _ring.cf) + + _ring.cf.cfDelete(&numerator, _ring.cf) + _ring.cf.cfDelete(&denominator, _ring.cf) + _ring.cf.cfDelete(&a, _ring.cf) + + return n1 + + cdef number *sa2si_NF(object elem, ring *_ring): """ Create a singular number from a sage element of a number field. @@ -1190,6 +1338,9 @@ cdef object si2sa(number *n, ring *_ring, object base): elif isinstance(base, FractionField_generic) and isinstance(base.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base.base_ring(), RationalField): return si2sa_transext_QQ(n, _ring, base) + elif isinstance(base, FractionField_generic) and isinstance(base.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(base.base_ring(), FiniteField_prime_modn): + return si2sa_transext_FF(n, _ring, base) + elif isinstance(base, IntegerModRing_generic): if _ring.cf.type == n_unknown: return base(_ring.cf.cfInt(n, _ring.cf)) @@ -1241,6 +1392,9 @@ cdef number *sa2si(Element elem, ring * _ring): elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), RationalField): return sa2si_transext_QQ(elem, _ring) + elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), FiniteField_prime_modn): + return sa2si_transext_FF(elem, _ring) + else: raise ValueError("cannot convert to SINGULAR number") From cb3070fd966e4e3f5a6066876693574682625bac Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 17 Oct 2021 19:57:01 +0200 Subject: [PATCH 068/378] Add documentation for prime fields --- src/sage/libs/singular/ring.pyx | 23 ++++++++++++ src/sage/libs/singular/singular.pyx | 56 +++++++++++++++++++++++++---- 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/src/sage/libs/singular/ring.pyx b/src/sage/libs/singular/ring.pyx index 7f6f2d7b22b..78c96e1fc02 100644 --- a/src/sage/libs/singular/ring.pyx +++ b/src/sage/libs/singular/ring.pyx @@ -133,6 +133,10 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: sage: P. = K[]; P Multivariate Polynomial Ring in x, y over Fraction Field of Multivariate Polynomial Ring in s, t over Rational Field + sage: F = PolynomialRing(FiniteField(7),'a,b').fraction_field() + sage: R. = F[] + sage: R + Multivariate Polynomial Ring in x, y, z over Fraction Field of Multivariate Polynomial Ring in a, b over Finite Field of size 7 TESTS: @@ -144,6 +148,25 @@ cdef ring *singular_ring_new(base_ring, n, names, term_order) except NULL: sage: L = [v for d in (0..4) for v in IntegerVectors(d, 4)] sage: sorted([R.monomial(*e) for e in L]) == sorted([S.monomial(*e) for e in L]) True + + Check that we are using the libsingular backend instead of the pexpect one:: + + sage: F = PolynomialRing(FiniteField(7),'a,b').fraction_field() + sage: R. = F[] + sage: from sage.libs.singular.function import singular_function + sage: sing_print = singular_function('print') + sage: sing_print(R) + 'polynomial ring, over a field, global ordering\n// coefficients: ZZ/7(a, b)\n// number of vars : 3\n// block 1 : ordering dp\n// : names x y z\n// block 2 : ordering C' + + :: + + sage: F = PolynomialRing(QQ, 's,t').fraction_field() + sage: R. = F[] + sage: from sage.libs.singular.function import singular_function + sage: sing_print = singular_function('print') + sage: sing_print(R) + 'polynomial ring, over a field, global ordering\n// coefficients: QQ(s, t)\n// number of vars : 3\n// block 1 : ordering dp\n// : names x y z\n// block 2 : ordering C' + """ cdef long cexponent cdef GFInfo* _param diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 226e225bffb..ca37b9c590d 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -426,7 +426,32 @@ cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): cdef object si2sa_transext_FF(number *n, ring *_ring, object base): """ + Create a sage element of a transcendental extension of a prime field from a + singular one. + + INPUT: + + - ``n`` - a (pointer to) a singular number in a transcendental extension + of the rationals + + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` + + - ``base`` - A sage FractionField + OUTPUT: + + - A sage element of ``base`` + + TESTS:: + + sage: F = PolynomialRing(FiniteField(7),'a,b').fraction_field() + sage: R. = F[] + sage: n = R(5) + sage: n + -2 + sage: type(n) + """ @@ -907,7 +932,6 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): """ - cdef int i cdef int j cdef number *n1 cdef number *a @@ -1002,19 +1026,40 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): cdef number *sa2si_transext_FF(object elem, ring *_ring): """ + Create a singular number from a sage element of a transcendental extension + of a prime field. + INPUT: - """ + - ``elem`` - a sage element of a FractionField of polynomials over the rationals - cdef int i + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + + + OUTPUT: + + - A (pointer to) a singular number + + + TESTS:: + + sage: F = PolynomialRing(FiniteField(7),'a,b').fraction_field() + sage: R. = F[] + sage: n = R(5) + sage: n + n + 3 + sage: Integer(n) + 5 + + + + """ cdef int j cdef number *n1 cdef number *a cdef number *naCoeff cdef number *numerator cdef number *denominator - cdef number *cfnum - cdef number *cfden cdef number *aux1 cdef number *aux2 cdef int ngens @@ -1042,7 +1087,6 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring): if _ring != currRing: rChangeCurrRing(_ring) - n1 = _ring.cf.cfInit(0, _ring.cf) numerator = _ring.cf.cfInit(0, _ring.cf) for (exponents, coef) in numerdic.items(): naCoeff = _ring.cf.cfInit(coef, _ring.cf) From 5555f49c32a1c39141e298bc438983140037681e Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 17 Oct 2021 20:29:45 +0200 Subject: [PATCH 069/378] Fix doctests for prime fields --- src/sage/schemes/plane_conics/con_field.py | 15 ++++++++------- .../plane_conics/con_rational_function_field.py | 13 +++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sage/schemes/plane_conics/con_field.py b/src/sage/schemes/plane_conics/con_field.py index 5ecce3b3168..def754a202f 100644 --- a/src/sage/schemes/plane_conics/con_field.py +++ b/src/sage/schemes/plane_conics/con_field.py @@ -199,7 +199,7 @@ def derivative_matrix(self): sage: P. = GF(2)[] sage: c = Conic([t, 1, t^2, 1, 1, 0]); c - Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) defined by t*x^2 + x*y + y^2 + t^2*x*z + y*z + Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 2 (using GF2X) defined by t*x^2 + x*y + y^2 + (t^2)*x*z + y*z sage: c.is_smooth() True sage: c.derivative_matrix() @@ -340,18 +340,19 @@ def diagonalization(self, names=None): sage: (t,) = K.gens() sage: C = Conic(K, [t/2,0, 1, 2, 0, 3]) sage: C.diagonalization() - (Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by 4*t*x^2 + 2*y^2 + ((3*t + 3)/t)*z^2, + (Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2, Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by 4*t*x^2 + 2*y^2 + ((3*t + 3)/t)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by 4*t*x^2 + 2*y^2 + x*z + 3*z^2 + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 Defn: Defined on coordinates by sending (x : y : z) to - (x + 6/t*z : y : z), + (x - 1/t*z : y : z), Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by 4*t*x^2 + 2*y^2 + x*z + 3*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by 4*t*x^2 + 2*y^2 + ((3*t + 3)/t)*z^2 + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + x*z + 3*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-3*t)*x^2 + 2*y^2 + (3*t + 3)/t*z^2 Defn: Defined on coordinates by sending (x : y : z) to (x + 1/t*z : y : z)) + """ if names is None: names = self.defining_polynomial().parent().variable_names() diff --git a/src/sage/schemes/plane_conics/con_rational_function_field.py b/src/sage/schemes/plane_conics/con_rational_function_field.py index 154201f2cb2..383802d75a8 100644 --- a/src/sage/schemes/plane_conics/con_rational_function_field.py +++ b/src/sage/schemes/plane_conics/con_rational_function_field.py @@ -203,14 +203,15 @@ def has_rational_point(self, point=False, algorithm='default', Traceback (most recent call last): ... TypeError: self (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (5*t^2 + 4)*x^2 + ((6*t^3 + 3*t^2 + 5*t + 5)/(t + 3))*y^2 + ((6*t^6 + 3*t^5 + t^3 + 6*t^2 + 6*t + 2)/(t^4 + t^3 + 4*t^2 + 3*t + 1))*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (5*t^2 + 4)*x^2 + (t^2 + 3*t + 3)*x*y + (5*t^2 + 5)*y^2 + (6*t^2 + 3*t + 2)*x*z + (4*t + 3)*y*z + (4*t^2 + t + 5)*z^2 + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^2 - 3)*x^2 + (-t^3 + 3*t^2 - 2*t - 2)/(t + 3)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^2 - 3)*x^2 + (t^2 + 3*t + 3)*x*y + (-2*t^2 - 2)*y^2 + (-t^2 + 3*t + 2)*x*z + (-3*t + 3)*y*z + (-3*t^2 + t - 2)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - (x + ((2*t + 5)/(t + 3))*y + ((3*t^4 + 2*t^3 + 5*t^2 + 5*t + 3)/(t^4 + t^3 + 4*t^2 + 3*t + 1))*z : y + ((6*t^3 + 6*t^2 + 3*t + 6)/(t^3 + 4*t^2 + 2*t + 2))*z : z)) domain must equal right (=Scheme morphism: - From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (5*t^3 + 6*t^2 + 3*t + 3)*x^2 + (t + 4)*y^2 + (6*t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 + 6*t + 6)*z^2 - To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (5/(t^3 + 4*t^2 + 2*t + 2))*x^2 + (1/(t^3 + 3*t^2 + 5*t + 1))*y^2 + ((6*t^6 + 3*t^5 + t^3 + 6*t^2 + 6*t + 2)/(t^9 + 5*t^8 + t^7 + 6*t^6 + 3*t^5 + 4*t^3 + t^2 + 5*t + 3))*z^2 + (x + (2*t - 2)/(t + 3)*y + (3*t^4 + 2*t^3 - 2*t^2 - 2*t + 3)/(t^4 + t^3 - 3*t^2 + 3*t + 1)*z : y + (-t^3 - t^2 + 3*t - 1)/(t^3 - 3*t^2 + 2*t + 2)*z : z)) domain must equal right (=Scheme morphism: + From: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by (-2*t^3 - t^2 + 3*t + 3)*x^2 + (t - 3)*y^2 + (-t^7 + 2*t^5 + t^4 + 2*t^3 + 3*t^2 - t - 1)*z^2 + To: Projective Conic Curve over Fraction Field of Univariate Polynomial Ring in t over Finite Field of size 7 defined by -2/(t^3 - 3*t^2 + 2*t + 2)*x^2 + 1/(t^3 + 3*t^2 - 2*t + 1)*y^2 + (-t^6 + 3*t^5 + t^3 - t^2 - t + 2)/(t^9 - 2*t^8 + t^7 - t^6 + 3*t^5 - 3*t^3 + t^2 - 2*t + 3)*z^2 Defn: Defined on coordinates by sending (x : y : z) to - ((t^3 + 4*t^2 + 2*t + 2)*x : (t^2 + 5)*y : (t^5 + 4*t^4 + t^2 + 3*t + 3)*z)) codomain + ((t^3 - 3*t^2 + 2*t + 2)*x : (t^2 - 2)*y : (t^5 - 3*t^4 + t^2 + 3*t + 3)*z)) codomain + TESTS:: From 3d5bad2c26444649725142041afc4499ff3dffbc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 17 Oct 2021 22:17:09 -0700 Subject: [PATCH 070/378] Make doctests accept RealDoubleElement and RealDoubleElement_gsl --- src/sage/libs/mpmath/utils.pyx | 2 +- src/sage/misc/functional.py | 2 +- src/sage/symbolic/expression.pyx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/libs/mpmath/utils.pyx b/src/sage/libs/mpmath/utils.pyx index ea5aa54bfc8..ed771bb1958 100644 --- a/src/sage/libs/mpmath/utils.pyx +++ b/src/sage/libs/mpmath/utils.pyx @@ -406,7 +406,7 @@ def call(func, *args, **kwargs): sage: a.call(a.polylog, 2, 1/2, parent=RDF) 0.5822405264650125 sage: type(_) - + Check that :trac:`11885` is fixed:: diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index c1f895c217c..fd8f3ab31bb 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -1538,7 +1538,7 @@ def round(x, ndigits=0): sage: q = round(sqrt(2),5); q 1.41421 sage: type(q) - + sage: q = round(sqrt(2)); q 1 sage: type(q) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 3bb7e6a6fe3..487f6d42605 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -1687,7 +1687,7 @@ cdef class Expression(CommutativeRingElement): sage: SR(CBF(1))._convert({'parent':RDF}) 1.0 sage: type(_.pyobject()) - + """ cdef GEx res = self._gobj.evalf(0, kwds) return new_Expression_from_GEx(self._parent, res) From 46d7eac7c6b2ca798bcaa958043478c31b18b05a Mon Sep 17 00:00:00 2001 From: Kiran Kedlaya Date: Mon, 18 Oct 2021 11:07:21 -0700 Subject: [PATCH 071/378] Change __bool__ in Magma interface --- src/sage/interfaces/magma.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sage/interfaces/magma.py b/src/sage/interfaces/magma.py index 238f2061181..9aed0ea413d 100644 --- a/src/sage/interfaces/magma.py +++ b/src/sage/interfaces/magma.py @@ -373,7 +373,7 @@ def set_seed(self, seed=None): sage: m.set_seed(1) # optional - magma 1 sage: [m.Random(100) for i in range(5)] # optional - magma - [13, 55, 84, 100, 37] + [14, 81, 45, 75, 67] """ if seed is None: seed = self.rand_seed() @@ -2318,7 +2318,7 @@ def _polynomial_(self, R): sage: R. = QQ[] sage: f = magma(x^2 + 2/3*x + 5) # optional - magma sage: f # optional - magma - x^2 + 2/3*x + 5 + t^2 + 2/3*t + 5 sage: f.Type() # optional - magma RngUPolElt sage: f._polynomial_(R) # optional - magma @@ -2626,13 +2626,27 @@ def __bool__(self): True sage: bool(magma(0)) # optional - magma False + + TESTS:: + + Verify that :trac:`32602` is fixed:: + + sage: magma("1 eq 0").bool() # optional - magma + False + sage: magma("1 eq 1").bool() # optional - magma + True + sage: Q. = PolynomialRing(GF(3)) + sage: u = x^6+x^4+2*x^3+2*x+1 + sage: F0 = magma.FunctionField(GF(3)) # optional - magma + sage: bool(F0.1) # optional - magma + True """ try: - return not self.parent()("%s eq 0" % self.name()).bool() + return str(self.parent()("%s eq 0" % self.name())) == "false" except TypeError: - # comparing with 0 didn't work; try comparing with + # comparing with 0 didn't work; try comparing with false try: - return not self.parent()("%s eq false" % self.name()).bool() + return str(self.parent()("%s eq false" % self.name())) == "false" except TypeError: pass return True From ecbcaf963d53e0e0e80822b98c20ec4e22007401 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Mon, 18 Oct 2021 21:42:54 +0200 Subject: [PATCH 072/378] Use cfPower instead of repeated multiplications --- src/sage/libs/singular/singular.pyx | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index ca37b9c590d..6c6c907359c 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -942,6 +942,7 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): cdef number *cfden cdef number *aux1 cdef number *aux2 + cdef number *power cdef int ngens cdef int ex cdef nMapFunc nMapFuncPtr = NULL; @@ -974,16 +975,17 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): cfnum = _ring.cf.cfInitMPZ((numer).value, _ring.cf) denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) - naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + naCoeff = _ring.cf.cfDiv(cfnum, cfden, _ring.cf) _ring.cf.cfDelete(&cfnum, _ring.cf) _ring.cf.cfDelete(&cfden, _ring.cf) for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) - for k in range(ex): - aux1 = naCoeff - naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) - _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfPower(a, ex, &power, _ring.cf) + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, power, _ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) _ring.cf.cfDelete(&a, _ring.cf) + _ring.cf.cfDelete(&power, _ring.cf) aux2 = numerator numerator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) _ring.cf.cfDelete(&aux2, _ring.cf) @@ -996,16 +998,17 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): cfnum = _ring.cf.cfInitMPZ((numer).value, _ring.cf) denom = coef.denominator() cfden = _ring.cf.cfInitMPZ((denom).value, _ring.cf) - naCoeff = _ring.cf.cfDiv(cfnum, cfden , _ring.cf ) + naCoeff = _ring.cf.cfDiv(cfnum, cfden, _ring.cf) _ring.cf.cfDelete(&cfnum, _ring.cf) _ring.cf.cfDelete(&cfden, _ring.cf) for (j, ex) in enumerate(exponents): a = _ring.cf.cfParameter(j+1, _ring.cf) - for k in range(ex): - aux1 = naCoeff - naCoeff = _ring.cf.cfMult(aux1, a ,_ring.cf) - _ring.cf.cfDelete(&aux1, _ring.cf) + _ring.cf.cfPower(a, ex, &power, _ring.cf) + aux1 = naCoeff + naCoeff = _ring.cf.cfMult(aux1, power, _ring.cf) + _ring.cf.cfDelete(&aux1, _ring.cf) _ring.cf.cfDelete(&a, _ring.cf) + _ring.cf.cfDelete(&power, _ring.cf) aux2 = denominator denominator = _ring.cf.cfAdd(aux2, naCoeff,_ring.cf) _ring.cf.cfDelete(&aux2, _ring.cf) From b9b1dba57d85ea7d6f68471024406a939579b5bb Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Mon, 18 Oct 2021 22:36:14 +0200 Subject: [PATCH 073/378] Enable editable mode also for other sage packages --- build/bin/sage-dist-helpers | 5 +++++ build/pkgs/sage_conf/spkg-install | 7 ++++++- build/pkgs/sage_docbuild/spkg-install | 7 ++++++- build/pkgs/sage_setup/spkg-install | 7 ++++++- build/pkgs/sagelib/spkg-install | 2 +- src/doc/en/developer/packaging.rst | 7 +++++++ 6 files changed, 31 insertions(+), 4 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 4a8862d50f6..7bee8527f89 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -246,6 +246,11 @@ sdh_pip_install() { sdh_store_and_pip_install_wheel . } +sdh_pip_editable_install() { + echo "Installing $PKG_NAME (editable mode)" + python3 -m pip install --verbose --no-deps --no-index --no-build-isolation --isolated --editable "$@" +} + sdh_store_wheel() { if [ -n "$SAGE_DESTDIR" ]; then local sudo="" diff --git a/build/pkgs/sage_conf/spkg-install b/build/pkgs/sage_conf/spkg-install index 468970ba085..e572d89f80d 100755 --- a/build/pkgs/sage_conf/spkg-install +++ b/build/pkgs/sage_conf/spkg-install @@ -9,4 +9,9 @@ if [ $? -ne 0 ]; then echo >&2 "Is $SAGE_ROOT the correct SAGE_ROOT?" exit 1 fi -cd src && sdh_pip_install . +cd src +if [ "$SAGE_EDITABLE" = yes ]; then + sdh_pip_editable_install . +else + sdh_pip_install . +fi diff --git a/build/pkgs/sage_docbuild/spkg-install b/build/pkgs/sage_docbuild/spkg-install index ea7a36674d7..1bb66bc4a07 100755 --- a/build/pkgs/sage_docbuild/spkg-install +++ b/build/pkgs/sage_docbuild/spkg-install @@ -9,4 +9,9 @@ if [ $? -ne 0 ]; then echo >&2 "Is $SAGE_ROOT the correct SAGE_ROOT?" exit 1 fi -cd src && sdh_pip_install . +cd src +if [ "$SAGE_EDITABLE" = yes ]; then + sdh_pip_editable_install . +else + sdh_pip_install . +fi diff --git a/build/pkgs/sage_setup/spkg-install b/build/pkgs/sage_setup/spkg-install index ea7a36674d7..1bb66bc4a07 100755 --- a/build/pkgs/sage_setup/spkg-install +++ b/build/pkgs/sage_setup/spkg-install @@ -9,4 +9,9 @@ if [ $? -ne 0 ]; then echo >&2 "Is $SAGE_ROOT the correct SAGE_ROOT?" exit 1 fi -cd src && sdh_pip_install . +cd src +if [ "$SAGE_EDITABLE" = yes ]; then + sdh_pip_editable_install . +else + sdh_pip_install . +fi diff --git a/build/pkgs/sagelib/spkg-install b/build/pkgs/sagelib/spkg-install index 76a306e5762..050af61a140 100755 --- a/build/pkgs/sagelib/spkg-install +++ b/build/pkgs/sagelib/spkg-install @@ -49,7 +49,7 @@ if [ "$SAGE_EDITABLE" = yes ]; then # and renamed the distribution to "sagemath-standard"). There is no clean way to uninstall # them, so we just use rm. (cd "$SITEPACKAGESDIR" && rm -rf sage sage_setup sage-[1-9]*.egg-info sage-[1-9]*.dist-info) - time python3 -m pip install --verbose --no-deps --no-index --no-build-isolation --isolated --editable . || exit 1 + time sdh_pip_editable_install . || exit 1 else # Likewise, we should remove the egg-link that may have been installed previously. (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 498825377c5..122282af80e 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -411,6 +411,13 @@ begin with ``sdh_``, which stands for "Sage-distribution helper". creating a wheel file in ``dist/``, followed by ``sdh_store_and_pip_install_wheel`` (see below). +- ``sdh_pip_editable_install [...]``: The equivalent of running ``pip install -e`` + with the given arguments, as well as additional default arguments used for + installing packages into Sage with pip. The last argument must be + ``.`` to indicate installation from the current directory. + See `pip documentation `_ + for more details concerning editable installs. + - ``sdh_pip_uninstall [...]``: Runs ``pip uninstall`` with the given arguments. If unsuccessful, it displays a warning. From a257621c3b3aa7e4d245a691dffbc67e6e45f08b Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 19 Oct 2021 01:17:35 +0200 Subject: [PATCH 074/378] Add error handling --- build/bin/sage-dist-helpers | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 7bee8527f89..84af795c901 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -248,7 +248,8 @@ sdh_pip_install() { sdh_pip_editable_install() { echo "Installing $PKG_NAME (editable mode)" - python3 -m pip install --verbose --no-deps --no-index --no-build-isolation --isolated --editable "$@" + python3 -m pip install --verbose --no-deps --no-index --no-build-isolation --isolated --editable "$@" || \ + sdh_die "Error installing $PKG_NAME" } sdh_store_wheel() { From edbb85a662d924be547d7dd7f0fa7d92b36b338c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 08:48:26 -0700 Subject: [PATCH 075/378] src/sage/modules/free_module_element.pyx: Use sage.rings.abc --- src/sage/modules/free_module_element.pyx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index de44743651e..2d597a0af3b 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -122,8 +122,7 @@ import sage.rings.abc from sage.rings.ring import is_Ring from sage.rings.infinity import Infinity, AnInfinity from sage.rings.integer_ring import ZZ -from sage.rings.real_double import RDF -from sage.rings.complex_double import CDF +from sage.rings.abc import RealDoubleField, ComplexDoubleField from sage.rings.ring cimport Ring from sage.rings.integer cimport Integer, smallInteger @@ -536,14 +535,16 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): if len(v.shape) != 1: raise TypeError("cannot convert %r-dimensional array to a vector" % len(v.shape)) from .free_module import VectorSpace - if (R is None or R is RDF) and v.dtype.kind == 'f': + if (R is None or isinstance(R, RealDoubleField)) and v.dtype.kind == 'f': + from sage.rings.real_double import RDF V = VectorSpace(RDF, v.shape[0]) from .vector_real_double_dense import Vector_real_double_dense v = Vector_real_double_dense(V, v) if immutable: v.set_immutable() return v - if (R is None or R is CDF) and v.dtype.kind == 'c': + if (R is None or isinstance(R, ComplexDoubleField)) and v.dtype.kind == 'c': + from sage.rings.complex_double import CDF V = VectorSpace(CDF, v.shape[0]) from .vector_complex_double_dense import Vector_complex_double_dense v = Vector_complex_double_dense(V, v) From 1ac5001120d098919793c20ee1f9d9f94aa8426a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 14:51:50 -0700 Subject: [PATCH 076/378] vector: Cache result of isinstance(arg1, (Integer, int, long) --- src/sage/modules/free_module_element.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 2d597a0af3b..1acdc6c3780 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -475,7 +475,8 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): # We first efficiently handle the important special case of the zero vector # over a ring. See trac 11657. # !! PLEASE DO NOT MOVE THIS CODE LOWER IN THIS FUNCTION !! - if arg2 is None and is_Ring(arg0) and (isinstance(arg1, (int, long, Integer))): + arg1_integer = isinstance(arg1, (int, long, Integer)) + if arg2 is None and is_Ring(arg0) and arg1_integer: M = FreeModule(arg0, arg1, bool(sparse)) v = M.zero_vector() if immutable: @@ -499,7 +500,7 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): # consider a possible degree specified in second argument degree = None maxindex = None - if isinstance(arg1, (Integer, int, long)): + if arg1_integer: if arg1 < 0: raise ValueError("cannot specify the degree of a vector as a negative integer (%s)" % arg1) if isinstance(arg2, dict): From 7451f242e427e99938436fcda43d5d564aa0b02e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 14:52:45 -0700 Subject: [PATCH 077/378] vector: Micro-optimization: Use try...except instead of hasattr/call --- src/sage/modules/free_module_element.pyx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 1acdc6c3780..f1497cf0408 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -483,16 +483,24 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): v.set_immutable() return v - # WARNING TO FUTURE OPTIMIZERS: The following two hasattr's take + # The try...except is slightly faster than testing with hasattr first # quite a significant amount of time. - if hasattr(arg0, '_vector_'): - v = arg0._vector_(arg1) + try: + arg0_vector_ = arg0._vector_ + except AttributeError: + pass + else: + v = arg0_vector_(arg1) if immutable: v.set_immutable() return v - if hasattr(arg1, '_vector_'): - v = arg1._vector_(arg0) + try: + arg1_vector_ = arg1._vector_ + except AttributeError: + pass + else: + v = arg1_vector_(arg0) if immutable: v.set_immutable() return v From 50c5f5884797efcdb191a72bc159034acc8db27d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 16:37:38 -0700 Subject: [PATCH 078/378] src/sage/matrix/args.pyx: Move import of RDF, CDF into method --- src/sage/matrix/args.pyx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/args.pyx b/src/sage/matrix/args.pyx index 4d2a114328e..66bde8aa9e0 100644 --- a/src/sage/matrix/args.pyx +++ b/src/sage/matrix/args.pyx @@ -21,8 +21,6 @@ from cysignals.signals cimport sig_check MatrixSpace = None from sage.rings.integer_ring import ZZ -from sage.rings.real_double import RDF -from sage.rings.complex_double import CDF from sage.structure.coerce cimport (coercion_model, is_numpy_type, py_scalar_parent) from sage.structure.element cimport Element, RingElement, Vector @@ -1070,6 +1068,9 @@ cdef class MatrixArgs: raise TypeError('numpy matrix must be either c_contiguous or f_contiguous') from .constructor import matrix + from sage.rings.real_double import RDF + from sage.rings.complex_double import CDF + if 'float32' in str_dtype: m = matrix(RDF, inrows, incols, 0) m._replace_self_with_numpy32(e) From d0818149da70cae9edd907ec4ba33a0b355f7213 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 18:32:42 -0700 Subject: [PATCH 079/378] src/sage/matrix/matrix_misc.py: Move import of PolynomialRing into method --- src/sage/matrix/matrix_misc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix_misc.py b/src/sage/matrix/matrix_misc.py index 72986685c1f..e68ba3ad0bc 100644 --- a/src/sage/matrix/matrix_misc.py +++ b/src/sage/matrix/matrix_misc.py @@ -19,7 +19,6 @@ #***************************************************************************** from sage.categories.fields import Fields -from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing _Fields = Fields() @@ -270,6 +269,8 @@ def permanental_minor_polynomial(A, permanent_only=False, var='t', prec=None): if prec == 0: raise ValueError('the argument `prec` must be a positive integer') + from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing + K = PolynomialRing(A.base_ring(), var) nrows = A.nrows() ncols = A.ncols() From 561bad4d37df97f73adfb40eece19b9caef34318 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 18:34:00 -0700 Subject: [PATCH 080/378] sage.modules, sage.matrix: Use sage.rings.abc more --- src/sage/matrix/matrix2.pyx | 15 +++++++++------ src/sage/modules/free_module.py | 12 +++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 868df0cfab7..92829ac298b 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -90,10 +90,6 @@ from sage.rings.number_field.number_field_base import is_NumberField from sage.rings.integer_ring import ZZ, is_IntegerRing from sage.rings.integer import Integer from sage.rings.rational_field import QQ, is_RationalField -from sage.rings.real_double import RDF -from sage.rings.complex_double import CDF -from sage.rings.real_mpfr import RealField -from sage.rings.complex_mpfr import ComplexField from sage.rings.finite_rings.integer_mod_ring import IntegerModRing import sage.rings.abc from sage.arith.numerical_approx cimport digits_to_bits @@ -1545,6 +1541,8 @@ cdef class Matrix(Matrix1): ring = self.base_ring() if algorithm is None: # Choose algorithm depending on base ring + from sage.rings.real_mpfr import RealField + from sage.rings.complex_mpfr import ComplexField is_complex = ComplexField(2).has_coerce_map_from(ring) if is_complex: if ring.is_exact(): @@ -15024,6 +15022,8 @@ cdef class Matrix(Matrix1): sage: matrix(CDF, 2, 2, sparse=True).norm(1) 0.0 """ + from sage.rings.real_double import RDF + from sage.rings.complex_double import CDF if self._nrows == 0 or self._ncols == 0: return RDF(0) @@ -15128,14 +15128,17 @@ cdef class Matrix(Matrix1): sage: _ = A.n() """ + from sage.rings.real_mpfr import RealField + from sage.rings.complex_mpfr import ComplexField + if prec is None: prec = digits_to_bits(digits) try: - return self.change_ring(sage.rings.real_mpfr.RealField(prec)) + return self.change_ring(RealField(prec)) except (TypeError, ValueError): # try to return a complex result - return self.change_ring(sage.rings.complex_mpfr.ComplexField(prec)) + return self.change_ring(ComplexField(prec)) def plot(self, *args, **kwds): """ diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index ba5e1eb6ccb..1fc72b8bf1d 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -242,10 +242,10 @@ def create_object(self, version, key): # raise TypeError, "The base_ring must be a commutative ring." try: - if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): + if not sparse and isinstance(base_ring, sage.rings.abc.RealDoubleField): return RealDoubleVectorSpace_class(rank) - elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class): + elif not sparse and isinstance(base_ring, sage.rings.abc.ComplexDoubleField): return ComplexDoubleVectorSpace_class(rank) elif base_ring.is_field(): @@ -7454,12 +7454,10 @@ def element_class(R, is_sparse): elif isinstance(R, sage.rings.abc.SymbolicRing) and not is_sparse: import sage.modules.vector_symbolic_dense return sage.modules.vector_symbolic_dense.Vector_symbolic_dense + if is_sparse: + return free_module_element.FreeModuleElement_generic_sparse else: - if is_sparse: - return free_module_element.FreeModuleElement_generic_sparse - else: - return free_module_element.FreeModuleElement_generic_dense - raise NotImplementedError + return free_module_element.FreeModuleElement_generic_dense @richcmp_method class EchelonMatrixKey(object): From e072aa145b3a227404383945e0297a7796cfc508 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 19:08:25 -0700 Subject: [PATCH 081/378] sage.structure, sage.rings, sage.matrix: Use sage.rings.abc for IntegerModRing --- src/sage/matrix/matrix2.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 92829ac298b..6e5ba5bc6a4 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -90,7 +90,6 @@ from sage.rings.number_field.number_field_base import is_NumberField from sage.rings.integer_ring import ZZ, is_IntegerRing from sage.rings.integer import Integer from sage.rings.rational_field import QQ, is_RationalField -from sage.rings.finite_rings.integer_mod_ring import IntegerModRing import sage.rings.abc from sage.arith.numerical_approx cimport digits_to_bits from copy import copy From b34974098babf7ec0111b6c15ca028c6e02fe178 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 19:15:38 -0700 Subject: [PATCH 082/378] src/sage/modules/free_module.py: Use sage.rings.abc.Order --- src/sage/modules/free_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 1fc72b8bf1d..48f08845176 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -2932,7 +2932,7 @@ def index_in(self, other): a = sage.matrix.matrix_space.MatrixSpace(self.base_field(), self.rank())(C).determinant() if sage.rings.integer_ring.is_IntegerRing(self.base_ring()): return a.abs() - elif isinstance(self.base_ring, sage.rings.number_field.order.Order): + elif isinstance(self.base_ring, sage.rings.abc.Order): return self.base_ring().ideal(a).norm() else: raise NotImplementedError From f2f00e593de0a4d6144b45fb45dda432fbd39b19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 23:36:46 -0700 Subject: [PATCH 083/378] src/sage/matrix/matrix_space.py: More try..except for imports --- src/sage/matrix/matrix_space.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 99e57196f3f..1ab9feacdf4 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -243,9 +243,18 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): if R.order() < matrix_modn_dense_double.MAX_MODULUS: return matrix_modn_dense_double.Matrix_modn_dense_double - if sage.rings.number_field.number_field.is_CyclotomicField(R): - from . import matrix_cyclo_dense - return matrix_cyclo_dense.Matrix_cyclo_dense + try: + from sage.rings.number_field.number_field import is_CyclotomicField + except ImportError: + pass + else: + if is_CyclotomicField(R): + try: + from . import matrix_cyclo_dense + except ImportError: + pass + else: + return matrix_cyclo_dense.Matrix_cyclo_dense from sage.symbolic.ring import SR if R is SR: From 40f01d5ec0fe3ef434b2ca5f64d41288a333de97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 23:37:08 -0700 Subject: [PATCH 084/378] src/sage/modules/free_module.py: More try..except for imports --- src/sage/modules/free_module.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 48f08845176..9e002cfbea9 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -7426,9 +7426,7 @@ def element_class(R, is_sparse): sage: sage.modules.free_module.element_class(P, is_sparse=False) """ - import sage.modules.vector_real_double_dense - import sage.modules.vector_complex_double_dense - + import sage.rings.integer_ring if sage.rings.integer_ring.is_IntegerRing(R) and not is_sparse: from .vector_integer_dense import Vector_integer_dense return Vector_integer_dense @@ -7445,9 +7443,19 @@ def element_class(R, is_sparse): else: return free_module_element.FreeModuleElement_generic_dense elif isinstance(R, sage.rings.abc.RealDoubleField) and not is_sparse: - return sage.modules.vector_real_double_dense.Vector_real_double_dense + try: + from sage.modules.vector_real_double_dense import Vector_real_double_dense + except ImportError: + pass + else: + return Vector_real_double_dense elif isinstance(R, sage.rings.abc.ComplexDoubleField) and not is_sparse: - return sage.modules.vector_complex_double_dense.Vector_complex_double_dense + try: + from sage.modules.vector_complex_double_dense import Vector_complex_double_dense + except ImportError: + pass + else: + return Vector_complex_double_dense elif isinstance(R, sage.rings.abc.CallableSymbolicExpressionRing) and not is_sparse: import sage.modules.vector_callable_symbolic_dense return sage.modules.vector_callable_symbolic_dense.Vector_callable_symbolic_dense From 65a5ce396d9e91963913bea0b4e18bd3fa53a49b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 29 Sep 2021 15:09:32 -0700 Subject: [PATCH 085/378] src/sage/modules/free_module_element.pyx: Do not fail if numpy cannot be imported --- src/sage/modules/free_module_element.pyx | 50 +++++++++++++----------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index f1497cf0408..e9137f78613 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -539,29 +539,33 @@ def vector(arg0, arg1=None, arg2=None, sparse=None, immutable=False): v = arg0 R = None - from numpy import ndarray - if isinstance(v, ndarray): - if len(v.shape) != 1: - raise TypeError("cannot convert %r-dimensional array to a vector" % len(v.shape)) - from .free_module import VectorSpace - if (R is None or isinstance(R, RealDoubleField)) and v.dtype.kind == 'f': - from sage.rings.real_double import RDF - V = VectorSpace(RDF, v.shape[0]) - from .vector_real_double_dense import Vector_real_double_dense - v = Vector_real_double_dense(V, v) - if immutable: - v.set_immutable() - return v - if (R is None or isinstance(R, ComplexDoubleField)) and v.dtype.kind == 'c': - from sage.rings.complex_double import CDF - V = VectorSpace(CDF, v.shape[0]) - from .vector_complex_double_dense import Vector_complex_double_dense - v = Vector_complex_double_dense(V, v) - if immutable: - v.set_immutable() - return v - # Use slower conversion via list - v = list(v) + try: + from numpy import ndarray + except ImportError: + pass + else: + if isinstance(v, ndarray): + if len(v.shape) != 1: + raise TypeError("cannot convert %r-dimensional array to a vector" % len(v.shape)) + from .free_module import VectorSpace + if (R is None or isinstance(R, RealDoubleField)) and v.dtype.kind == 'f': + from sage.rings.real_double import RDF + V = VectorSpace(RDF, v.shape[0]) + from .vector_real_double_dense import Vector_real_double_dense + v = Vector_real_double_dense(V, v) + if immutable: + v.set_immutable() + return v + if (R is None or isinstance(R, ComplexDoubleField)) and v.dtype.kind == 'c': + from sage.rings.complex_double import CDF + V = VectorSpace(CDF, v.shape[0]) + from .vector_complex_double_dense import Vector_complex_double_dense + v = Vector_complex_double_dense(V, v) + if immutable: + v.set_immutable() + return v + # Use slower conversion via list + v = list(v) if isinstance(v, dict): if degree is None: From b325232e3a6e9f25851a0c3fba74c93d6860e7f2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 22:27:17 -0700 Subject: [PATCH 086/378] Matrix.gram_schmidt: Use sage.rings.abc --- src/sage/matrix/matrix2.pyx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 6e5ba5bc6a4..74d8aefb90b 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -10719,10 +10719,8 @@ cdef class Matrix(Matrix1): sage: mu*G == A True """ - import sage.rings.real_double - import sage.rings.complex_double R = self.base_ring() - if R in [sage.rings.real_double.RDF, sage.rings.complex_double.CDF]: + if instance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): Q, R = self.transpose().QR() m = R.nrows(); n = R.ncols() if m > n: From 69e89687a41b8659cff8b5a4692094fda689e003 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 22:30:16 -0700 Subject: [PATCH 087/378] Matrix.gram_schmidt: Use sage.rings.abc (fixup) --- src/sage/matrix/matrix2.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 74d8aefb90b..7c73f4717ec 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -10720,7 +10720,7 @@ cdef class Matrix(Matrix1): True """ R = self.base_ring() - if instance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): + if isinstance(R, (sage.rings.abc.RealDoubleField, sage.rings.abc.ComplexDoubleField)): Q, R = self.transpose().QR() m = R.nrows(); n = R.ncols() if m > n: From 6644879d4af587e06c261dfe7601f0ca71134bc7 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Wed, 13 Oct 2021 13:44:06 +0900 Subject: [PATCH 088/378] Place get converted to a prime divisor --- src/sage/coding/ag_code.py | 102 +++++++++++++++---------- src/sage/coding/ag_code_decoders.pyx | 22 +++--- src/sage/rings/function_field/place.py | 15 +++- 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/src/sage/coding/ag_code.py b/src/sage/coding/ag_code.py index 9b12c412f18..72bf5c37d5f 100644 --- a/src/sage/coding/ag_code.py +++ b/src/sage/coding/ag_code.py @@ -8,8 +8,8 @@ EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -72,6 +72,7 @@ from sage.modules.free_module_element import vector from sage.matrix.constructor import matrix from sage.matrix.matrix_space import MatrixSpace +from sage.rings.function_field.place import FunctionFieldPlace from .linear_code import (AbstractLinearCode, LinearCodeGeneratorMatrixEncoder, @@ -97,8 +98,8 @@ def base_function_field(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -123,10 +124,12 @@ class EvaluationAGCode(AGCode): - ``G`` -- a divisor whose support is disjoint from ``pls`` + If ``G`` is a place, then it is regarded as a prime divisor. + EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -135,6 +138,10 @@ class EvaluationAGCode(AGCode): sage: G = 5*Q sage: codes.EvaluationAGCode(pls, G) [8, 5] evaluation AG code over GF(4) + + sage: G = F.get_place(5) + sage: codes.EvaluationAGCode(pls, G) + [8, 5] evaluation AG code over GF(4) """ _registered_encoders = {} _registered_decoders = {} @@ -145,8 +152,8 @@ def __init__(self, pls, G): TESTS:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -156,6 +163,9 @@ def __init__(self, pls, G): sage: code = codes.EvaluationAGCode(pls, G) sage: TestSuite(code).run() """ + if issubclass(type(G), FunctionFieldPlace): + G = G.divisor() # place is converted to a prime divisor + F = G.parent().function_field() K = F.constant_base_field() n = len(pls) @@ -197,8 +207,8 @@ def __eq__(self, other): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -221,8 +231,8 @@ def __hash__(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -240,8 +250,8 @@ def _repr_(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -259,8 +269,8 @@ def _latex_(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -279,8 +289,8 @@ def basis_functions(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -302,8 +312,8 @@ def generator_matrix(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -325,8 +335,8 @@ def designed_distance(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -353,17 +363,24 @@ class DifferentialAGCode(AGCode): - ``G`` -- a divisor whose support is disjoint from ``pls`` + If ``G`` is a place, then it is regarded as a prime divisor. + EXAMPLES:: - sage: F. = GF(4) - sage: A2. = AffineSpace(F, 2) - sage: C = A2.curve(y^3 + y - x^4) + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) + sage: C = A.curve(y^3 + y - x^4) sage: Q = C.places_at_infinity()[0] sage: O = C([0,0]).place() sage: pls = [p for p in C.places() if p not in [O, Q]] sage: G = -O + 3*Q sage: codes.DifferentialAGCode(pls, -O + Q) [3, 2] differential AG code over GF(4) + + sage: F = C.function_field() + sage: G = F.get_place(1) + sage: codes.DifferentialAGCode(pls, G) + [3, 1] differential AG code over GF(4) """ _registered_encoders = {} _registered_decoders = {} @@ -374,8 +391,8 @@ def __init__(self, pls, G): TESTS:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -384,6 +401,9 @@ def __init__(self, pls, G): sage: code = codes.DifferentialAGCode(pls, 3*Q) sage: TestSuite(code).run() """ + if issubclass(type(G), FunctionFieldPlace): + G = G.divisor() # place is converted to a prime divisor + F = G.parent().function_field() K = F.constant_base_field() n = len(pls) @@ -424,8 +444,8 @@ def __eq__(self, other): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -452,8 +472,8 @@ def __hash__(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -471,8 +491,8 @@ def _repr_(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -490,8 +510,8 @@ def _latex_(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -510,8 +530,8 @@ def basis_differentials(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -533,8 +553,8 @@ def generator_matrix(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() @@ -558,8 +578,8 @@ def designed_distance(self): EXAMPLES:: - sage: F. = GF(4) - sage: P. = AffineSpace(F, 2); + sage: k. = GF(4) + sage: A. = AffineSpace(k, 2) sage: C = Curve(y^2 + y - x^3) sage: F = C.function_field() sage: pls = F.places() diff --git a/src/sage/coding/ag_code_decoders.pyx b/src/sage/coding/ag_code_decoders.pyx index 4a9771f221b..8d28e242030 100644 --- a/src/sage/coding/ag_code_decoders.pyx +++ b/src/sage/coding/ag_code_decoders.pyx @@ -19,27 +19,27 @@ EXAMPLES:: sage: pls.remove(O) sage: G = -O + 18*Q sage: code = codes.EvaluationAGCode(pls, G) # long time - sage: code # long time + sage: code # long time [26, 15] evaluation AG code over GF(9) - sage: decoder = code.decoder('K') # long time - sage: tau = decoder.decoding_radius() # long time - sage: tau # long time + sage: decoder = code.decoder('K') # long time + sage: tau = decoder.decoding_radius() # long time + sage: tau # long time 4 The ``decoder`` is now ready for correcting vectors received from a noisy channel:: sage: channel = channels.StaticErrorRateChannel(code.ambient_space(), tau) # long time - sage: message_space = decoder.message_space() # long time - sage: message = message_space.random_element() # long time - sage: encoder = decoder.connected_encoder() # long time - sage: sent_codeword = encoder.encode(message) # long time - sage: received_vector = channel(sent_codeword) # long time - sage: (received_vector - sent_codeword).hamming_weight() # long time + sage: message_space = decoder.message_space() # long time + sage: message = message_space.random_element() # long time + sage: encoder = decoder.connected_encoder() # long time + sage: sent_codeword = encoder.encode(message) # long time + sage: received_vector = channel(sent_codeword) # long time + sage: (received_vector - sent_codeword).hamming_weight() # long time 4 sage: decoder.decode_to_code(received_vector) == sent_codeword # long time True - sage: decoder.decode_to_message(received_vector) == message # long time + sage: decoder.decode_to_message(received_vector) == message # long time True AUTHORS: diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 43abc67a6fb..3173eee1cbf 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -81,7 +81,7 @@ class FunctionFieldPlace(Element): INPUT: - - ``field`` -- function field + - ``parent`` -- place set of a function field - ``prime`` -- prime ideal associated with the place @@ -1188,3 +1188,16 @@ def _an_element_(self): break return p + def function_field(self): + """ + Return the function field to which this place set belongs. + + EXAMPLES:: + + sage: K.=FunctionField(GF(2)); _.=K[] + sage: L.=K.extension(Y^3+x+x^3*Y) + sage: PS = L.place_set() + sage: PS.function_field() == L + True + """ + return self._field From 50a4554dd05e50e5f11609504ce6eba0e93e34a5 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 14 Oct 2021 14:39:01 +0900 Subject: [PATCH 089/378] Fix typos --- src/sage/rings/function_field/place.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/function_field/place.py b/src/sage/rings/function_field/place.py index 3173eee1cbf..4b8c9d6f588 100644 --- a/src/sage/rings/function_field/place.py +++ b/src/sage/rings/function_field/place.py @@ -1194,8 +1194,8 @@ def function_field(self): EXAMPLES:: - sage: K.=FunctionField(GF(2)); _.=K[] - sage: L.=K.extension(Y^3+x+x^3*Y) + sage: K. = FunctionField(GF(2)); _. = K[] + sage: L. = K.extension(Y^3 + x + x^3*Y) sage: PS = L.place_set() sage: PS.function_field() == L True From 16a74e2f7e35fc918c46836b2e70032765962538 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 18 Oct 2021 23:03:38 -0700 Subject: [PATCH 090/378] For isinstance tests, import Expression from sage.structure.element --- src/sage/arith/misc.py | 4 ++-- src/sage/matrix/matrix0.pyx | 2 +- src/sage/matrix/matrix_integer_dense.pyx | 2 +- src/sage/numerical/optimize.py | 6 +++--- src/sage/rings/asymptotic/asymptotic_ring.py | 2 +- src/sage/rings/complex_arb.pyx | 2 +- src/sage/rings/finite_rings/integer_mod.pyx | 2 +- src/sage/rings/polynomial/laurent_polynomial_ring.py | 4 ++-- src/sage/sets/real_set.py | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 9a2aa40819d..256801c893b 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -4848,7 +4848,7 @@ def falling_factorial(x, a): - Jaap Spies (2006-03-05) """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression x = py_scalar_to_element(x) a = py_scalar_to_element(a) if (isinstance(a, Integer) or @@ -4942,7 +4942,7 @@ def rising_factorial(x, a): - Jaap Spies (2006-03-05) """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression x = py_scalar_to_element(x) a = py_scalar_to_element(a) if (isinstance(a, Integer) or diff --git a/src/sage/matrix/matrix0.pyx b/src/sage/matrix/matrix0.pyx index bf0b0bff73c..50b38a67534 100644 --- a/src/sage/matrix/matrix0.pyx +++ b/src/sage/matrix/matrix0.pyx @@ -5835,7 +5835,7 @@ cdef class Matrix(sage.structure.element.Matrix): [ 2*k + 2 -2*k - 1] [ 2*k + 1 -2*k] """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if not self.is_square(): raise ArithmeticError("self must be a square matrix") diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index c9dcecdef47..4415e5047bf 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -963,7 +963,7 @@ cdef class Matrix_integer_dense(Matrix_dense): try: n = Integer(n) except TypeError: - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if isinstance(n, Expression): from sage.matrix.matrix2 import _matrix_power_symbolic return _matrix_power_symbolic(self, n) diff --git a/src/sage/numerical/optimize.py b/src/sage/numerical/optimize.py index 255e958c2d0..d5677955984 100644 --- a/src/sage/numerical/optimize.py +++ b/src/sage/numerical/optimize.py @@ -384,7 +384,7 @@ def minimize(func, x0, gradient=None, hessian=None, algorithm="default", sage: minimize(rosen, [.1,.3,.4], gradient=rosen_der, algorithm="bfgs") # abs tol 1e-6 (1.0, 1.0, 1.0) """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression from sage.ext.fast_callable import fast_callable import numpy from scipy import optimize @@ -505,7 +505,7 @@ def minimize_constrained(func,cons,x0,gradient=None,algorithm='default', **args) sage: minimize_constrained(f, c, [100, 300]) (805.985..., 1005.985...) """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression from sage.ext.fast_callable import fast_callable import numpy from scipy import optimize @@ -751,7 +751,7 @@ def find_fit(data, model, initial_guess = None, parameters = None, variables = N if data.ndim != 2: raise ValueError("data has to be a two dimensional table of floating point numbers") - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if isinstance(model, Expression): if variables is None: diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index f7e3d0c235e..0ecaff62f65 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -1684,7 +1684,7 @@ def __pow__(self, exponent, precision=None): else: return self.__pow_number__(exponent, precision=precision) - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if isinstance(exponent, Expression) and exponent.is_constant(): return self.__pow_number__(exponent, precision=precision) diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index 4e09e548f0a..b18359ca151 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -650,7 +650,7 @@ class ComplexBallField(UniqueRepresentation, sage.rings.abc.ComplexBallField): # this is not implemented via an _acb_() method, because such a # conversion method would also be called by things like # CBF(re_expr, im_expr). - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if isinstance(x, Expression): # Parse the expression. Despite the method name, the result # will be a complex ball. diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index ab92c9a8ecb..91b8d57e552 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -380,7 +380,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): try: z = integer_ring.Z(value) except (TypeError, ValueError): - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if isinstance(value, Expression): value = value.pyobject() else: diff --git a/src/sage/rings/polynomial/laurent_polynomial_ring.py b/src/sage/rings/polynomial/laurent_polynomial_ring.py index 3ecdb534370..b0fdb43016d 100644 --- a/src/sage/rings/polynomial/laurent_polynomial_ring.py +++ b/src/sage/rings/polynomial/laurent_polynomial_ring.py @@ -973,7 +973,7 @@ def _element_constructor_(self, x): ... TypeError: fraction must have unit denominator """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression from sage.rings.fraction_field_element import FractionFieldElement if isinstance(x, Expression): return x.laurent_polynomial(ring=self) @@ -1169,7 +1169,7 @@ def _element_constructor_(self, x, mon=None): sage: R(sum(P.gens()), (-1,-1,-1)) y^-1*z^-1 + x^-1*z^-1 + x^-1*y^-1 """ - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if mon is not None: return self.element_class(self, x, mon) diff --git a/src/sage/sets/real_set.py b/src/sage/sets/real_set.py index fca8d3e179b..0cf6f27fc28 100644 --- a/src/sage/sets/real_set.py +++ b/src/sage/sets/real_set.py @@ -1103,7 +1103,7 @@ def __classcall__(cls, *args, **kwds): if kwds: raise TypeError(f'unless manifold keywords {manifold_keywords} are given, RealSet constructors take no keyword arguments') - from sage.symbolic.expression import Expression + from sage.structure.element import Expression if len(args) == 1 and isinstance(args[0], RealSet): return args[0] # common optimization intervals = [] From e13b958b802ae5e88b2a3b49bcb90a42b13e472d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Oct 2021 10:30:08 -0700 Subject: [PATCH 091/378] src/sage/plot: Import Expression from sage.structure.element --- src/sage/plot/plot.py | 2 +- src/sage/plot/point.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/plot/plot.py b/src/sage/plot/plot.py index 2f08cb2b994..7bec1ca4dce 100644 --- a/src/sage/plot/plot.py +++ b/src/sage/plot/plot.py @@ -580,7 +580,7 @@ def f(x): return (x-3)*(x-5)*(x-7)+40 from math import sin, cos, pi, log, exp #for polar_plot and log scaling from sage.ext.fast_eval import fast_float, is_fast_float -from sage.symbolic.expression import Expression +from sage.structure.element import Expression from sage.misc.decorators import options from .graphics import Graphics diff --git a/src/sage/plot/point.py b/src/sage/plot/point.py index cf8297cc84c..61ee092ac94 100644 --- a/src/sage/plot/point.py +++ b/src/sage/plot/point.py @@ -475,7 +475,7 @@ def point2d(points, **options): """ from sage.plot.plot import xydata_from_point_list from sage.plot.all import Graphics - from sage.symbolic.expression import Expression + from sage.structure.element import Expression # points could be a single number if isinstance(points, numbers.Complex): From 82ea84cfad2c81080f51bfa03255dcf1362c4488 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Oct 2021 23:44:28 -0700 Subject: [PATCH 092/378] src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py: Use integer division instead of floor(.../...) --- .../endPN_automorphism_group.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index e5ef59acf59..f820d893503 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -39,7 +39,7 @@ from sage.sets.set import Set from sage.combinat.permutation import Arrangements from sage.parallel.use_fork import p_iter_fork -from sage.functions.other import floor + def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, iso_type=False): r""" @@ -2213,8 +2213,8 @@ def find_conjugations_arrangement(tuples): # and check linear independence in parallel if len(all_subsets) > num_cpus: for i in range(num_cpus): - start = floor(len(all_subsets)*i/num_cpus) - end = floor(len(all_subsets)*(i+1)/num_cpus) + start = (len(all_subsets) * i) // num_cpus + end = (len(all_subsets) * (i+1)) // num_cpus tuples = all_subsets[start:end] parallel_data.append(([tuples], {})) @@ -2242,8 +2242,8 @@ def find_conjugations_arrangement(tuples): all_arrangements += list(product(*subset_arrangements)) parallel_data = [] for i in range(num_cpus): - start = floor(len(all_arrangements)*i/num_cpus) - end = floor(len(all_arrangements)*(i+1)/num_cpus) + start = (len(all_arrangements) * i) // num_cpus + end = (len(all_arrangements) * (i+1)) // num_cpus tuples = all_arrangements[start:end] parallel_data.append(([tuples], {})) X = p_iter_fork(num_cpus) @@ -2350,8 +2350,8 @@ def find_conjugations_arrangement(tuples): # and check linear independence in parallel if len(all_subsets) > num_cpus: for i in range(num_cpus): - start = floor(len(all_subsets)*i/num_cpus) - end = floor(len(all_subsets)*(i+1)/num_cpus) + start = (len(all_subsets) * i) // num_cpus + end = (len(all_subsets) * (i+1)) // num_cpus tuples = all_subsets[start:end] parallel_data.append(([tuples], {})) @@ -2380,8 +2380,8 @@ def find_conjugations_arrangement(tuples): all_arrangements += list(product(*subset_arrangements)) parallel_data = [] for i in range(num_cpus): - start = floor(len(all_arrangements)*i/num_cpus) - end = floor(len(all_arrangements)*(i+1)/num_cpus) + start = (len(all_arrangements) * i) // num_cpus + end = (len(all_arrangements) * (i+1)) // num_cpus tuples = all_arrangements[start:end] parallel_data.append(([tuples], {})) X = p_iter_fork(num_cpus) From 1b876e41ec68201bf1d1b60461e9ff8a3780b004 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 18:58:02 -0700 Subject: [PATCH 093/378] sage.arith.misc.integer_trun: New, move here from sage.combinat.crystals --- src/sage/arith/misc.py | 18 +++++++++++++++++ src/sage/combinat/crystals/tensor_product.py | 21 +------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/sage/arith/misc.py b/src/sage/arith/misc.py index 9a2aa40819d..273055ba387 100644 --- a/src/sage/arith/misc.py +++ b/src/sage/arith/misc.py @@ -5031,6 +5031,24 @@ def integer_floor(x): raise NotImplementedError("computation of floor of %s not implemented"%x) +def integer_trunc(i): + """ + Truncate to the integer closer to zero + + EXAMPLES:: + + sage: from sage.arith.misc import integer_trunc as trunc + sage: trunc(-3/2), trunc(-1), trunc(-1/2), trunc(0), trunc(1/2), trunc(1), trunc(3/2) + (-1, -1, 0, 0, 0, 1, 1) + sage: isinstance(trunc(3/2), Integer) + True + """ + if i >= 0: + return integer_floor(i) + else: + return integer_ceil(i) + + def two_squares(n): """ Write the integer `n` as a sum of two integer squares if possible; diff --git a/src/sage/combinat/crystals/tensor_product.py b/src/sage/combinat/crystals/tensor_product.py index 9df369573f8..4b8ee8480d8 100644 --- a/src/sage/combinat/crystals/tensor_product.py +++ b/src/sage/combinat/crystals/tensor_product.py @@ -52,27 +52,8 @@ from sage.misc.flatten import flatten from sage.structure.element import get_coercion_model from sage.rings.semirings.non_negative_integer_semiring import NN +from sage.arith.misc import integer_trunc as trunc -############################################################################## -# Until trunc gets implemented in sage.function.other - -from sage.functions.other import floor, ceil -def trunc(i): - """ - Truncates to the integer closer to zero - - EXAMPLES:: - - sage: from sage.combinat.crystals.tensor_product import trunc - sage: trunc(-3/2), trunc(-1), trunc(-1/2), trunc(0), trunc(1/2), trunc(1), trunc(3/2) - (-1, -1, 0, 0, 0, 1, 1) - sage: isinstance(trunc(3/2), Integer) - True - """ - if i>= 0: - return floor(i) - else: - return ceil(i) ############################################################################## # Support classes From 8305ac34dd41816e8482a656e67756a345f30bb4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 15:12:22 -0700 Subject: [PATCH 094/378] sage.geometry.polyhedron: Remove use of sage.functions --- src/sage/geometry/polyhedron/backend_normaliz.py | 2 +- src/sage/geometry/polyhedron/base.py | 13 ++++++------- .../polyhedron/combinatorial_polyhedron/base.pyx | 4 ++-- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index d1f30e2d31f..58af1b3059c 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1538,7 +1538,7 @@ def _volume_normaliz(self, measure='euclidean'): from sage.rings.infinity import infinity return infinity - from sage.functions.other import factorial + from sage.arith.misc import factorial return self._volume_normaliz('induced_lattice') / factorial(self.dim()) else: diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index c07d3ccfe3f..81f8e630e2a 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -40,7 +40,7 @@ from sage.misc.misc_c import prod from sage.misc.randstate import current_randstate from sage.misc.superseded import deprecated_function_alias - +y from sage.rings.integer_ring import ZZ from sage.rings.qqbar import AA from sage.rings.rational_field import QQ @@ -48,10 +48,9 @@ from sage.modules.free_module_element import vector from sage.modules.vector_space_morphism import linear_transformation from sage.matrix.constructor import matrix -from sage.functions.other import floor, ceil -from sage.misc.functional import sqrt -from sage.groups.matrix_gps.finitely_generated import MatrixGroup -from sage.graphs.graph import Graph +from sage.arith.misc import integer_floor as floor +from sage.arith.misc import integer_ceil as ceil +lazy_import('sage.groups.matrix_gps.finitely_generated', 'MatrixGroup') from sage.geometry.convex_set import ConvexSet_closed, AffineHullProjectionData from .constructor import Polyhedron @@ -3418,7 +3417,7 @@ def radius(self): sage: p.radius() 2 """ - return sqrt(self.radius_square()) + return self.radius_square().sqrt() def is_inscribed(self, certificate=False): """ @@ -8999,7 +8998,7 @@ def integrate(self, function, measure='ambient', **kwds): Adet = AA.coerce(Adet) except TypeError: pass - return I / sqrt(Adet) + return I / Adet.sqrt() else: raise ValueError('unknown measure "{}"'.format(measure)) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 524933a01a8..c63b8a943bd 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -1854,7 +1854,7 @@ cdef class CombinatorialPolyhedron(SageObject): if self.is_simplex(): return self.dim() + 1 else: - from sage.functions.other import binomial + from sage.arith.misc import binomial k = 1 while self.f_vector()[k+1] == binomial(self.n_vertices(), k + 1): k += 1 @@ -1904,7 +1904,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: C.is_neighborly(k=2) True """ - from sage.functions.other import binomial + from sage.arith.misc import binomial if k is None: k = self.dim() // 2 return all(self.f_vector()[i+1] == binomial(self.n_vertices(), i + 1) From 00f5615f14bf34dc82b377a2c6b7cd4a32fc0e3b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 19:08:02 -0700 Subject: [PATCH 095/378] src/sage/graphs/hyperbolicity.pyx: Remove unused import --- src/sage/graphs/hyperbolicity.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/graphs/hyperbolicity.pyx b/src/sage/graphs/hyperbolicity.pyx index 1f479774b7e..44e33930181 100644 --- a/src/sage/graphs/hyperbolicity.pyx +++ b/src/sage/graphs/hyperbolicity.pyx @@ -158,7 +158,6 @@ from sage.graphs.distances_all_pairs cimport c_distances_all_pairs from sage.arith.all import binomial from sage.rings.integer_ring import ZZ from sage.rings.real_mpfr import RR -from sage.functions.other import floor from sage.data_structures.bitset import Bitset from sage.graphs.base.static_sparse_graph cimport short_digraph from sage.graphs.base.static_sparse_graph cimport init_short_digraph From 27b44b9df1de6b0ebbe83eadde4ceba60a096c45 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 18 Oct 2021 22:19:17 -0700 Subject: [PATCH 096/378] src/sage/modular/pollack_stevens/dist.pyx: Remove unused import --- src/sage/modular/pollack_stevens/dist.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/modular/pollack_stevens/dist.pyx b/src/sage/modular/pollack_stevens/dist.pyx index 65942454937..b9165153621 100644 --- a/src/sage/modular/pollack_stevens/dist.pyx +++ b/src/sage/modular/pollack_stevens/dist.pyx @@ -39,7 +39,6 @@ from sage.matrix.matrix cimport Matrix from sage.matrix.matrix_space import MatrixSpace from sage.matrix.constructor import matrix from sage.misc.prandom import random -from sage.functions.other import floor from sage.structure.element cimport RingElement, Element import operator from sage.rings.padics.padic_generic import pAdicGeneric From 7f1d021ee896adb823e20a34367333a2031b943e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 18 Oct 2021 22:19:36 -0700 Subject: [PATCH 097/378] src/sage/quadratic_forms/ternary.pyx: Remove unused import --- src/sage/quadratic_forms/ternary.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/quadratic_forms/ternary.pyx b/src/sage/quadratic_forms/ternary.pyx index 63b59b82525..80405d61158 100644 --- a/src/sage/quadratic_forms/ternary.pyx +++ b/src/sage/quadratic_forms/ternary.pyx @@ -19,7 +19,6 @@ from sage.arith.all import inverse_mod, xgcd, gcd from sage.quadratic_forms.extras import extend_to_primitive from sage.rings.finite_rings.integer_mod import mod from sage.misc.prandom import randint -from sage.functions.other import ceil, floor def red_mfact(a,b): From d5cfe2a94a61a066cf0fbab4eb1cedd7a62e8886 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 18 Oct 2021 22:20:19 -0700 Subject: [PATCH 098/378] src/sage/combinat/crystals/tensor_product_element.pyx: Remove unused import --- src/sage/combinat/crystals/tensor_product_element.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/combinat/crystals/tensor_product_element.pyx b/src/sage/combinat/crystals/tensor_product_element.pyx index ed3e688ee56..8a6f7043491 100644 --- a/src/sage/combinat/crystals/tensor_product_element.pyx +++ b/src/sage/combinat/crystals/tensor_product_element.pyx @@ -34,7 +34,6 @@ from cpython.object cimport Py_LT, Py_LE, Py_EQ, Py_NE, Py_GT, Py_GE from sage.structure.parent cimport Parent from sage.misc.cachefunc import cached_method, cached_in_parent_method -from sage.functions.other import ceil from sage.combinat.tableau import Tableau from sage.rings.integer_ring import ZZ From d825aa8bdcd7c6ef1ae2d9254940921457448829 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 19:10:35 -0700 Subject: [PATCH 099/378] src/sage/combinat/crystals/littelmann_path.py: Use integer_floor instead of sage.functions.other.floor --- src/sage/combinat/crystals/littelmann_path.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/crystals/littelmann_path.py b/src/sage/combinat/crystals/littelmann_path.py index 4efbef4a0c3..04cddcf7278 100644 --- a/src/sage/combinat/crystals/littelmann_path.py +++ b/src/sage/combinat/crystals/littelmann_path.py @@ -40,7 +40,7 @@ from sage.rings.integer import Integer from sage.rings.rational_field import QQ from sage.combinat.root_system.root_system import RootSystem -from sage.functions.other import floor +from sage.arith.misc import integer_floor as floor from sage.misc.latex import latex From 9c35213ad90d917f46d5875616c3bdc7320da411 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 19:11:01 -0700 Subject: [PATCH 100/378] src/sage/combinat/diagram_algebras.py: Use integer_floor, integer_ceil instead of importing from sage.functions --- src/sage/combinat/diagram_algebras.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/combinat/diagram_algebras.py b/src/sage/combinat/diagram_algebras.py index 17a9f85bc5f..ea5303bf1bc 100644 --- a/src/sage/combinat/diagram_algebras.py +++ b/src/sage/combinat/diagram_algebras.py @@ -43,7 +43,8 @@ from sage.misc.misc_c import prod from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.functions.other import floor, ceil +from sage.arith.misc import integer_floor as floor +from sage.arith.misc import integer_ceil as ceil import itertools From 57551d338a8bc8d105fbdc5cff8bc6e8b42d8608 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 19:11:16 -0700 Subject: [PATCH 101/378] src/sage/graphs/generic_graph.py: Use integer_floor instead of sage.functions.other.floor --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 33f06c06dda..1a1ff3f292d 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -9272,7 +9272,7 @@ def _ford_fulkerson(self, s, t, use_edge_labels=False, integer=False, value_only 0 """ from sage.graphs.digraph import DiGraph - from sage.functions.other import floor + from sage.arith.misc import integer_floor as floor # Whether we should consider the edges labeled if use_edge_labels: From eea4077172a7f76e4cf9a08236d64571fb1b1840 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 14:06:10 -0700 Subject: [PATCH 102/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx: Mark doctests using combinatorial polytopes # optional - sage.combinat --- .../combinatorial_face.pyx | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 91d8878cfb4..1212516a340 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -242,15 +242,15 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(6) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(dimension=3, dual=False) - sage: face = next(it) - sage: face.__repr__() + sage: P = polytopes.permutahedron(6) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(dimension=3, dual=False) # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: face.__repr__() # optional - sage.combinat 'A 3-dimensional face of a 5-dimensional combinatorial polyhedron' - sage: it = C.face_iter(dimension=3, dual=True) - sage: face = next(it) - sage: face.__repr__() + sage: it = C.face_iter(dimension=3, dual=True) # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: face.__repr__() # optional - sage.combinat 'A 3-dimensional face of a 5-dimensional combinatorial polyhedron' """ return "A {}-dimensional face of a {}-dimensional combinatorial polyhedron"\ @@ -483,16 +483,16 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.associahedron(['A', 3]) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter() - sage: face = next(it) - sage: face.dimension() + sage: P = polytopes.associahedron(['A', 3]) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter() # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: face.dimension() # optional - sage.combinat 2 ``dim`` is an alias:: - sage: face.dim() + sage: face.dim() # optional - sage.combinat 2 """ if self._dual: @@ -527,19 +527,19 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(dimension=2) - sage: face = next(it) - sage: face.ambient_Vrepresentation() + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(dimension=2) # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: face.ambient_Vrepresentation() # optional - sage.combinat (A vertex at (1, 3, 2, 5, 4), A vertex at (2, 3, 1, 5, 4), A vertex at (3, 1, 2, 5, 4), A vertex at (3, 2, 1, 5, 4), A vertex at (2, 1, 3, 5, 4), A vertex at (1, 2, 3, 5, 4)) - sage: face = next(it) - sage: face.ambient_Vrepresentation() + sage: face = next(it) # optional - sage.combinat + sage: face.ambient_Vrepresentation() # optional - sage.combinat (A vertex at (2, 1, 4, 5, 3), A vertex at (3, 2, 4, 5, 1), A vertex at (3, 1, 4, 5, 2), @@ -591,13 +591,13 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(dimension=2) - sage: face = next(it) - sage: next(it).ambient_V_indices() + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(dimension=2) # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: next(it).ambient_V_indices() # optional - sage.combinat (32, 91, 92, 93, 94, 95) - sage: next(it).ambient_V_indices() + sage: next(it).ambient_V_indices() # optional - sage.combinat (32, 89, 90, 94) sage: C = CombinatorialPolyhedron([[0,1,2],[0,1,3],[0,2,3],[1,2,3]]) @@ -677,7 +677,7 @@ cdef class CombinatorialFace(SageObject): r""" Return the length of the :meth:`CombinatorialFace.ambient_V_indices`. - Might be faster than then using ``len``. + Might be faster than using ``len``. EXAMPLES:: @@ -714,14 +714,14 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(2) - sage: next(it).ambient_Hrepresentation() + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(2) # optional - sage.combinta + sage: next(it).ambient_Hrepresentation() # optional - sage.combinat (An inequality (1, 1, 1, 0, 0) x - 6 >= 0, An inequality (0, 0, 0, -1, 0) x + 5 >= 0, An equation (1, 1, 1, 1, 1) x - 15 == 0) - sage: next(it).ambient_Hrepresentation() + sage: next(it).ambient_Hrepresentation() # optional - sage.combinat (An inequality (0, 0, -1, -1, 0) x + 9 >= 0, An inequality (0, 0, 0, -1, 0) x + 5 >= 0, An equation (1, 1, 1, 1, 1) x - 15 == 0) @@ -774,21 +774,21 @@ cdef class CombinatorialFace(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(2) - sage: face = next(it) - sage: face.ambient_H_indices(add_equations=False) + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(2) # optional - sage.combinat + sage: face = next(it) # optional - sage.combinat + sage: face.ambient_H_indices(add_equations=False) # optional - sage.combinat (28, 29) - sage: face2 = next(it) - sage: face2.ambient_H_indices(add_equations=False) + sage: face2 = next(it) # optional - sage.combinat + sage: face2.ambient_H_indices(add_equations=False) # optional - sage.combinat (25, 29) Add the indices of the equation:: - sage: face.ambient_H_indices(add_equations=True) + sage: face.ambient_H_indices(add_equations=True) # optional - sage.combinat (28, 29, 30) - sage: face2.ambient_H_indices(add_equations=True) + sage: face2.ambient_H_indices(add_equations=True) # optional - sage.combinat (25, 29, 30) Another example:: @@ -894,13 +894,13 @@ cdef class CombinatorialFace(SageObject): Specifying whether to count the equations or not:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter(2) - sage: f = next(it) - sage: f.n_ambient_Hrepresentation(add_equations=True) + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter(2) # optional - sage.combinat + sage: f = next(it) # optional - sage.combinat + sage: f.n_ambient_Hrepresentation(add_equations=True) # optional - sage.combinat 3 - sage: f.n_ambient_Hrepresentation(add_equations=False) + sage: f.n_ambient_Hrepresentation(add_equations=False) # optional - sage.combinat 2 TESTS:: From 7094aab3a63895f412490294b36949b93d6c83d3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 18:40:41 -0700 Subject: [PATCH 103/378] sage.geometry.polyedron.combinatorial_polyhedron: Mark more doctests # optional - sage.combinat --- .../combinatorial_face.pyx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 1212516a340..a7affd611f7 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -22,9 +22,9 @@ Obtain a face from a face lattice index: sage: P = polytopes.simplex(2) sage: C = CombinatorialPolyhedron(P) - sage: sorted(C.face_lattice()._elements) + sage: sorted(C.face_lattice()._elements) # optional - sage.combinat [0, 1, 2, 3, 4, 5, 6, 7] - sage: face = C.face_by_face_lattice_index(0); face + sage: face = C.face_by_face_lattice_index(0); face # optional - sage.combinat A -1-dimensional face of a 2-dimensional combinatorial polyhedron Obtain further information regarding a face:: @@ -95,7 +95,7 @@ cdef class CombinatorialFace(SageObject): Obtain a combinatorial face from an index of the face lattice:: - sage: F = C.face_lattice() + sage: F = C.face_lattice() # optional - sage.combinat sage: F._elements[3] 34 sage: C.face_by_face_lattice_index(29) @@ -300,15 +300,15 @@ cdef class CombinatorialFace(SageObject): TESTS:: - sage: P = polytopes.permutahedron(5) - sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() - sage: G = F.relabel(C.face_by_face_lattice_index) + sage: P = polytopes.permutahedron(5) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: F = C.face_lattice() # optional - sage.combinat + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat sage: P = polytopes.cyclic_polytope(4,10) sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() - sage: G = F.relabel(C.face_by_face_lattice_index) + sage: F = C.face_lattice() # optional - sage.combinat + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat """ return self._hash_index @@ -331,7 +331,7 @@ cdef class CombinatorialFace(SageObject): sage: F2 = C.face_by_face_lattice_index(1) sage: F1 < F2 True - sage: for i,j in Combinations(range(28), 2): + sage: for i,j in Combinations(range(28), 2): # optional - sage.combinat ....: F1 = C.face_by_face_lattice_index(i) ....: F2 = C.face_by_face_lattice_index(j) ....: if F1.dim() != F2.dim(): @@ -343,7 +343,7 @@ cdef class CombinatorialFace(SageObject): sage: F2 = C.face_by_face_lattice_index(1) sage: F1 < F2 True - sage: for i,j in Combinations(range(28), 2): + sage: for i,j in Combinations(range(28), 2): # optional - sage.combinat ....: F1 = C.face_by_face_lattice_index(i) ....: F2 = C.face_by_face_lattice_index(j) ....: if F1.dim() != F2.dim(): @@ -948,7 +948,7 @@ cdef class CombinatorialFace(SageObject): sage: F.f_vector() (1, 5, 10, 10, 5, 1) sage: F_alt = polytopes.cyclic_polytope(4,5).combinatorial_polyhedron() - sage: F_alt.vertex_facet_graph().is_isomorphic(F.vertex_facet_graph()) + sage: F_alt.vertex_facet_graph().is_isomorphic(F.vertex_facet_graph()) # optional - sage.graphs True Obtaining the quotient:: From 7ff2f74c37f2a29da62521a64abc7789fdc2a327 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 20:03:05 -0700 Subject: [PATCH 104/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx: Some more # optional --- .../combinatorial_polyhedron/base.pyx | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 524933a01a8..bf03f279552 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -50,14 +50,14 @@ Obtaining edges and ridges:: Vertex-graph and facet-graph:: - sage: C.vertex_graph() + sage: C.vertex_graph() # optional - sage.graphs Graph on 16 vertices - sage: C.facet_graph() + sage: C.facet_graph() # optional - sage.graphs Graph on 8 vertices Face lattice:: - sage: C.face_lattice() + sage: C.face_lattice() # optional - sage.combinat Finite lattice containing 82 elements Face iterator:: @@ -2628,12 +2628,12 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() + sage: F = C.face_lattice() # optional - sage.combinat sage: def f(i): ....: return (i, C._face_lattice_dimension(i)) ....: - sage: G = F.relabel(f) - sage: set(G._elements) + sage: G = F.relabel(f) # optional - sage.combinat + sage: set(G._elements) # optional - sage.combinat {(0, -1), (1, 0), (2, 0), @@ -2684,13 +2684,13 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = polytopes.cube() sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() - sage: F + sage: F = C.face_lattice() # optional - sage.combinat + sage: F # optional - sage.combinat Finite lattice containing 28 elements - sage: G = F.relabel(C.face_by_face_lattice_index) - sage: G.level_sets()[0] + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat + sage: G.level_sets()[0] # optional - sage.combinat [A -1-dimensional face of a 3-dimensional combinatorial polyhedron] - sage: G.level_sets()[3] + sage: G.level_sets()[3] # optional - sage.combinat [A 2-dimensional face of a 3-dimensional combinatorial polyhedron, A 2-dimensional face of a 3-dimensional combinatorial polyhedron, A 2-dimensional face of a 3-dimensional combinatorial polyhedron, @@ -2700,9 +2700,9 @@ cdef class CombinatorialPolyhedron(SageObject): sage: P = Polyhedron(rays=[[0,1], [1,0]]) sage: C = CombinatorialPolyhedron(P) - sage: F = C.face_lattice() - sage: G = F.relabel(C.face_by_face_lattice_index) - sage: G._elements + sage: F = C.face_lattice() # optional - sage.combinat + sage: G = F.relabel(C.face_by_face_lattice_index) # optional - sage.combinat + sage: G._elements # optional - sage.combinat (A -1-dimensional face of a 2-dimensional combinatorial polyhedron, A 0-dimensional face of a 2-dimensional combinatorial polyhedron, A 1-dimensional face of a 2-dimensional combinatorial polyhedron, @@ -2710,8 +2710,8 @@ cdef class CombinatorialPolyhedron(SageObject): A 2-dimensional face of a 2-dimensional combinatorial polyhedron) sage: def f(i): return C.face_by_face_lattice_index(i).ambient_V_indices() - sage: G = F.relabel(f) - sage: G._elements + sage: G = F.relabel(f) # optional - sage.combinat + sage: G._elements # optional - sage.combinat ((), (0,), (0, 1), (0, 2), (0, 1, 2)) """ self._record_all_faces() # Initialize ``_all_faces``, if not done yet. @@ -3058,7 +3058,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: D.f_vector() (1, 6, 12, 8, 1) sage: D1 = P.polar().combinatorial_polyhedron() - sage: D1.face_lattice().is_isomorphic(D.face_lattice()) + sage: D1.face_lattice().is_isomorphic(D.face_lattice()) # optional - sage.combinat True Polar is an alias to be consistent with :class:`~sage.geometry.polyhedron.base.Polyhedron_base`:: From 6baf055da18d2fa0a4767a8fdff6cdd13d8e40f0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 20:53:21 -0700 Subject: [PATCH 105/378] src/sage/geometry/polyhedron/base.py: Some more # optional --- src/sage/geometry/polyhedron/base.py | 95 ++++++++++++++-------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index e2e6772defb..9b06b7fd995 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -11092,71 +11092,72 @@ def affine_hull_projection(self, More examples with the ``orthonormal`` parameter:: - sage: P = polytopes.permutahedron(3); P + sage: P = polytopes.permutahedron(3); P # optional - sage.combinat # optional - sage.rings.number_field A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 6 vertices - sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection().faces(1)]) == {1, sqrt(AA(2))} + sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection().faces(1)]) == {1, sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field True - sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection(orthonormal=True, extend=True).faces(1)]) == {sqrt(AA(2))} + sage: set([F.as_polyhedron().affine_hull_projection(orthonormal=True, extend=True).volume() for F in P.affine_hull_projection(orthonormal=True, extend=True).faces(1)]) == {sqrt(AA(2))} # optional - sage.combinat # optional - sage.rings.number_field True - sage: D = polytopes.dodecahedron() - sage: F = D.faces(2)[0].as_polyhedron() - sage: F.affine_hull_projection(orthogonal=True) + + sage: D = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: F = D.faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: F.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field A 2-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^2 defined as the convex hull of 5 vertices - sage: F.affine_hull_projection(orthonormal=True, extend=True) + sage: F.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field A 2-dimensional polyhedron in AA^2 defined as the convex hull of 5 vertices - sage: K. = QuadraticField(2) - sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]) - sage: K. = QuadraticField(2) - sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]); P + + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: P = Polyhedron([2*[K.zero()],2*[sqrt2]]); P # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^2 defined as the convex hull of 2 vertices - sage: P.vertices() + sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt2, sqrt2)) - sage: A = P.affine_hull_projection(orthonormal=True); A + sage: A = P.affine_hull_projection(orthonormal=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt2 with defining polynomial x^2 - 2 with sqrt2 = 1.414213562373095?)^1 defined as the convex hull of 2 vertices - sage: A.vertices() + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2)) - sage: K. = QuadraticField(3) - sage: P = Polyhedron([2*[K.zero()],2*[sqrt3]]); P + + sage: K. = QuadraticField(3) # optional - sage.rings.number_field + sage: P = Polyhedron([2*[K.zero()],2*[sqrt3]]); P # optional - sage.rings.number_field A 1-dimensional polyhedron in (Number Field in sqrt3 with defining polynomial x^2 - 3 with sqrt3 = 1.732050807568878?)^2 defined as the convex hull of 2 vertices - sage: P.vertices() + sage: P.vertices() # optional - sage.rings.number_field (A vertex at (0, 0), A vertex at (sqrt3, sqrt3)) - sage: A = P.affine_hull_projection(orthonormal=True) + sage: A = P.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: A = P.affine_hull_projection(orthonormal=True, extend=True); A + sage: A = P.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices - sage: A.vertices() + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (0), A vertex at (2.449489742783178?)) - sage: sqrt(6).n() + sage: sqrt(6).n() # optional - sage.rings.number_field 2.44948974278318 The affine hull is combinatorially equivalent to the input:: - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection()) + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection()) # optional - sage.rings.number_field True - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthogonal=True)) + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthogonal=True)) # optional - sage.rings.number_field True - sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthonormal=True, extend=True)) + sage: P.is_combinatorially_isomorphic(P.affine_hull_projection(orthonormal=True, extend=True)) # optional - sage.rings.number_field True The ``orthonormal=True`` parameter preserves volumes; it provides an isometric copy of the polyhedron:: - sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() - sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) - sage: _, c= P.is_inscribed(certificate=True) + sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: _, c= P.is_inscribed(certificate=True) # optional - sage.rings.number_field sage: c (0.4721359549995794?, 0.6498393924658126?) - sage: circumradius = (c-vector(P.vertices()[0])).norm() - sage: p = polytopes.regular_polygon(5) - sage: p.volume() + sage: circumradius = (c-vector(P.vertices()[0])).norm() # optional - sage.rings.number_field + sage: p = polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: p.volume() # optional - sage.rings.number_field 2.377641290737884? - sage: P.volume() + sage: P.volume() # optional - sage.rings.number_field 1.53406271079097? - sage: p.volume()*circumradius^2 + sage: p.volume()*circumradius^2 # optional - sage.rings.number_field 1.534062710790965? - sage: P.volume() == p.volume()*circumradius^2 + sage: P.volume() == p.volume()*circumradius^2 # optional - sage.rings.number_field True One can also use ``orthogonal`` parameter to calculate volumes; @@ -11164,28 +11165,28 @@ def affine_hull_projection(self, by the square root of the determinant of the linear part of the affine transformation times its transpose:: - sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() - sage: Pnormal = Pentagon.affine_hull_projection(orthonormal=True, extend=True) - sage: Pgonal = Pentagon.affine_hull_projection(orthogonal=True) - sage: A, b = Pentagon.affine_hull_projection(orthogonal=True, as_affine_map=True) - sage: Adet = (A.matrix().transpose()*A.matrix()).det() - sage: Pnormal.volume() + sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field + sage: Pnormal = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field + sage: Pgonal = Pentagon.affine_hull_projection(orthogonal=True) # optional - sage.rings.number_field + sage: A, b = Pentagon.affine_hull_projection(orthogonal=True, as_affine_map=True) # optional - sage.rings.number_field + sage: Adet = (A.matrix().transpose()*A.matrix()).det() # optional - sage.rings.number_field + sage: Pnormal.volume() # optional - sage.rings.number_field 1.53406271079097? - sage: Pgonal.volume()/Adet.sqrt(extend=True) + sage: Pgonal.volume()/Adet.sqrt(extend=True) # optional - sage.rings.number_field -80*(55*sqrt(5) - 123)/sqrt(-6368*sqrt(5) + 14240) - sage: Pgonal.volume()/AA(Adet).sqrt().n(digits=20) + sage: Pgonal.volume()/AA(Adet).sqrt().n(digits=20) # optional - sage.rings.number_field 1.5340627107909646813 - sage: AA(Pgonal.volume()^2) == (Pnormal.volume()^2)*AA(Adet) + sage: AA(Pgonal.volume()^2) == (Pnormal.volume()^2)*AA(Adet) # optional - sage.rings.number_field True Another example with ``as_affine_map=True``:: - sage: P = polytopes.permutahedron(4) - sage: A, b = P.affine_hull_projection(orthonormal=True, as_affine_map=True, extend=True) - sage: Q = P.affine_hull_projection(orthonormal=True, extend=True) - sage: Q.center() + sage: P = polytopes.permutahedron(4) # optional - sage.combinat # optional - sage.rings.number_field + sage: A, b = P.affine_hull_projection(orthonormal=True, as_affine_map=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field + sage: Q = P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.combinat # optional - sage.rings.number_field + sage: Q.center() # optional - sage.combinat # optional - sage.rings.number_field (0.7071067811865475?, 1.224744871391589?, 1.732050807568878?) - sage: A(P.center()) + b == Q.center() + sage: A(P.center()) + b == Q.center() # optional - sage.combinat # optional - sage.rings.number_field True For unbounded, non full-dimensional polyhedra, the ``orthogonal=True`` and ``orthonormal=True`` From 7c73a01725955891f83164e828ce44910976c9f5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 4 Oct 2021 22:52:36 -0700 Subject: [PATCH 106/378] src/sage/geometry/polyhedron/base.py: Some more # optional --- src/sage/geometry/polyhedron/base.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 9b06b7fd995..720d6367cb6 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -4979,7 +4979,7 @@ def join(self, other): sage: C = polytopes.hypercube(5) sage: S = Polyhedron([[1]]) - sage: C.join(S).is_combinatorially_isomorphic(C.pyramid()) + sage: C.join(S).is_combinatorially_isomorphic(C.pyramid()) # optional - sage.graphs True sage: P = polytopes.simplex(backend='cdd') @@ -6064,11 +6064,11 @@ def wedge(self, face, width=1): EXAMPLES:: - sage: P_4 = polytopes.regular_polygon(4) - sage: W1 = P_4.wedge(P_4.faces(1)[0]); W1 + sage: P_4 = polytopes.regular_polygon(4) # optional - sage.rings.number_field + sage: W1 = P_4.wedge(P_4.faces(1)[0]); W1 # optional - sage.rings.number_field A 3-dimensional polyhedron in AA^3 defined as the convex hull of 6 vertices - sage: triangular_prism = polytopes.regular_polygon(3).prism() - sage: W1.is_combinatorially_isomorphic(triangular_prism) + sage: triangular_prism = polytopes.regular_polygon(3).prism() # optional - sage.rings.number_field + sage: W1.is_combinatorially_isomorphic(triangular_prism) # optional - sage.graphs # optional - sage.rings.number_field True sage: Q = polytopes.hypersimplex(4,2) @@ -6100,9 +6100,9 @@ def wedge(self, face, width=1): A vertex at (0, 1, 1, 0, -1)) sage: C_3_7 = polytopes.cyclic_polytope(3,7) - sage: P_6 = polytopes.regular_polygon(6) - sage: W4 = P_6.wedge(P_6.faces(1)[0]) - sage: W4.is_combinatorially_isomorphic(C_3_7.polar()) + sage: P_6 = polytopes.regular_polygon(6) # optional - sage.rings.number_field + sage: W4 = P_6.wedge(P_6.faces(1)[0]) # optional - sage.rings.number_field + sage: W4.is_combinatorially_isomorphic(C_3_7.polar()) # optional - sage.graphs # optional - sage.rings.number_field True REFERENCES: @@ -10795,7 +10795,7 @@ def _affine_hull_projection(self, *, sage: P1 = Polyhedron(vertices=([[-1, 1], [0, -1], [0, 0], [-1, -1]])) sage: P2 = Polyhedron(vertices=[[1, 1], [1, -1], [0, -1], [0, 0]]) sage: P = P1.intersection(P2) - sage: A, b = P.affine_hull_projection(as_affine_map=True, orthonormal=True, extend=True) + sage: A, b = P.affine_hull_projection(as_affine_map=True, orthonormal=True, extend=True) # optional - sage.rings.number_field sage: Polyhedron([(2,3,4)]).affine_hull_projection() A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex @@ -10806,7 +10806,7 @@ def _affine_hull_projection(self, *, 'field' sage: P = Polyhedron(vertices=[[0,0], [1,0]], backend='field') - sage: P.affine_hull_projection(orthogonal=True, orthonormal=True, extend=True).backend() + sage: P.affine_hull_projection(orthogonal=True, orthonormal=True, extend=True).backend() # optional - sage.rings.number_field 'field' Check that :trac:`29116` is fixed:: @@ -10826,7 +10826,7 @@ def _affine_hull_projection(self, *, Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: P.affine_hull_projection(orthonormal=True, extend=True) + sage: P.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field A 4-dimensional polyhedron in AA^4 defined as the convex hull of 6 vertices """ result = AffineHullProjectionData() @@ -11040,13 +11040,13 @@ def affine_hull_projection(self, A 1-dimensional polyhedron in QQ^1 defined as the convex hull of 2 vertices sage: A.vertices() (A vertex at (0), A vertex at (2)) - sage: A = L.affine_hull_projection(orthonormal=True) + sage: A = L.affine_hull_projection(orthonormal=True) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: the base ring needs to be extended; try with "extend=True" - sage: A = L.affine_hull_projection(orthonormal=True, extend=True); A + sage: A = L.affine_hull_projection(orthonormal=True, extend=True); A # optional - sage.rings.number_field A 1-dimensional polyhedron in AA^1 defined as the convex hull of 2 vertices - sage: A.vertices() + sage: A.vertices() # optional - sage.rings.number_field (A vertex at (1.414213562373095?), A vertex at (0.?e-18)) More generally:: From 5a3dbf4fc542d610310d9c3cbd179750f27da4d2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 5 Oct 2021 23:05:17 -0700 Subject: [PATCH 107/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx: Mark doctests # optional - sage.rings.number_field or sage.combinat --- .../face_iterator.pyx | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx index 6b7f436e956..8cdedf29ca6 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/face_iterator.pyx @@ -207,13 +207,13 @@ cdef class FaceIterator_base(SageObject): EXAMPLES:: - sage: P = polytopes.permutahedron(4) - sage: C = CombinatorialPolyhedron(P) - sage: it = C.face_iter() # indirect doctest + sage: P = polytopes.permutahedron(4) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: it = C.face_iter() # indirect doctest # optional - sage.combinat sage: f_vector = [1, 0, 0, 0, 1] - sage: for face in it: f_vector[face.dimension()+1] += 1 - sage: print ('f_vector of permutahedron(4): ', f_vector) + sage: for face in it: f_vector[face.dimension()+1] += 1 # optional - sage.combinat + sage: print ('f_vector of permutahedron(4): ', f_vector) # optional - sage.combinat f_vector of permutahedron(4): [1, 24, 36, 14, 1] sage: TestSuite(sage.geometry.polyhedron.combinatorial_polyhedron.face_iterator.FaceIterator).run() @@ -601,17 +601,17 @@ cdef class FaceIterator_base(SageObject): If the iterator has already been used, it must be reset before:: - sage: P = polytopes.dodecahedron() - sage: it = P.face_generator() - sage: _ = next(it), next(it) - sage: next(it).ambient_V_indices() + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: it = P.face_generator() # optional - sage.rings.number_field + sage: _ = next(it), next(it) # optional - sage.rings.number_field + sage: next(it).ambient_V_indices() # optional - sage.rings.number_field (15, 16, 17, 18, 19) - sage: it.meet_of_Hrep(9,11) + sage: it.meet_of_Hrep(9,11) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: please reset the face iterator - sage: it.reset() - sage: it.meet_of_Hrep(9,11).ambient_H_indices() + sage: it.reset() # optional - sage.rings.number_field + sage: it.meet_of_Hrep(9,11).ambient_H_indices() # optional - sage.rings.number_field (9, 11) TESTS: @@ -686,17 +686,17 @@ cdef class FaceIterator_base(SageObject): If the iterator has already been used, it must be reset before:: - sage: P = polytopes.dodecahedron() - sage: it = P.face_generator() - sage: _ = next(it), next(it) - sage: next(it).ambient_V_indices() + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: it = P.face_generator() # optional - sage.rings.number_field + sage: _ = next(it), next(it) # optional - sage.rings.number_field + sage: next(it).ambient_V_indices() # optional - sage.rings.number_field (15, 16, 17, 18, 19) - sage: it.join_of_Vrep(1,10) + sage: it.join_of_Vrep(1,10) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: please reset the face iterator - sage: it.reset() - sage: it.join_of_Vrep(1,10).ambient_V_indices() + sage: it.reset() # optional - sage.rings.number_field + sage: it.join_of_Vrep(1,10).ambient_V_indices() # optional - sage.rings.number_field (1, 10) In the case of an unbounded polyhedron, we try to make sense of the input:: @@ -810,9 +810,9 @@ cdef class FaceIterator_base(SageObject): The face iterator must not have the output dimension specified:: - sage: P = polytopes.dodecahedron() - sage: it = P.face_generator(2) - sage: it._meet_of_coatoms(1,2) + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: it = P.face_generator(2) # optional - sage.rings.number_field + sage: it._meet_of_coatoms(1,2) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: face iterator must not have the output dimension specified @@ -919,24 +919,24 @@ cdef class FaceIterator_base(SageObject): If the iterator has already been used, it must be reset before:: - sage: P = polytopes.dodecahedron() - sage: it = P.face_generator() - sage: _ = next(it), next(it) - sage: next(it).ambient_V_indices() + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: it = P.face_generator() # optional - sage.rings.number_field + sage: _ = next(it), next(it) # optional - sage.rings.number_field + sage: next(it).ambient_V_indices() # optional - sage.rings.number_field (15, 16, 17, 18, 19) - sage: it._join_of_atoms(1,10) + sage: it._join_of_atoms(1,10) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: please reset the face iterator - sage: it.reset() - sage: it._join_of_atoms(1,10).ambient_V_indices() + sage: it.reset() # optional - sage.rings.number_field + sage: it._join_of_atoms(1,10).ambient_V_indices() # optional - sage.rings.number_field (1, 10) The face iterator must not have the output dimension specified:: - sage: P = polytopes.dodecahedron() - sage: it = P.face_generator(2) - sage: it._join_of_atoms(1,2) + sage: P = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: it = P.face_generator(2) # optional - sage.rings.number_field + sage: it._join_of_atoms(1,2) # optional - sage.rings.number_field Traceback (most recent call last): ... ValueError: face iterator must not have the output dimension specified @@ -1530,12 +1530,12 @@ cdef class FaceIterator(FaceIterator_base): r""" EXAMPLES:: - sage: P = polytopes.associahedron(['A',3]) - sage: C = CombinatorialPolyhedron(P) - sage: C.face_iter() + sage: P = polytopes.associahedron(['A',3]) # optional - sage.combinat + sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat + sage: C.face_iter() # optional - sage.combinat Iterator over the proper faces of a 3-dimensional combinatorial polyhedron - sage: C.face_iter(1) + sage: C.face_iter(1) # optional - sage.combinat Iterator over the 1-faces of a 3-dimensional combinatorial polyhedron """ if self.structure.output_dimension != -2: @@ -1813,11 +1813,11 @@ cdef class FaceIterator_geom(FaceIterator_base): r""" EXAMPLES:: - sage: P = polytopes.associahedron(['A',3]) - sage: P.face_generator() + sage: P = polytopes.associahedron(['A',3]) # optional - sage.combinat + sage: P.face_generator() # optional - sage.combinat Iterator over the faces of a 3-dimensional polyhedron in QQ^3 - sage: P.face_generator(1) + sage: P.face_generator(1) # optional - sage.combinat Iterator over the 1-faces of a 3-dimensional polyhedron in QQ^3 """ if self._requested_dim is not None: From e236b523279c7dbded1c43d753e2315099f0332f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 5 Oct 2021 23:53:25 -0700 Subject: [PATCH 108/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx: More # optional --- .../combinatorial_polyhedron/base.pyx | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index bf03f279552..a98afc29de8 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -2577,20 +2577,20 @@ cdef class CombinatorialPolyhedron(SageObject): EXAMPLES:: - sage: P = polytopes.regular_polygon(4).pyramid() - sage: C = CombinatorialPolyhedron(P) - sage: D = C.hasse_diagram(); D + sage: P = polytopes.regular_polygon(4).pyramid() # optional - sage.rings.number_field + sage: C = CombinatorialPolyhedron(P) # optional - sage.rings.number_field + sage: D = C.hasse_diagram(); D # optional - sage.graphs # optional - sage.rings.number_field Digraph on 20 vertices - sage: D.average_degree() + sage: D.average_degree() # optional - sage.graphs # optional - sage.rings.number_field 21/5 - sage: D.relabel(C.face_by_face_lattice_index) - sage: dim_0_vert = D.vertices()[1:6]; dim_0_vert + sage: D.relabel(C.face_by_face_lattice_index) # optional - sage.graphs # optional - sage.rings.number_field + sage: dim_0_vert = D.vertices()[1:6]; dim_0_vert # optional - sage.graphs # optional - sage.rings.number_field [A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron, A 0-dimensional face of a 3-dimensional combinatorial polyhedron] - sage: sorted(D.out_degree(vertices=dim_0_vert)) + sage: sorted(D.out_degree(vertices=dim_0_vert)) # optional - sage.graphs # optional - sage.rings.number_field [3, 3, 3, 3, 4] """ if not self._face_lattice_incidences: @@ -3108,7 +3108,7 @@ cdef class CombinatorialPolyhedron(SageObject): sage: C1 = C.pyramid() sage: P1 = P.pyramid() sage: C2 = P1.combinatorial_polyhedron() - sage: C2.vertex_facet_graph().is_isomorphic(C1.vertex_facet_graph()) + sage: C2.vertex_facet_graph().is_isomorphic(C1.vertex_facet_graph()) # optional - sage.combinat True One can specify a name for the new vertex:: @@ -3127,10 +3127,10 @@ cdef class CombinatorialPolyhedron(SageObject): One can specify a name for the new facets:: - sage: P = polytopes.regular_polygon(4) - sage: C = P.combinatorial_polyhedron() - sage: C1 = C.pyramid(new_facet='base') - sage: C1.Hrepresentation() + sage: P = polytopes.regular_polygon(4) # optional - sage.rings.number_field + sage: C = P.combinatorial_polyhedron() # optional - sage.rings.number_field + sage: C1 = C.pyramid(new_facet='base') # optional - sage.rings.number_field + sage: C1.Hrepresentation() # optional - sage.rings.number_field (An inequality (-1/2, 1/2) x + 1/2 >= 0, An inequality (-1/2, -1/2) x + 1/2 >= 0, An inequality (1/2, 0.50000000000000000?) x + 1/2 >= 0, From d892e342310ff60554ef9ea3328fdd00f7d60c09 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 6 Oct 2021 13:02:43 -0700 Subject: [PATCH 109/378] git grep -l 'sage:.*plot' src/sage/geometry/ | xargs sed -i.bak '/sage: .*plot(/s/$/ # optional - sage.plot/' --- src/sage/geometry/cone.py | 4 +- src/sage/geometry/fan.py | 6 +- .../hyperbolic_space/hyperbolic_geodesic.py | 40 ++++---- .../hyperplane_arrangement/arrangement.py | 4 +- .../hyperplane_arrangement/hyperplane.py | 2 +- .../geometry/hyperplane_arrangement/plot.py | 46 ++++----- src/sage/geometry/newton_polygon.py | 2 +- src/sage/geometry/polyhedral_complex.py | 6 +- .../geometry/polyhedron/backend_normaliz.py | 2 +- src/sage/geometry/polyhedron/base.py | 98 +++++++++---------- src/sage/geometry/polyhedron/library.py | 4 +- src/sage/geometry/polyhedron/parent.py | 2 +- src/sage/geometry/polyhedron/plot.py | 30 +++--- .../polyhedron/ppl_lattice_polygon.py | 6 +- .../parametrized_surface3d.py | 8 +- .../surface3d_generators.py | 30 +++--- src/sage/geometry/toric_lattice.py | 6 +- src/sage/geometry/toric_lattice_element.pyx | 2 +- src/sage/geometry/toric_plotter.py | 10 +- src/sage/geometry/triangulation/element.py | 8 +- .../triangulation/point_configuration.py | 14 +-- src/sage/geometry/voronoi_diagram.py | 10 +- 22 files changed, 170 insertions(+), 170 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 177e143dd5e..daab3494c25 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1097,7 +1097,7 @@ def plot(self, **options): EXAMPLES:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.plot() + sage: quadrant.plot() # optional - sage.plot Graphics object consisting of 9 graphics primitives """ tp = ToricPlotter(options, self.lattice().degree(), self.rays()) @@ -3474,7 +3474,7 @@ def plot(self, **options): EXAMPLES:: sage: quadrant = Cone([(1,0), (0,1)]) - sage: quadrant.plot() + sage: quadrant.plot() # optional - sage.plot Graphics object consisting of 9 graphics primitives """ # What to do with 3-d cones in 5-d? Use some projection method? diff --git a/src/sage/geometry/fan.py b/src/sage/geometry/fan.py index 5f8754941d4..9aa8fa24784 100644 --- a/src/sage/geometry/fan.py +++ b/src/sage/geometry/fan.py @@ -504,7 +504,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: fan = Fan([c1, c2], allow_arrangement=True) sage: fan.ngenerating_cones() 7 - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics3d Object Cones of different dimension:: @@ -524,7 +524,7 @@ def Fan(cones, rays=None, lattice=None, check=True, normalize=True, sage: c3 = Cone([[0, 1, 1], [1, 0, 1], [0, -1, 1], [-1, 0, 1]]) sage: c1 = Cone([[0, 0, 1]]) sage: fan1 = Fan([c1, c3], allow_arrangement=True) - sage: fan1.plot() + sage: fan1.plot() # optional - sage.plot Graphics3d Object A 3-d cone and two 2-d cones:: @@ -2970,7 +2970,7 @@ def plot(self, **options): EXAMPLES:: sage: fan = toric_varieties.dP6().fan() - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics object consisting of 31 graphics primitives """ tp = ToricPlotter(options, self.lattice().degree(), self.rays()) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index ccb1fcdd95c..9ddee0b6437 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -24,7 +24,7 @@ :: - sage: g.plot(axes=True) + sage: g.plot(axes=True) # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -37,7 +37,7 @@ sage: g = HyperbolicPlane().UHP().get_geodesic(I, 3 + I) sage: g.length() arccosh(11/2) - sage: g.plot(axes=True) + sage: g.plot(axes=True) # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -49,7 +49,7 @@ sage: g = HyperbolicPlane().UHP().get_geodesic(I, 3*I) sage: g Geodesic in UHP from I to 3*I - sage: g.plot() + sage: g.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -887,7 +887,7 @@ def perpendicular_bisector(self): sage: PD = HyperbolicPlane().PD() sage: g = PD.get_geodesic(-0.3+0.4*I,+0.7-0.1*I) sage: h = g.perpendicular_bisector() - sage: P = g.plot(color='blue')+h.plot(color='orange');P + sage: P = g.plot(color='blue')+h.plot(color='orange');P # optional - sage.plot Graphics object consisting of 4 graphics primitives .. PLOT:: @@ -1107,7 +1107,7 @@ def plot(self, boundary=True, **options): EXAMPLES:: sage: UHP = HyperbolicPlane().UHP() - sage: UHP.get_geodesic(0, 1).plot() + sage: UHP.get_geodesic(0, 1).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -1118,7 +1118,7 @@ def plot(self, boundary=True, **options): :: - sage: UHP.get_geodesic(I, 3+4*I).plot(linestyle="dashed", color="brown") + sage: UHP.get_geodesic(I, 3+4*I).plot(linestyle="dashed", color="brown") # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -1129,7 +1129,7 @@ def plot(self, boundary=True, **options): :: - sage: UHP.get_geodesic(1, infinity).plot(color='orange') + sage: UHP.get_geodesic(1, infinity).plot(color='orange') # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -1143,25 +1143,25 @@ def plot(self, boundary=True, **options): Plotting a line with ``boundary=True``. :: sage: g = HyperbolicPlane().UHP().get_geodesic(0, I) - sage: g.plot() + sage: g.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives Plotting a line with ``boundary=False``. :: sage: g = HyperbolicPlane().UHP().get_geodesic(0, I) - sage: g.plot(boundary=False) + sage: g.plot(boundary=False) # optional - sage.plot Graphics object consisting of 1 graphics primitive Plotting a circle with ``boundary=True``. :: sage: g = HyperbolicPlane().UHP().get_geodesic(-3, 19) - sage: g.plot() + sage: g.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives Plotting a circle with ``boundary=False``. :: sage: g = HyperbolicPlane().UHP().get_geodesic(3, 4) - sage: g.plot(boundary=False) + sage: g.plot(boundary=False) # optional - sage.plot Graphics object consisting of 1 graphics primitive """ @@ -1380,7 +1380,7 @@ def perpendicular_bisector(self): # UHP sage: UHP = HyperbolicPlane().UHP() sage: g = UHP.get_geodesic(1+I,2+0.5*I) sage: h = g.perpendicular_bisector() - sage: show(g.plot(color='blue')+h.plot(color='orange')) + sage: show(g.plot(color='blue')+h.plot(color='orange')) # optional - sage.plot .. PLOT:: @@ -2009,7 +2009,7 @@ def plot(self, boundary=True, **options): First some lines:: sage: PD = HyperbolicPlane().PD() - sage: PD.get_geodesic(0, 1).plot() + sage: PD.get_geodesic(0, 1).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2018,7 +2018,7 @@ def plot(self, boundary=True, **options): :: - sage: PD.get_geodesic(0, 0.3+0.8*I).plot() + sage: PD.get_geodesic(0, 0.3+0.8*I).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2028,13 +2028,13 @@ def plot(self, boundary=True, **options): Then some generic geodesics:: - sage: PD.get_geodesic(-0.5, 0.3+0.4*I).plot() + sage: PD.get_geodesic(-0.5, 0.3+0.4*I).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: g = PD.get_geodesic(-1, exp(3*I*pi/7)) - sage: G = g.plot(linestyle="dashed",color="red"); G + sage: G = g.plot(linestyle="dashed",color="red"); G # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: h = PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)) - sage: H = h.plot(thickness=6, color="orange"); H + sage: H = h.plot(thickness=6, color="orange"); H # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: show(G+H) @@ -2101,7 +2101,7 @@ class HyperbolicGeodesicKM(HyperbolicGeodesic): sage: g = KM.get_geodesic(KM.get_point((0.1,0.9)), KM.get_point((-0.1,-0.9))) sage: g = KM.get_geodesic((0.1,0.9),(-0.1,-0.9)) sage: h = KM.get_geodesic((-0.707106781,-0.707106781),(0.707106781,-0.707106781)) - sage: P = g.plot(color='orange')+h.plot(); P + sage: P = g.plot(color='orange')+h.plot(); P # optional - sage.plot Graphics object consisting of 4 graphics primitives @@ -2122,7 +2122,7 @@ def plot(self, boundary=True, **options): EXAMPLES:: - sage: HyperbolicPlane().KM().get_geodesic((0,0), (1,0)).plot() + sage: HyperbolicPlane().KM().get_geodesic((0,0), (1,0)).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives .. PLOT:: @@ -2182,7 +2182,7 @@ def plot(self, show_hyperboloid=True, **graphics_options): sage: from sage.geometry.hyperbolic_space.hyperbolic_geodesic \ ....: import * sage: g = HyperbolicPlane().HM().random_geodesic() - sage: g.plot() + sage: g.plot() # optional - sage.plot Graphics3d Object .. PLOT:: diff --git a/src/sage/geometry/hyperplane_arrangement/arrangement.py b/src/sage/geometry/hyperplane_arrangement/arrangement.py index 1914442251c..9b7163b525a 100644 --- a/src/sage/geometry/hyperplane_arrangement/arrangement.py +++ b/src/sage/geometry/hyperplane_arrangement/arrangement.py @@ -689,7 +689,7 @@ def plot(self, **kwds): EXAMPLES:: sage: L. = HyperplaneArrangements(QQ) - sage: L(x, y, x+y-2).plot() + sage: L(x, y, x+y-2).plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives """ from sage.geometry.hyperplane_arrangement.plot import plot @@ -1690,7 +1690,7 @@ def vertices(self, exclude_sandwiched=False): (6, 21, 16) sage: A.vertices() ((-2/3, 1/3), (-1/3, -1/3), (0, -1), (0, 0), (1/3, -2/3), (2/3, -1/3)) - sage: point2d(A.vertices(), size=20) + A.plot() + sage: point2d(A.vertices(), size=20) + A.plot() # optional - sage.plot Graphics object consisting of 7 graphics primitives sage: H. = HyperplaneArrangements(QQ) diff --git a/src/sage/geometry/hyperplane_arrangement/hyperplane.py b/src/sage/geometry/hyperplane_arrangement/hyperplane.py index fd5bb34da7f..589d45d0750 100644 --- a/src/sage/geometry/hyperplane_arrangement/hyperplane.py +++ b/src/sage/geometry/hyperplane_arrangement/hyperplane.py @@ -604,7 +604,7 @@ def plot(self, **kwds): EXAMPLES:: sage: L. = HyperplaneArrangements(QQ) - sage: (x+y-2).plot() + sage: (x+y-2).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ from sage.geometry.hyperplane_arrangement.plot import plot_hyperplane diff --git a/src/sage/geometry/hyperplane_arrangement/plot.py b/src/sage/geometry/hyperplane_arrangement/plot.py index a8750290fb8..6457234eece 100644 --- a/src/sage/geometry/hyperplane_arrangement/plot.py +++ b/src/sage/geometry/hyperplane_arrangement/plot.py @@ -56,25 +56,25 @@ sage: H3. = HyperplaneArrangements(QQ) sage: A = H3([(1,0,0), 0], [(0,0,1), 5]) - sage: A.plot(hyperplane_opacities=0.5, hyperplane_labels=True, hyperplane_legend=False) + sage: A.plot(hyperplane_opacities=0.5, hyperplane_labels=True, hyperplane_legend=False) # optional - sage.plot Graphics3d Object sage: c = H3([(1,0,0),0], [(0,0,1),5]) - sage: c.plot(ranges=10) + sage: c.plot(ranges=10) # optional - sage.plot Graphics3d Object - sage: c.plot(ranges=[[9.5,10], [-3,3]]) + sage: c.plot(ranges=[[9.5,10], [-3,3]]) # optional - sage.plot Graphics3d Object - sage: c.plot(ranges=[[[9.5,10], [-3,3]], [[-6,6], [-5,5]]]) + sage: c.plot(ranges=[[[9.5,10], [-3,3]], [[-6,6], [-5,5]]]) # optional - sage.plot Graphics3d Object sage: H2. = HyperplaneArrangements(QQ) sage: h = H2([(1,1),0], [(1,-1),0], [(0,1),2]) - sage: h.plot(ranges=20) + sage: h.plot(ranges=20) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: h.plot(ranges=[-1, 10]) + sage: h.plot(ranges=[-1, 10]) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: h.plot(ranges=[[-1, 1], [-5, 5], [-1, 10]]) + sage: h.plot(ranges=[[-1, 1], [-5, 5], [-1, 10]]) # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: a = hyperplane_arrangements.coordinate(3) @@ -83,24 +83,24 @@ sage: opts['label_offsets'] = [(0,2,2), (2,0,2), (2,2,0)] sage: opts['hyperplane_legend'] = False sage: opts['hyperplane_opacities'] = 0.7 - sage: a.plot(**opts) + sage: a.plot(**opts) # optional - sage.plot Graphics3d Object sage: opts['hyperplane_labels'] = 'short' - sage: a.plot(**opts) + sage: a.plot(**opts) # optional - sage.plot Graphics3d Object sage: H. = HyperplaneArrangements(QQ) sage: pts = H(3*u+4, 2*u+5, 7*u+1) - sage: pts.plot(hyperplane_colors=['yellow','black','blue']) + sage: pts.plot(hyperplane_colors=['yellow','black','blue']) # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: pts.plot(point_sizes=[50,100,200], hyperplane_colors='blue') + sage: pts.plot(point_sizes=[50,100,200], hyperplane_colors='blue') # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: H. = HyperplaneArrangements(QQ) sage: a = H(x, y+1, y+2) - sage: a.plot(hyperplane_labels=True,label_colors='blue',label_fontsize=18) + sage: a.plot(hyperplane_labels=True,label_colors='blue',label_fontsize=18) # optional - sage.plot Graphics3d Object - sage: a.plot(hyperplane_labels=True,label_colors=['red','green','black']) + sage: a.plot(hyperplane_labels=True,label_colors=['red','green','black']) # optional - sage.plot Graphics3d Object """ @@ -144,7 +144,7 @@ def plot(hyperplane_arrangement, **kwds): EXAMPLES:: sage: B = hyperplane_arrangements.semiorder(4) - sage: B.plot() + sage: B.plot() # optional - sage.plot Displaying the essentialization. Graphics3d Object """ @@ -332,34 +332,34 @@ def plot_hyperplane(hyperplane, **kwds): sage: H1. = HyperplaneArrangements(QQ) sage: a = 3*x + 4 - sage: a.plot() # indirect doctest + sage: a.plot() # indirect doctest # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: a.plot(point_size=100,hyperplane_label='hello') + sage: a.plot(point_size=100,hyperplane_label='hello') # optional - sage.plot Graphics object consisting of 3 graphics primitives sage: H2. = HyperplaneArrangements(QQ) sage: b = 3*x + 4*y + 5 - sage: b.plot() + sage: b.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: b.plot(ranges=(1,5),label_offset=(2,-1)) + sage: b.plot(ranges=(1,5),label_offset=(2,-1)) # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: opts = {'hyperplane_label':True, 'label_color':'green', ....: 'label_fontsize':24, 'label_offset':(0,1.5)} - sage: b.plot(**opts) + sage: b.plot(**opts) # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: H3. = HyperplaneArrangements(QQ) sage: c = 2*x + 3*y + 4*z + 5 - sage: c.plot() + sage: c.plot() # optional - sage.plot Graphics3d Object - sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False) + sage: c.plot(label_offset=(1,0,1), color='green', label_color='red', frame=False) # optional - sage.plot Graphics3d Object sage: d = -3*x + 2*y + 2*z + 3 - sage: d.plot(opacity=0.8) + sage: d.plot(opacity=0.8) # optional - sage.plot Graphics3d Object sage: e = 4*x + 2*z + 3 - sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1) + sage: e.plot(ranges=[[-1,1],[0,8]], label_offset=(2,2,1), aspect_ratio=1) # optional - sage.plot Graphics3d Object """ if hyperplane.base_ring().characteristic(): diff --git a/src/sage/geometry/newton_polygon.py b/src/sage/geometry/newton_polygon.py index ad977843958..6c12c0a01d3 100644 --- a/src/sage/geometry/newton_polygon.py +++ b/src/sage/geometry/newton_polygon.py @@ -464,7 +464,7 @@ def plot(self, **kwargs): sage: from sage.geometry.newton_polygon import NewtonPolygon sage: NP = NewtonPolygon([ (0,0), (1,1), (2,6) ]) - sage: polygon = NP.plot() + sage: polygon = NP.plot() # optional - sage.plot """ vertices = self.vertices() if len(vertices) == 0: diff --git a/src/sage/geometry/polyhedral_complex.py b/src/sage/geometry/polyhedral_complex.py index 10e8c34f79d..948196fa306 100644 --- a/src/sage/geometry/polyhedral_complex.py +++ b/src/sage/geometry/polyhedral_complex.py @@ -203,7 +203,7 @@ class PolyhedralComplex(GenericCellComplex): (A vertex at (0, 1/4),), (A vertex at (1/7, 2/7),), (A vertex at (1/3, 1/3),)] - sage: pc.plot() + sage: pc.plot() # optional - sage.plot Graphics object consisting of 10 graphics primitives sage: pc.is_pure() True @@ -728,7 +728,7 @@ def plot(self, **kwds): sage: p1 = Polyhedron(vertices=[(1, 1), (0, 0), (1, 2)]) sage: p2 = Polyhedron(vertices=[(1, 2), (0, 0), (0, 2)]) sage: pc = PolyhedralComplex([p1, p2]) - sage: pc.plot() + sage: pc.plot() # optional - sage.plot Graphics object consisting of 10 graphics primitives """ if self.dimension() > 3: @@ -937,7 +937,7 @@ def face_poset(self): sage: poset Finite poset containing 11 elements sage: d = {i: i.vertices_matrix() for i in poset} - sage: poset.plot(element_labels=d) + sage: poset.plot(element_labels=d) # optional - sage.plot Graphics object consisting of 28 graphics primitives For a nonbounded polyhedral complex:: diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index d1f30e2d31f..c741e5f8636 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -1381,7 +1381,7 @@ def integral_hull(self): sage: P = Polyhedron(ieqs=[[1, 0, 2], [3, 0, -2], [3, 2, -2]], # optional - pynormaliz ....: backend='normaliz') sage: PI = P.integral_hull() # optional - pynormaliz - sage: P.plot(color='yellow') + PI.plot(color='green') # optional - pynormaliz + sage: P.plot(color='yellow') + PI.plot(color='green') # optional - pynormaliz # optional - sage.plot Graphics object consisting of 10 graphics primitives sage: PI.Vrepresentation() # optional - pynormaliz (A vertex at (-1, 0), A vertex at (0, 1), A ray in the direction (1, 0)) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 720d6367cb6..fd34e454c1e 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -895,55 +895,55 @@ def plot(self, By default, the wireframe is rendered in blue and the fill in green:: - sage: square.plot() + sage: square.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: point.plot() + sage: point.plot() # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot() + sage: line.plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: cube.plot() + sage: cube.plot() # optional - sage.plot Graphics3d Object - sage: hypercube.plot() + sage: hypercube.plot() # optional - sage.plot Graphics3d Object Draw the lines in red and nothing else:: - sage: square.plot(point=False, line='red', polygon=False) + sage: square.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 4 graphics primitives - sage: point.plot(point=False, line='red', polygon=False) + sage: point.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 0 graphics primitives - sage: line.plot(point=False, line='red', polygon=False) + sage: line.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: cube.plot(point=False, line='red', polygon=False) + sage: cube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object - sage: hypercube.plot(point=False, line='red', polygon=False) + sage: hypercube.plot(point=False, line='red', polygon=False) # optional - sage.plot Graphics3d Object Draw points in red, no lines, and a blue polygon:: - sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) + sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) + sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) + sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) + sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object - sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) + sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) # optional - sage.plot Graphics3d Object If we instead use the ``fill`` and ``wireframe`` options, the coloring depends on the dimension of the object:: - sage: square.plot(fill='green', wireframe='red') + sage: square.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: point.plot(fill='green', wireframe='red') + sage: point.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 1 graphics primitive - sage: line.plot(fill='green', wireframe='red') + sage: line.plot(fill='green', wireframe='red') # optional - sage.plot Graphics object consisting of 2 graphics primitives - sage: cube.plot(fill='green', wireframe='red') + sage: cube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object - sage: hypercube.plot(fill='green', wireframe='red') + sage: hypercube.plot(fill='green', wireframe='red') # optional - sage.plot Graphics3d Object It is possible to draw polyhedra up to dimension 4, no matter what the @@ -952,12 +952,12 @@ def plot(self, sage: hcube = polytopes.hypercube(5) sage: facet = hcube.facets()[0].as_polyhedron();facet A 4-dimensional polyhedron in ZZ^5 defined as the convex hull of 16 vertices - sage: facet.plot() + sage: facet.plot() # optional - sage.plot Graphics3d Object TESTS:: - sage: for p in square.plot(): + sage: for p in square.plot(): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) blue Point set defined by 4 point(s) blue Line defined by 2 points @@ -966,18 +966,18 @@ def plot(self, blue Line defined by 2 points green Polygon defined by 4 points - sage: for p in line.plot(): + sage: for p in line.plot(): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) blue Point set defined by 2 point(s) green Line defined by 2 points - sage: for p in point.plot(): + sage: for p in point.plot(): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) green Point set defined by 1 point(s) Draw the lines in red and nothing else:: - sage: for p in square.plot(point=False, line='red', polygon=False): + sage: for p in square.plot(point=False, line='red', polygon=False): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Line defined by 2 points red Line defined by 2 points @@ -986,66 +986,66 @@ def plot(self, Draw vertices in red, no lines, and a blue polygon:: - sage: for p in square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): + sage: for p in square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Point set defined by 4 point(s) (0, 0, 1) Polygon defined by 4 points - sage: for p in line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): + sage: for p in line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Point set defined by 2 point(s) - sage: for p in point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): + sage: for p in point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Point set defined by 1 point(s) Draw in red without wireframe:: - sage: for p in square.plot(wireframe=False, fill="red"): + sage: for p in square.plot(wireframe=False, fill="red"): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Polygon defined by 4 points - sage: for p in line.plot(wireframe=False, fill="red"): + sage: for p in line.plot(wireframe=False, fill="red"): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Line defined by 2 points - sage: for p in point.plot(wireframe=False, fill="red"): + sage: for p in point.plot(wireframe=False, fill="red"): # optional - sage.plot ....: print("{} {}".format(p.options()['rgbcolor'], p)) red Point set defined by 1 point(s) We try to draw the polytope in 2 or 3 dimensions:: - sage: type(Polyhedron(ieqs=[(1,)]).plot()) + sage: type(Polyhedron(ieqs=[(1,)]).plot()) # optional - sage.plot - sage: type(polytopes.hypercube(1).plot()) + sage: type(polytopes.hypercube(1).plot()) # optional - sage.plot - sage: type(polytopes.hypercube(2).plot()) + sage: type(polytopes.hypercube(2).plot()) # optional - sage.plot - sage: type(polytopes.hypercube(3).plot()) + sage: type(polytopes.hypercube(3).plot()) # optional - sage.plot In 4d a projection to 3d is used:: - sage: type(polytopes.hypercube(4).plot()) + sage: type(polytopes.hypercube(4).plot()) # optional - sage.plot - sage: type(polytopes.hypercube(5).plot()) + sage: type(polytopes.hypercube(5).plot()) # optional - sage.plot Traceback (most recent call last): ... NotImplementedError: plotting of 5-dimensional polyhedra not implemented If the polyhedron is not full-dimensional, the :meth:`affine_hull_projection` is used if necessary:: - sage: type(Polyhedron([(0,), (1,)]).plot()) + sage: type(Polyhedron([(0,), (1,)]).plot()) # optional - sage.plot - sage: type(Polyhedron([(0,0), (1,1)]).plot()) + sage: type(Polyhedron([(0,0), (1,1)]).plot()) # optional - sage.plot - sage: type(Polyhedron([(0,0,0), (1,1,1)]).plot()) + sage: type(Polyhedron([(0,0,0), (1,1,1)]).plot()) # optional - sage.plot - sage: type(Polyhedron([(0,0,0,0), (1,1,1,1)]).plot()) + sage: type(Polyhedron([(0,0,0,0), (1,1,1,1)]).plot()) # optional - sage.plot - sage: type(Polyhedron([(0,0,0,0,0), (1,1,1,1,1)]).plot()) + sage: type(Polyhedron([(0,0,0,0,0), (1,1,1,1,1)]).plot()) # optional - sage.plot - sage: type(Polyhedron([(0,0,0,0), (1,1,1,1), (1,0,0,0)]).plot()) + sage: type(Polyhedron([(0,0,0,0), (1,1,1,1), (1,0,0,0)]).plot()) # optional - sage.plot TESTS: @@ -6582,7 +6582,7 @@ def face_lattice(self): sage: c5_20_fl = c5_20.face_lattice() # long time sage: [len(x) for x in c5_20_fl.level_sets()] # long time [1, 20, 190, 580, 680, 272, 1] - sage: polytopes.hypercube(2).face_lattice().plot() + sage: polytopes.hypercube(2).face_lattice().plot() # optional - sage.plot Graphics object consisting of 27 graphics primitives sage: level_sets = polytopes.cross_polytope(2).face_lattice().level_sets() sage: level_sets[0][0].ambient_V_indices(), level_sets[-1][0].ambient_V_indices() @@ -8361,7 +8361,7 @@ def schlegel_projection(self, facet=None, position=None): sage: tfcube.facets()[-1] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 8 vertices sage: sp = tfcube.schlegel_projection(tfcube.facets()[-1]) - sage: sp.plot() + sage: sp.plot() # optional - sage.plot Graphics3d Object The same truncated cube but see inside the tetrahedral facet:: @@ -8369,16 +8369,16 @@ def schlegel_projection(self, facet=None, position=None): sage: tfcube.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices sage: sp = tfcube.schlegel_projection(tfcube.facets()[4]) - sage: sp.plot() + sage: sp.plot() # optional - sage.plot Graphics3d Object A different values of ``position`` changes the projection:: sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],1/2) - sage: sp.plot() + sage: sp.plot() # optional - sage.plot Graphics3d Object sage: sp = tfcube.schlegel_projection(tfcube.facets()[4],4) - sage: sp.plot() + sage: sp.plot() # optional - sage.plot Graphics3d Object A value which is too large give a projection point that sees more than @@ -11449,7 +11449,7 @@ def affine_hull_manifold(self, name=None, latex_name=None, start_index=0, ambien sage: submanifolds = [ ....: F.as_polyhedron().affine_hull_manifold(name=f'F{i}', orthogonal=True, ambient_space=E3) ....: for i, F in enumerate(D.facets())] - sage: sum(FM.plot({}, srange(-2, 2, 0.1), srange(-2, 2, 0.1), opacity=0.2) # not tested + sage: sum(FM.plot({}, srange(-2, 2, 0.1), srange(-2, 2, 0.1), opacity=0.2) # not tested # optional - sage.plot ....: for FM in submanifolds) + D.plot() Graphics3d Object diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 31cec880ccf..d1f6e7333b0 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -2522,7 +2522,7 @@ def permutahedron(self, n, project=False, backend=None): sage: perm4 = polytopes.permutahedron(4, project=True) sage: perm4 A 3-dimensional polyhedron in RDF^3 defined as the convex hull of 24 vertices - sage: perm4.plot() + sage: perm4.plot() # optional - sage.plot Graphics3d Object sage: perm4.graph().is_isomorphic(graphs.BubbleSortGraph(4)) True @@ -3305,7 +3305,7 @@ def cube(self, intervals=None, backend=None): (1, 8, 12, 6, 1) sage: c.volume() 8 - sage: c.plot() + sage: c.plot() # optional - sage.plot Graphics3d Object Return the `0/1`-cube:: diff --git a/src/sage/geometry/polyhedron/parent.py b/src/sage/geometry/polyhedron/parent.py index 48bed4a9553..c03b03129ee 100644 --- a/src/sage/geometry/polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/parent.py @@ -576,7 +576,7 @@ def _element_constructor_(self, *args, **kwds): sage: lp.set_objective(x[0] + x[1]) sage: b = lp.get_backend() sage: P = b.interactive_lp_problem() - sage: p = P.plot() + sage: p = P.plot() # optional - sage.plot sage: Q = Polyhedron(ieqs=[[-499999, 1000000], [1499999, -1000000]]) sage: P = Polyhedron(ieqs=[[0, 1.0], [1.0, -1.0]], base_ring=RDF) diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index 9a6a759eb93..3c8e2055139 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -348,12 +348,12 @@ def __init__(self, polyhedron, proj=projection_func_identity): The projection of a polyhedron into 2 dimensions sage: Projection(p, lambda x: [x[1],x[2]] ) # another way of doing the same projection The projection of a polyhedron into 2 dimensions - sage: _.plot() # plot of the projected icosahedron in 2d + sage: _.plot() # plot of the projected icosahedron in 2d # optional - sage.plot Graphics object consisting of 51 graphics primitives sage: proj = Projection(p) sage: proj.stereographic([1,2,3]) The projection of a polyhedron into 2 dimensions - sage: proj.plot() + sage: proj.plot() # optional - sage.plot Graphics object consisting of 51 graphics primitives sage: TestSuite(proj).run(skip='_test_pickling') """ @@ -452,7 +452,7 @@ def stereographic(self, projection_point=None): sage: proj = Projection(polytopes.buckyball()) #long time sage: proj #long time The projection of a polyhedron into 3 dimensions - sage: proj.stereographic([5,2,3]).plot() #long time + sage: proj.stereographic([5,2,3]).plot() #long time # optional - sage.plot Graphics object consisting of 123 graphics primitives sage: Projection( polytopes.twenty_four_cell() ).stereographic([2,0,0,0]) The projection of a polyhedron into 3 dimensions @@ -489,7 +489,7 @@ def schlegel(self, facet=None, position=None): sage: from sage.geometry.polyhedron.plot import Projection sage: Projection(cube4).schlegel() The projection of a polyhedron into 3 dimensions - sage: _.plot() + sage: _.plot() # optional - sage.plot Graphics3d Object The 4-cube with a truncated vertex seen into the resulting tetrahedron @@ -499,13 +499,13 @@ def schlegel(self, facet=None, position=None): sage: tcube4.facets()[4] A 3-dimensional face of a Polyhedron in QQ^4 defined as the convex hull of 4 vertices sage: into_tetra = Projection(tcube4).schlegel(tcube4.facets()[4]) - sage: into_tetra.plot() + sage: into_tetra.plot() # optional - sage.plot Graphics3d Object Taking a larger value for the position changes the image:: sage: into_tetra_far = Projection(tcube4).schlegel(tcube4.facets()[4],4) - sage: into_tetra_far.plot() + sage: into_tetra_far.plot() # optional - sage.plot Graphics3d Object A value which is too large or negative give a projection point that @@ -1094,7 +1094,7 @@ def render_2d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: q3 = p3.projection() sage: p4 = Polyhedron(vertices=[[2,0]], rays=[[1,-1]], lines=[[1,1]]) sage: q4 = p4.projection() - sage: q1.plot() + q2.plot() + q3.plot() + q4.plot() + sage: q1.plot() + q2.plot() + q3.plot() + q4.plot() # optional - sage.plot Graphics object consisting of 17 graphics primitives """ plt = Graphics() @@ -1126,12 +1126,12 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: p1 = Polyhedron(vertices=[[1,1,1]], rays=[[1,1,1]]) sage: p2 = Polyhedron(vertices=[[2,0,0], [0,2,0], [0,0,2]]) sage: p3 = Polyhedron(vertices=[[1,0,0], [0,1,0], [0,0,1]], rays=[[-1,-1,-1]]) - sage: p1.projection().plot() + p2.projection().plot() + p3.projection().plot() + sage: p1.projection().plot() + p2.projection().plot() + p3.projection().plot() # optional - sage.plot Graphics3d Object It correctly handles various degenerate cases:: - sage: Polyhedron(lines=[[1,0,0],[0,1,0],[0,0,1]]).plot() # whole space + sage: Polyhedron(lines=[[1,0,0],[0,1,0],[0,0,1]]).plot() # whole space # optional - sage.plot Graphics3d Object sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], ....: lines=[[0,1,0],[0,0,1]]).plot() # half space @@ -1139,15 +1139,15 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: Polyhedron(vertices=[[1,1,1]], ....: lines=[[0,1,0],[0,0,1]]).plot() # R^2 in R^3 Graphics3d Object - sage: Polyhedron(rays=[[0,1,0],[0,0,1]], lines=[[1,0,0]]).plot() # quadrant wedge in R^2 + sage: Polyhedron(rays=[[0,1,0],[0,0,1]], lines=[[1,0,0]]).plot() # quadrant wedge in R^2 # optional - sage.plot Graphics3d Object - sage: Polyhedron(rays=[[0,1,0]], lines=[[1,0,0]]).plot() # upper half plane in R^3 + sage: Polyhedron(rays=[[0,1,0]], lines=[[1,0,0]]).plot() # upper half plane in R^3 # optional - sage.plot Graphics3d Object - sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 + sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 # optional - sage.plot Graphics3d Object - sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 + sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 # optional - sage.plot Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 + sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 # optional - sage.plot Graphics3d Object The origin is not included, if it is not in the polyhedron (:trac:`23555`):: @@ -1155,7 +1155,7 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: Q = Polyhedron([[100],[101]]) sage: P = Q*Q*Q; P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: p = P.plot() + sage: p = P.plot() # optional - sage.plot sage: p.bounding_box() ((100.0, 100.0, 100.0), (101.0, 101.0, 101.0)) """ diff --git a/src/sage/geometry/polyhedron/ppl_lattice_polygon.py b/src/sage/geometry/polyhedron/ppl_lattice_polygon.py index 03343dc6f9f..c7eac168fad 100644 --- a/src/sage/geometry/polyhedron/ppl_lattice_polygon.py +++ b/src/sage/geometry/polyhedron/ppl_lattice_polygon.py @@ -407,11 +407,11 @@ def plot(self): sage: from sage.geometry.polyhedron.ppl_lattice_polytope import LatticePolytope_PPL sage: P = LatticePolytope_PPL((1,0), (0,1), (0,0), (2,2)) - sage: P.plot() + sage: P.plot() # optional - sage.plot Graphics object consisting of 6 graphics primitives - sage: LatticePolytope_PPL([0], [1]).plot() + sage: LatticePolytope_PPL([0], [1]).plot() # optional - sage.plot Graphics object consisting of 3 graphics primitives - sage: LatticePolytope_PPL([0]).plot() + sage: LatticePolytope_PPL([0]).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ from sage.plot.point import point2d diff --git a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py index ce3e306d277..e189cbcbdfc 100644 --- a/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py +++ b/src/sage/geometry/riemannian_manifolds/parametrized_surface3d.py @@ -97,7 +97,7 @@ class ParametrizedSurface3D(SageObject): sage: ellipsoid_eq = (cos(u1)*cos(u2), 2*sin(u1)*cos(u2), 3*sin(u2)) sage: ellipsoid = ParametrizedSurface3D(ellipsoid_eq, coords, 'ellipsoid'); ellipsoid Parametrized surface ('ellipsoid') with equation (cos(u1)*cos(u2), 2*cos(u2)*sin(u1), 3*sin(u2)) - sage: ellipsoid.plot() + sage: ellipsoid.plot() # optional - sage.plot Graphics3d Object Standard surfaces can be constructed using the ``surfaces`` generator:: @@ -120,7 +120,7 @@ class ParametrizedSurface3D(SageObject): sage: enneper = surfaces.Enneper(); enneper Parametrized surface ('Enneper's surface') with equation (-1/9*(u^2 - 3*v^2 - 3)*u, -1/9*(3*u^2 - v^2 + 3)*v, 1/3*u^2 - 1/3*v^2) - sage: enneper.plot(aspect_ratio='automatic') + sage: enneper.plot(aspect_ratio='automatic') # optional - sage.plot Graphics3d Object We construct an ellipsoid whose axes are given by symbolic variables `a`, @@ -314,7 +314,7 @@ class ParametrizedSurface3D(SageObject): sage: g1 = [c[-1] for c in S.geodesics_numerical((0,0),(1,0),(0,2*pi,100))] sage: g2 = [c[-1] for c in S.geodesics_numerical((0,0),(cos(pi/3),sin(pi/3)),(0,2*pi,100))] sage: g3 = [c[-1] for c in S.geodesics_numerical((0,0),(cos(2*pi/3),sin(2*pi/3)),(0,2*pi,100))] - sage: (S.plot(opacity=0.3) + line3d(g1,color='red') + line3d(g2,color='red') + line3d(g3,color='red')).show() + sage: (S.plot(opacity=0.3) + line3d(g1,color='red') + line3d(g2,color='red') + line3d(g3,color='red')).show() # optional - sage.plot """ @@ -488,7 +488,7 @@ def plot(self, urange=None, vrange=None, **kwds): sage: u, v = var('u, v', domain='real') sage: eq = (3*u + 3*u*v^2 - u^3, 3*v + 3*u^2*v - v^3, 3*(u^2-v^2)) sage: enneper = ParametrizedSurface3D(eq, (u, v), 'Enneper Surface') - sage: enneper.plot((-5, 5), (-5, 5)) + sage: enneper.plot((-5, 5), (-5, 5)) # optional - sage.plot Graphics3d Object """ diff --git a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py index 078af43b338..3619c6c2952 100644 --- a/src/sage/geometry/riemannian_manifolds/surface3d_generators.py +++ b/src/sage/geometry/riemannian_manifolds/surface3d_generators.py @@ -53,7 +53,7 @@ def Catenoid(c=1, name="Catenoid"): sage: cat = surfaces.Catenoid(); cat Parametrized surface ('Catenoid') with equation (cos(u)*cosh(v), cosh(v)*sin(u), v) - sage: cat.plot() + sage: cat.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -86,7 +86,7 @@ def Crosscap(r=1, name="Crosscap"): sage: crosscap = surfaces.Crosscap(); crosscap Parametrized surface ('Crosscap') with equation ((cos(v) + 1)*cos(u), (cos(v) + 1)*sin(u), -sin(v)*tanh(-pi + u)) - sage: crosscap.plot() + sage: crosscap.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -120,7 +120,7 @@ def Dini(a=1, b=1, name="Dini's surface"): sage: dini = surfaces.Dini(a=3, b=4); dini Parametrized surface ('Dini's surface') with equation (3*cos(u)*sin(v), 3*sin(u)*sin(v), 4*u + 3*cos(v) + 3*log(tan(1/2*v))) - sage: dini.plot() + sage: dini.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -158,7 +158,7 @@ def Ellipsoid(center=(0, 0, 0), axes=(1, 1, 1), name="Ellipsoid"): sage: ell = surfaces.Ellipsoid(axes=(1, 2, 3)); ell Parametrized surface ('Ellipsoid') with equation (cos(u)*cos(v), 2*cos(v)*sin(u), 3*sin(v)) - sage: ell.plot() + sage: ell.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -193,7 +193,7 @@ def Enneper(name="Enneper's surface"): sage: enn = surfaces.Enneper(); enn Parametrized surface ('Enneper's surface') with equation (-1/9*(u^2 - 3*v^2 - 3)*u, -1/9*(3*u^2 - v^2 + 3)*v, 1/3*u^2 - 1/3*v^2) - sage: enn.plot() + sage: enn.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -227,7 +227,7 @@ def Helicoid(h=1, name="Helicoid"): sage: helicoid = surfaces.Helicoid(h=2); helicoid Parametrized surface ('Helicoid') with equation (rho*cos(theta), rho*sin(theta), theta/pi) - sage: helicoid.plot() + sage: helicoid.plot() # optional - sage.plot Graphics3d Object """ rho, theta = var('rho, theta') @@ -260,7 +260,7 @@ def Klein(r=1, name="Klein bottle"): sage: klein = surfaces.Klein(); klein Parametrized surface ('Klein bottle') with equation (-(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*cos(u), -(sin(1/2*u)*sin(2*v) - cos(1/2*u)*sin(v) - 1)*sin(u), cos(1/2*u)*sin(2*v) + sin(1/2*u)*sin(v)) - sage: klein.plot() + sage: klein.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -291,7 +291,7 @@ def MonkeySaddle(name="Monkey saddle"): sage: saddle = surfaces.MonkeySaddle(); saddle Parametrized surface ('Monkey saddle') with equation (u, v, u^3 - 3*u*v^2) - sage: saddle.plot() + sage: saddle.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -327,12 +327,12 @@ def Paraboloid(a=1, b=1, c=1, elliptic=True, name=None): sage: epar = surfaces.Paraboloid(1, 3, 2); epar Parametrized surface ('Elliptic paraboloid') with equation (u, v, 2*u^2 + 2/9*v^2) - sage: epar.plot() + sage: epar.plot() # optional - sage.plot Graphics3d Object sage: hpar = surfaces.Paraboloid(2, 3, 1, elliptic=False); hpar Parametrized surface ('Hyperbolic paraboloid') with equation (u, v, -1/4*u^2 + 1/9*v^2) - sage: hpar.plot() + sage: hpar.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -372,7 +372,7 @@ def Sphere(center=(0, 0, 0), R=1, name="Sphere"): sage: sphere = surfaces.Sphere(center=(0, 1, -1), R=2); sphere Parametrized surface ('Sphere') with equation (2*cos(u)*cos(v), 2*cos(v)*sin(u) + 1, 2*sin(v) - 1) - sage: sphere.plot() + sage: sphere.plot() # optional - sage.plot Graphics3d Object Note that the radius of the sphere can be negative. The surface thus @@ -382,14 +382,14 @@ def Sphere(center=(0, 0, 0), R=1, name="Sphere"): sage: octant1 = surfaces.Sphere(R=1); octant1 Parametrized surface ('Sphere') with equation (cos(u)*cos(v), cos(v)*sin(u), sin(v)) - sage: octant1.plot((0, pi/2), (0, pi/2)) + sage: octant1.plot((0, pi/2), (0, pi/2)) # optional - sage.plot Graphics3d Object with the first octant of the unit sphere with negative radius:: sage: octant2 = surfaces.Sphere(R=-1); octant2 Parametrized surface ('Sphere') with equation (-cos(u)*cos(v), -cos(v)*sin(u), -sin(v)) - sage: octant2.plot((0, pi/2), (0, pi/2)) + sage: octant2.plot((0, pi/2), (0, pi/2)) # optional - sage.plot Graphics3d Object """ return SurfaceGenerators.Ellipsoid(center, (R, R, R), name) @@ -421,7 +421,7 @@ def Torus(r=2, R=3, name="Torus"): sage: torus = surfaces.Torus(); torus Parametrized surface ('Torus') with equation ((2*cos(v) + 3)*cos(u), (2*cos(v) + 3)*sin(u), 2*sin(v)) - sage: torus.plot() + sage: torus.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') @@ -448,7 +448,7 @@ def WhitneyUmbrella(name="Whitney's umbrella"): sage: whitney = surfaces.WhitneyUmbrella(); whitney Parametrized surface ('Whitney's umbrella') with equation (u*v, u, v^2) - sage: whitney.plot() + sage: whitney.plot() # optional - sage.plot Graphics3d Object """ u, v = var('u, v') diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index e8920bfb701..87b32ec2fca 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -1048,7 +1048,7 @@ def plot(self, **options): EXAMPLES:: sage: N = ToricLattice(3) - sage: N.plot() + sage: N.plot() # optional - sage.plot Graphics3d Object """ if "show_lattice" not in options: @@ -1195,12 +1195,12 @@ def plot(self, **options): sage: N = ToricLattice(3) sage: sublattice = N.submodule_with_basis([(1,1,0), (3,2,1)]) - sage: sublattice.plot() + sage: sublattice.plot() # optional - sage.plot Graphics3d Object Now we plot both the ambient lattice and its sublattice:: - sage: N.plot() + sublattice.plot(point_color="red") + sage: N.plot() + sublattice.plot(point_color="red") # optional - sage.plot Graphics3d Object """ if "show_lattice" not in options: diff --git a/src/sage/geometry/toric_lattice_element.pyx b/src/sage/geometry/toric_lattice_element.pyx index 5e858f8773d..caaf1c2be93 100644 --- a/src/sage/geometry/toric_lattice_element.pyx +++ b/src/sage/geometry/toric_lattice_element.pyx @@ -394,7 +394,7 @@ cdef class ToricLatticeElement(Vector_integer_dense): sage: N = ToricLattice(3) sage: n = N(1,2,3) - sage: n.plot() + sage: n.plot() # optional - sage.plot Graphics3d Object """ tp = ToricPlotter(options, self.parent().degree()) diff --git a/src/sage/geometry/toric_plotter.py b/src/sage/geometry/toric_plotter.py index 5afd455ed20..086861ccc16 100644 --- a/src/sage/geometry/toric_plotter.py +++ b/src/sage/geometry/toric_plotter.py @@ -15,7 +15,7 @@ In most cases, this module is used indirectly, e.g. :: sage: fan = toric_varieties.dP6().fan() - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics object consisting of 31 graphics primitives You may change default plotting options as follows:: @@ -25,12 +25,12 @@ sage: toric_plotter.options(show_rays=False) sage: toric_plotter.options("show_rays") False - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics object consisting of 19 graphics primitives sage: toric_plotter.reset_options() sage: toric_plotter.options("show_rays") True - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics object consisting of 31 graphics primitives """ @@ -133,9 +133,9 @@ class ToricPlotter(SageObject): plot, e.g. :: sage: fan = toric_varieties.dP6().fan() - sage: fan.plot() + sage: fan.plot() # optional - sage.plot Graphics object consisting of 31 graphics primitives - sage: print(fan.plot()) + sage: print(fan.plot()) # optional - sage.plot Graphics object consisting of 31 graphics primitives If you do want to create your own plotting function for some toric diff --git a/src/sage/geometry/triangulation/element.py b/src/sage/geometry/triangulation/element.py index 9aea06b7fb5..c9a43dca642 100644 --- a/src/sage/geometry/triangulation/element.py +++ b/src/sage/geometry/triangulation/element.py @@ -23,7 +23,7 @@ sage: points = PointConfiguration(p) sage: triang = points.triangulate(); triang (<0,1,2,5>, <0,1,3,5>, <1,3,4,5>) - sage: triang.plot(axes=False) + sage: triang.plot(axes=False) # optional - sage.plot Graphics3d Object See :mod:`sage.geometry.triangulation.point_configuration` for more details. @@ -68,7 +68,7 @@ def triangulation_render_2d(triangulation, **kwds): sage: points = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) sage: triang = points.triangulate() - sage: triang.plot(axes=False, aspect_ratio=1) # indirect doctest + sage: triang.plot(axes=False, aspect_ratio=1) # indirect doctest # optional - sage.plot Graphics object consisting of 12 graphics primitives """ from sage.plot.all import point2d, line2d, polygon2d @@ -132,7 +132,7 @@ def triangulation_render_3d(triangulation, **kwds): sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]] sage: points = PointConfiguration(p) sage: triang = points.triangulate() - sage: triang.plot(axes=False) # indirect doctest + sage: triang.plot(axes=False) # indirect doctest # optional - sage.plot Graphics3d Object """ from sage.plot.plot3d.all import point3d, line3d, polygon3d @@ -416,7 +416,7 @@ def plot(self, **kwds): sage: triangulation = p.triangulate() sage: triangulation (<1,3,4>, <2,3,4>) - sage: triangulation.plot(axes=False) + sage: triangulation.plot(axes=False) # optional - sage.plot Graphics object consisting of 12 graphics primitives """ dim = self.point_configuration().dim() diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 0346c9cdac4..3d900609d4a 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -67,7 +67,7 @@ (2, 3, 4) sage: list(t) [(1, 3, 4), (2, 3, 4)] - sage: t.plot(axes=False) + sage: t.plot(axes=False) # optional - sage.plot Graphics object consisting of 12 graphics primitives .. PLOT:: @@ -98,7 +98,7 @@ sage: p = [[0,-1,-1],[0,0,1],[0,1,0], [1,-1,-1],[1,0,1],[1,1,0]] sage: points = PointConfiguration(p) sage: triang = points.triangulate() - sage: triang.plot(axes=False) + sage: triang.plot(axes=False) # optional - sage.plot Graphics3d Object .. PLOT:: @@ -119,7 +119,7 @@ 16 sage: len(nonregular) # optional - topcom 2 - sage: nonregular[0].plot(aspect_ratio=1, axes=False) # optional - topcom + sage: nonregular[0].plot(aspect_ratio=1, axes=False) # optional - topcom # optional - sage.plot Graphics object consisting of 25 graphics primitives sage: PointConfiguration.set_engine('internal') # to make doctests independent of TOPCOM @@ -1555,9 +1555,9 @@ def bistellar_flips(self): sage: pc.bistellar_flips() (((<0,1,3>, <0,2,3>), (<0,1,2>, <1,2,3>)),) sage: Tpos, Tneg = pc.bistellar_flips()[0] - sage: Tpos.plot(axes=False) + sage: Tpos.plot(axes=False) # optional - sage.plot Graphics object consisting of 11 graphics primitives - sage: Tneg.plot(axes=False) + sage: Tneg.plot(axes=False) # optional - sage.plot Graphics object consisting of 11 graphics primitives The 3d analog:: @@ -1572,7 +1572,7 @@ def bistellar_flips(self): sage: pc.bistellar_flips() (((<0,1,3>, <0,2,3>), (<0,1,2>, <1,2,3>)),) sage: Tpos, Tneg = pc.bistellar_flips()[0] - sage: Tpos.plot(axes=False) + sage: Tpos.plot(axes=False) # optional - sage.plot Graphics3d Object """ flips = [] @@ -2114,7 +2114,7 @@ def plot(self, **kwds): EXAMPLES:: sage: p = PointConfiguration([[0,0],[0,1],[1,0],[1,1],[-1,-1]]) - sage: p.plot(axes=False) + sage: p.plot(axes=False) # optional - sage.plot Graphics object consisting of 5 graphics primitives .. PLOT:: diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index 1859a5e0c1a..d5c7ee2fd24 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -264,16 +264,16 @@ def plot(self, cell_colors=None, **kwds): sage: P = [[0.671, 0.650], [0.258, 0.767], [0.562, 0.406], [0.254, 0.709], [0.493, 0.879]] - sage: V = VoronoiDiagram(P); S=V.plot() + sage: V = VoronoiDiagram(P); S=V.plot() # optional - sage.plot sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) - sage: S=V.plot(cell_colors={0:'red', 1:'blue', 2:'green', 3:'white', 4:'yellow'}) + sage: S=V.plot(cell_colors={0:'red', 1:'blue', 2:'green', 3:'white', 4:'yellow'}) # optional - sage.plot sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) - sage: S=V.plot(cell_colors=['red','blue','red','white', 'white']) + sage: S=V.plot(cell_colors=['red','blue','red','white', 'white']) # optional - sage.plot sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) - sage: S=V.plot(cell_colors='something else') + sage: S=V.plot(cell_colors='something else') # optional - sage.plot Traceback (most recent call last): ... AssertionError: 'cell_colors' must be a list or a dictionary @@ -282,7 +282,7 @@ def plot(self, cell_colors=None, **kwds): Trying to plot a Voronoi diagram of dimension other than 2 gives an error:: - sage: VoronoiDiagram([[1, 2, 3], [6, 5, 4]]).plot() + sage: VoronoiDiagram([[1, 2, 3], [6, 5, 4]]).plot() # optional - sage.plot Traceback (most recent call last): ... NotImplementedError: Plotting of 3-dimensional Voronoi diagrams not From 2fd3fdfa10cfd6f9364aab17567dc716b035108f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 10 Oct 2021 20:05:08 -0700 Subject: [PATCH 110/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx: Add '# optional - sage.combinat' for tests using combinatorial examples --- .../polyhedron/combinatorial_polyhedron/list_of_faces.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx index 5ea9711090d..a7794cb315c 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/list_of_faces.pyx @@ -41,9 +41,9 @@ Obtain the Vrepresentation of a polyhedron as facet-incidences:: sage: from sage.geometry.polyhedron.combinatorial_polyhedron.conversions \ ....: import incidence_matrix_to_bit_rep_of_Vrep - sage: P = polytopes.associahedron(['A',3]) - sage: face_list = incidence_matrix_to_bit_rep_of_Vrep(P.incidence_matrix()) - sage: face_list.compute_dimension() + sage: P = polytopes.associahedron(['A',3]) # optional - sage.combinat + sage: face_list = incidence_matrix_to_bit_rep_of_Vrep(P.incidence_matrix()) # optional - sage.combinat + sage: face_list.compute_dimension() # optional - sage.combinat 3 Obtain the facets of a polyhedron as :class:`ListOfFaces` from a facet list:: From 59246d48976cb466c4a83bc1595ba83721220d30 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 10 Oct 2021 20:09:07 -0700 Subject: [PATCH 111/378] src/sage/geometry/polyhedron/representation.py: Add '# optional - sage.rings.number_field' in doctests --- src/sage/geometry/polyhedron/representation.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/polyhedron/representation.py b/src/sage/geometry/polyhedron/representation.py index 443bea9224a..333f18e1787 100644 --- a/src/sage/geometry/polyhedron/representation.py +++ b/src/sage/geometry/polyhedron/representation.py @@ -791,8 +791,8 @@ def is_facet_defining_inequality(self, other): sage: Q = Polyhedron(ieqs=[[0,2,0,3]]) sage: Q.inequalities()[0].is_facet_defining_inequality(P) True - sage: Q = Polyhedron(ieqs=[[0,AA(2).sqrt(),0,3]]) - sage: Q.inequalities()[0].is_facet_defining_inequality(P) + sage: Q = Polyhedron(ieqs=[[0,AA(2).sqrt(),0,3]]) # optional - sage.rings.number_field + sage: Q.inequalities()[0].is_facet_defining_inequality(P) # optional - sage.rings.number_field True sage: Q = Polyhedron(ieqs=[[1,1,0,0]]) sage: Q.inequalities()[0].is_facet_defining_inequality(P) @@ -893,9 +893,9 @@ def _repr_(self): Test that :trac:`21105` has been fixed:: - sage: K. = NumberField(x^3 - 2, 'a', embedding=1.26) - sage: P = Polyhedron(vertices=[(1,1,cbrt2),(cbrt2,1,1)]) - sage: P.inequalities() + sage: K. = NumberField(x^3 - 2, 'a', embedding=1.26) # optional - sage.rings.number_field + sage: P = Polyhedron(vertices=[(1,1,cbrt2),(cbrt2,1,1)]) # optional - sage.rings.number_field + sage: P.inequalities() # optional - sage.rings.number_field (An inequality (-cbrt2^2 - cbrt2 - 1, 0, 0) x + cbrt2^2 + cbrt2 + 2 >= 0, An inequality (cbrt2^2 + cbrt2 + 1, 0, 0) x - cbrt2^2 + cbrt2 + 1 >= 0) """ From 03ea96d8e2634fda08b5f35bb7c482a129fc8959 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 11 Oct 2021 15:30:06 -0700 Subject: [PATCH 112/378] src/sage/geometry/polyhedron/backend_polymake.py: Add # optional - sage.rings.number_field --- .../geometry/polyhedron/backend_polymake.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/sage/geometry/polyhedron/backend_polymake.py b/src/sage/geometry/polyhedron/backend_polymake.py index 6f595395153..34082d9ee92 100644 --- a/src/sage/geometry/polyhedron/backend_polymake.py +++ b/src/sage/geometry/polyhedron/backend_polymake.py @@ -96,9 +96,12 @@ class Polyhedron_polymake(Polyhedron_base): Quadratic fields work:: - sage: V = polytopes.dodecahedron().vertices_list() - sage: Polyhedron(vertices=V, backend='polymake') # optional - polymake - A 3-dimensional polyhedron in (Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?)^3 defined as the convex hull of 20 vertices + sage: V = polytopes.dodecahedron().vertices_list() # optional - sage.rings.number_field + sage: Polyhedron(vertices=V, backend='polymake') # optional - polymake # optional - sage.rings.number_field + A 3-dimensional polyhedron + in (Number Field in sqrt5 with defining polynomial x^2 - 5 + with sqrt5 = 2.236067977499790?)^3 + defined as the convex hull of 20 vertices TESTS: @@ -662,11 +665,11 @@ def __setstate__(self, state): sage: P2 = Polyhedron_polymake(P1.parent(), None, None, P1._polymake_polytope) # optional - polymake sage: P._test_polymake_pickling(other=P2) # optional - polymake - sage: print("Possible output"); P = polytopes.dodecahedron(backend='polymake') # optional - polymake + sage: print("Possible output"); P = polytopes.dodecahedron(backend='polymake') # optional - polymake # optional - sage.rings.number_field Possible output... - sage: P1 = loads(dumps(P)) # optional - polymake - sage: P2 = Polyhedron_polymake(P1.parent(), None, None, P1._polymake_polytope) # optional - polymake - sage: P._test_polymake_pickling(other=P2) # optional - polymake + sage: P1 = loads(dumps(P)) # optional - polymake # optional - sage.rings.number_field + sage: P2 = Polyhedron_polymake(P1.parent(), None, None, P1._polymake_polytope) # optional - polymake # optional - sage.rings.number_field + sage: P._test_polymake_pickling(other=P2) # optional - polymake # optional - sage.rings.number_field """ if "_pickle_vertices" in state[1]: vertices = state[1].pop("_pickle_vertices") From c97428e2f1a8e10ef1167ff172ba297b2eaafb3c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 19:51:43 -0700 Subject: [PATCH 113/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx: fix typo --- .../combinatorial_polyhedron/combinatorial_face.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index a7affd611f7..98f3ab0c769 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -416,7 +416,7 @@ cdef class CombinatorialFace(SageObject): sage: v5.is_subface(face2) True - Only implemented for faces of the same combintatorial polyhedron:: + Only implemented for faces of the same combinatorial polyhedron:: sage: P1 = polytopes.cube() sage: C1 = P1.combinatorial_polyhedron() @@ -716,7 +716,7 @@ cdef class CombinatorialFace(SageObject): sage: P = polytopes.permutahedron(5) # optional - sage.combinat sage: C = CombinatorialPolyhedron(P) # optional - sage.combinat - sage: it = C.face_iter(2) # optional - sage.combinta + sage: it = C.face_iter(2) # optional - sage.combinat sage: next(it).ambient_Hrepresentation() # optional - sage.combinat (An inequality (1, 1, 1, 0, 0) x - 6 >= 0, An inequality (0, 0, 0, -1, 0) x + 5 >= 0, From 5fe8aa6e3219a6a68f2709049fe68a29e022c608 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 18 Sep 2021 18:47:33 -0700 Subject: [PATCH 114/378] src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx: Avoid imports from .all --- .../geometry/polyhedron/combinatorial_polyhedron/base.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx index 524933a01a8..f2f2c6da71b 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/base.pyx @@ -392,7 +392,7 @@ cdef class CombinatorialPolyhedron(SageObject): far_face = tuple(i for i in range(len(Vrep) - 1)) self._dimension = data.dim() from sage.matrix.constructor import matrix - from sage.rings.all import ZZ + from sage.rings.integer_ring import ZZ data = matrix(ZZ, data.incidence_matrix().rows() + [[ZZ.one() for _ in range(len(facets))]]) else: @@ -441,7 +441,7 @@ cdef class CombinatorialPolyhedron(SageObject): self._n_Vrepresentation = data.nrows() if not isinstance(data, Matrix_integer_dense): - from sage.rings.all import ZZ + from sage.rings.integer_ring import ZZ from sage.matrix.constructor import matrix data = matrix(ZZ, data, sparse=False) assert isinstance(data, Matrix_integer_dense), "conversion to ``Matrix_integer_dense`` didn't work" @@ -1675,7 +1675,7 @@ cdef class CombinatorialPolyhedron(SageObject): if not self._f_vector: raise ValueError("could not determine f_vector") from sage.modules.free_module_element import vector - from sage.rings.all import ZZ + from sage.rings.integer_ring import ZZ f_vector = vector(ZZ, self._f_vector) f_vector.set_immutable() return f_vector From 6d5ec0a671db15a1d6913038f07443c751ca2db5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Oct 2021 23:19:36 -0700 Subject: [PATCH 115/378] git grep -l 'all import cached' src/sage | xargs sed -E -i.bak $'s/^( *)from sage.*all import (cached_[a-z]*) *$/\1from sage.misc.cachefunc import \2/' --- src/sage/combinat/alternating_sign_matrix.py | 2 +- src/sage/combinat/cluster_algebra_quiver/mutation_type.py | 2 +- .../combinat/cluster_algebra_quiver/quiver_mutation_type.py | 2 +- src/sage/combinat/root_system/integrable_representations.py | 2 +- src/sage/combinat/root_system/root_system.py | 2 +- src/sage/combinat/sidon_sets.py | 4 ++-- src/sage/modular/modform/eisenstein_submodule.py | 2 +- src/sage/modules/filtered_vector_space.py | 2 +- src/sage/modules/multi_filtered_vector_space.py | 2 +- src/sage/monoids/automatic_semigroup.py | 2 +- src/sage/schemes/elliptic_curves/cm.py | 2 +- src/sage/schemes/elliptic_curves/padics.py | 2 +- src/sage/schemes/generic/scheme.py | 2 +- src/sage/schemes/toric/morphism.py | 2 +- src/sage/schemes/toric/sheaf/klyachko.py | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/sage/combinat/alternating_sign_matrix.py b/src/sage/combinat/alternating_sign_matrix.py index 057dbfe6e06..acc735174d8 100644 --- a/src/sage/combinat/alternating_sign_matrix.py +++ b/src/sage/combinat/alternating_sign_matrix.py @@ -44,7 +44,7 @@ from sage.matrix.matrix_space import MatrixSpace from sage.matrix.constructor import matrix from sage.modules.free_module_element import zero_vector -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.rings.integer_ring import ZZ from sage.arith.all import factorial from sage.rings.integer import Integer diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py index 7a843e423f3..79cfccb2a36 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_type.py @@ -25,7 +25,7 @@ from copy import copy -from sage.misc.all import cached_function +from sage.misc.cachefunc import cached_function from sage.misc.flatten import flatten from sage.graphs.all import DiGraph from sage.combinat.all import Combinations diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index f697451a99c..019a0cfd957 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -22,7 +22,7 @@ from sage.structure.sage_object import SageObject from copy import copy from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.rings.all import ZZ, infinity from sage.graphs.all import Graph, DiGraph from sage.arith.all import binomial, euler_phi diff --git a/src/sage/combinat/root_system/integrable_representations.py b/src/sage/combinat/root_system/integrable_representations.py index de677e03deb..2f39e19b8b2 100644 --- a/src/sage/combinat/root_system/integrable_representations.py +++ b/src/sage/combinat/root_system/integrable_representations.py @@ -15,7 +15,7 @@ from sage.structure.category_object import CategoryObject from sage.categories.modules import Modules from sage.rings.integer_ring import ZZ -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.matrix.constructor import Matrix from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet from sage.combinat.root_system.weyl_characters import WeylCharacterRing diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 9285d9b958b..49c0a9f05ac 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -20,7 +20,7 @@ from .cartan_type import CartanType from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from .root_space import RootSpace from .weight_space import WeightSpace diff --git a/src/sage/combinat/sidon_sets.py b/src/sage/combinat/sidon_sets.py index dda3cd07d76..431ad4c6d61 100644 --- a/src/sage/combinat/sidon_sets.py +++ b/src/sage/combinat/sidon_sets.py @@ -12,8 +12,8 @@ # https://www.gnu.org/licenses/ # **************************************************************************** from sage.sets.set import Set -from sage.misc.all import cached_function -from sage.rings.all import Integer +from sage.misc.cachefunc import cached_function +from sage.rings.integer import Integer def sidon_sets(N, g = 1): diff --git a/src/sage/modular/modform/eisenstein_submodule.py b/src/sage/modular/modform/eisenstein_submodule.py index a4fc4a1aa6f..ab041a78fc4 100644 --- a/src/sage/modular/modform/eisenstein_submodule.py +++ b/src/sage/modular/modform/eisenstein_submodule.py @@ -4,7 +4,7 @@ """ from sage.structure.all import Sequence -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method import sage.rings.all as rings from sage.categories.all import Objects from sage.matrix.all import Matrix diff --git a/src/sage/modules/filtered_vector_space.py b/src/sage/modules/filtered_vector_space.py index dd6608c6161..dd5784041eb 100644 --- a/src/sage/modules/filtered_vector_space.py +++ b/src/sage/modules/filtered_vector_space.py @@ -113,7 +113,7 @@ from sage.categories.fields import Fields from sage.modules.free_module import FreeModule_ambient_field, VectorSpace from sage.matrix.constructor import matrix -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method def is_FilteredVectorSpace(X): diff --git a/src/sage/modules/multi_filtered_vector_space.py b/src/sage/modules/multi_filtered_vector_space.py index 0d0e4b316e7..61e4754452e 100644 --- a/src/sage/modules/multi_filtered_vector_space.py +++ b/src/sage/modules/multi_filtered_vector_space.py @@ -43,7 +43,7 @@ from sage.rings.infinity import infinity, minus_infinity from sage.categories.fields import Fields from sage.modules.free_module import FreeModule_ambient_field, VectorSpace -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.modules.filtered_vector_space import FilteredVectorSpace diff --git a/src/sage/monoids/automatic_semigroup.py b/src/sage/monoids/automatic_semigroup.py index b06df8af2f7..aa14bf11388 100644 --- a/src/sage/monoids/automatic_semigroup.py +++ b/src/sage/monoids/automatic_semigroup.py @@ -20,7 +20,7 @@ # **************************************************************************** import operator -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.categories.semigroups import Semigroups from sage.categories.sets_cat import Sets from sage.categories.monoids import Monoids diff --git a/src/sage/schemes/elliptic_curves/cm.py b/src/sage/schemes/elliptic_curves/cm.py index 7d3d20d15ff..b477d727563 100644 --- a/src/sage/schemes/elliptic_curves/cm.py +++ b/src/sage/schemes/elliptic_curves/cm.py @@ -41,7 +41,7 @@ is_fundamental_discriminant, PolynomialRing) -from sage.misc.all import cached_function +from sage.misc.cachefunc import cached_function @cached_function def hilbert_class_polynomial(D, algorithm=None): diff --git a/src/sage/schemes/elliptic_curves/padics.py b/src/sage/schemes/elliptic_curves/padics.py index 7c140199516..45d3fd9fcd2 100644 --- a/src/sage/schemes/elliptic_curves/padics.py +++ b/src/sage/schemes/elliptic_curves/padics.py @@ -39,7 +39,7 @@ sqrt = math.sqrt import sage.schemes.hyperelliptic_curves.monsky_washnitzer import sage.schemes.hyperelliptic_curves.hypellfrob -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method def __check_padic_hypotheses(self, p): r""" diff --git a/src/sage/schemes/generic/scheme.py b/src/sage/schemes/generic/scheme.py index f3b823e59d7..f26b0df2bc0 100644 --- a/src/sage/schemes/generic/scheme.py +++ b/src/sage/schemes/generic/scheme.py @@ -20,7 +20,7 @@ # **************************************************************************** from sage.structure.parent import Parent -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.rings.all import (ZZ, CommutativeRing) from sage.rings.ideal import is_Ideal from sage.structure.unique_representation import UniqueRepresentation diff --git a/src/sage/schemes/toric/morphism.py b/src/sage/schemes/toric/morphism.py index 7e891014a65..783a4b33a25 100644 --- a/src/sage/schemes/toric/morphism.py +++ b/src/sage/schemes/toric/morphism.py @@ -371,7 +371,7 @@ from sage.structure.sequence import Sequence from sage.rings.integer_ring import ZZ from sage.arith.all import gcd -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.matrix.constructor import matrix, identity_matrix from sage.modules.free_module_element import vector from sage.geometry.all import Cone, Fan diff --git a/src/sage/schemes/toric/sheaf/klyachko.py b/src/sage/schemes/toric/sheaf/klyachko.py index 0539f4204d3..338ec4bef7c 100644 --- a/src/sage/schemes/toric/sheaf/klyachko.py +++ b/src/sage/schemes/toric/sheaf/klyachko.py @@ -48,7 +48,7 @@ from sage.structure.all import SageObject from sage.structure.richcmp import richcmp_method, richcmp, richcmp_not_equal from sage.rings.integer_ring import ZZ -from sage.misc.all import cached_method +from sage.misc.cachefunc import cached_method from sage.matrix.constructor import vector, block_matrix, zero_matrix from sage.geometry.cone import is_Cone from sage.modules.multi_filtered_vector_space import MultiFilteredVectorSpace From 299bd0cdbddb27a1a65a77d2ad55e098014769b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Oct 2021 21:51:13 -0700 Subject: [PATCH 116/378] git grep -l 'all import .*Integer' src/sage | xargs sed -E -i.bak $'s/^( *)from sage.*all import Integer *$/\1from sage.rings.integer import Integer/' --- src/sage/algebras/free_algebra.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra.py | 10 +++++----- src/sage/algebras/steenrod/steenrod_algebra_bases.py | 4 ++-- src/sage/combinat/composition_signed.py | 2 +- src/sage/combinat/free_module.py | 2 +- src/sage/combinat/matrices/latin.py | 2 +- src/sage/combinat/species/series.py | 2 +- src/sage/combinat/species/series_order.py | 2 +- src/sage/combinat/species/species.py | 2 +- src/sage/combinat/words/lyndon_word.py | 2 +- src/sage/dynamics/arithmetic_dynamics/affine_ds.py | 2 +- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 2 +- src/sage/graphs/generators/families.py | 2 +- src/sage/graphs/graph_generators.py | 2 +- src/sage/groups/class_function.py | 2 +- src/sage/groups/finitely_presented_named.py | 2 +- src/sage/groups/libgap_mixin.py | 2 +- src/sage/groups/pari_group.py | 2 +- src/sage/interacts/library.py | 2 +- src/sage/interfaces/maxima_abstract.py | 4 ++-- src/sage/libs/eclib/interface.py | 2 +- src/sage/libs/eclib/mwrank.pyx | 2 +- src/sage/misc/misc.py | 2 +- src/sage/modular/btquotients/pautomorphicform.py | 2 +- src/sage/modular/modform/defaults.py | 2 +- .../modular/modform_hecketriangle/abstract_space.py | 2 +- src/sage/modular/modsym/manin_symbol_list.py | 2 +- src/sage/parallel/decorate.py | 2 +- src/sage/rings/padics/local_generic_element.pyx | 2 +- src/sage/schemes/affine/affine_morphism.py | 2 +- src/sage/schemes/projective/projective_morphism.py | 2 +- src/sage/symbolic/expression_conversions.py | 2 +- 32 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index b3dc47ba3ff..1f7728cdf6f 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -294,7 +294,7 @@ def create_key(self, base_ring, arg1=None, arg2=None, sparse=sparse, order=T) return tuple(degrees), R # normalise the generator names - from sage.all import Integer + from sage.rings.integer import Integer if isinstance(arg1, (Integer, int)): arg1, arg2 = arg2, arg1 if not names is None: diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 3eb15efd811..d9e1c31a215 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -2321,7 +2321,7 @@ def P(self, *nums): sage: SteenrodAlgebra(generic=True).P(2,0,1) P(2,0,1) """ - from sage.rings.all import Integer + from sage.rings.integer import Integer if self.basis_name() != 'milnor': return self(SteenrodAlgebra(p=self.prime(),generic=self._generic).P(*nums)) while nums and nums[-1] == 0: @@ -2542,7 +2542,7 @@ def pst(self,s,t): sage: SteenrodAlgebra(5).pst(3,5) P(0,0,0,0,125) """ - from sage.rings.all import Integer + from sage.rings.integer import Integer if self.basis_name() != 'milnor': return self(SteenrodAlgebra(p=self.prime(),generic=self._generic).pst(s,t)) if not isinstance(s, (Integer, int)) and s >= 0: @@ -2731,7 +2731,7 @@ def gen(self, i=0): P^1_1 """ from sage.rings.infinity import Infinity - from sage.rings.all import Integer + from sage.rings.integer import Integer p = self.prime() if not isinstance(i, (Integer, int)) and i >= 0: raise ValueError("%s is not a non-negative integer" % i) @@ -3586,7 +3586,7 @@ def may_weight(self): 3 """ from sage.rings.infinity import Infinity - from sage.rings.all import Integer + from sage.rings.integer import Integer p = self.prime() generic = self.parent()._generic if self == 0: @@ -3694,7 +3694,7 @@ def wall_height(self): sage: Sq(0,0,3).wall_height() [1, 2, 2, 1] """ - from sage.rings.all import Integer + from sage.rings.integer import Integer if self.parent()._generic: raise NotImplementedError("Wall height is not defined at odd primes.") if self == 0 or self == 1: diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index c759b8955cf..dd3b8912d79 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -479,7 +479,7 @@ def xi_degrees(n,p=2, reverse=True): sage: sage.algebras.steenrod.steenrod_algebra_bases.xi_degrees(400,p=17) [307, 18, 1] """ - from sage.rings.all import Integer + from sage.rings.integer import Integer if n <= 0: return [] N = Integer(n*(p-1) + 1) @@ -1029,7 +1029,7 @@ def sorting_pair(s,t,basis): # pair used for sorting the basis else: return (((), ()),) - from sage.rings.all import Integer + from sage.rings.integer import Integer from sage.rings.infinity import Infinity from sage.combinat.integer_vector_weighted import WeightedIntegerVectors profile = kwds.get("profile", None) diff --git a/src/sage/combinat/composition_signed.py b/src/sage/combinat/composition_signed.py index ae2b3b648bc..8d8b78bcd59 100644 --- a/src/sage/combinat/composition_signed.py +++ b/src/sage/combinat/composition_signed.py @@ -19,7 +19,7 @@ from sage.rings.integer_ring import ZZ from .composition import Compositions_n, Composition -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.arith.all import binomial diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index d9f5d7c8144..2ed9daae949 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -15,7 +15,7 @@ from sage.structure.parent import Parent from sage.structure.indexed_generators import IndexedGenerators, parse_indices_names from sage.modules.module import Module -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.structure.element import parent from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement from sage.sets.finite_enumerated_set import FiniteEnumeratedSet diff --git a/src/sage/combinat/matrices/latin.py b/src/sage/combinat/matrices/latin.py index 367facaa301..3274ed077e2 100644 --- a/src/sage/combinat/matrices/latin.py +++ b/src/sage/combinat/matrices/latin.py @@ -131,7 +131,7 @@ from sage.matrix.constructor import matrix from sage.rings.integer_ring import ZZ -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.matrix.matrix_integer_dense import Matrix_integer_dense from sage.groups.perm_gps.permgroup_element import PermutationGroupElement from sage.groups.perm_gps.constructor import PermutationGroupElement as PermutationConstructor diff --git a/src/sage/combinat/species/series.py b/src/sage/combinat/species/series.py index b312148a2f3..64862dd9d74 100644 --- a/src/sage/combinat/species/series.py +++ b/src/sage/combinat/species/series.py @@ -33,7 +33,7 @@ from .stream import Stream, Stream_class from .series_order import bounded_decrement, increment, inf, unk -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.misc.misc_c import prod from functools import partial from sage.misc.misc import is_iterator diff --git a/src/sage/combinat/species/series_order.py b/src/sage/combinat/species/series_order.py index 17fa96201c4..f4c42d032bd 100644 --- a/src/sage/combinat/species/series_order.py +++ b/src/sage/combinat/species/series_order.py @@ -11,7 +11,7 @@ In particular, the relevant section for this file can be found at http://www.risc.uni-linz.ac.at/people/hemmecke/AldorCombinat/combinatsu30.html. """ -from sage.rings.all import Integer +from sage.rings.integer import Integer class SeriesOrderElement: pass diff --git a/src/sage/combinat/species/species.py b/src/sage/combinat/species/species.py index 26a0c2e58ec..48bd74e2f2b 100644 --- a/src/sage/combinat/species/species.py +++ b/src/sage/combinat/species/species.py @@ -458,7 +458,7 @@ def __pow__(self, n): ... ValueError: only positive exponents are currently supported """ - from sage.rings.all import Integer + from sage.rings.integer import Integer import operator n = Integer(n) if n <= 0: diff --git a/src/sage/combinat/words/lyndon_word.py b/src/sage/combinat/words/lyndon_word.py index 16115350bc8..076124ad798 100644 --- a/src/sage/combinat/words/lyndon_word.py +++ b/src/sage/combinat/words/lyndon_word.py @@ -16,7 +16,7 @@ from sage.structure.parent import Parent from sage.combinat.composition import Composition, Compositions -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.arith.all import divisors, gcd, moebius, multinomial from sage.combinat.necklace import _sfc diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index 116ee4e12b9..59e03e3bb57 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -42,7 +42,7 @@ class initialization directly. from sage.matrix.constructor import identity_matrix from sage.misc.cachefunc import cached_method from sage.misc.classcall_metaclass import typecall -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.rings.finite_rings.finite_field_constructor import is_PrimeFiniteField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.fraction_field import FractionField diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 27f9c39b583..90283083044 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -67,7 +67,7 @@ class initialization directly. from sage.misc.classcall_metaclass import typecall from sage.misc.mrange import xmrange from sage.modules.free_module_element import vector -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.arith.all import gcd, lcm, next_prime, binomial, primes, moebius from sage.categories.finite_fields import FiniteFields from sage.rings.complex_mpfr import ComplexField diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 91003aae159..f68788aaddb 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -2821,7 +2821,7 @@ def HanoiTowerGraph(pegs, disks, labels=True, positions=True): """ # sanitize input - from sage.rings.all import Integer + from sage.rings.integer import Integer pegs = Integer(pegs) if pegs < 2: raise ValueError("Pegs for Tower of Hanoi graph should be two or greater (not %d)" % pegs) diff --git a/src/sage/graphs/graph_generators.py b/src/sage/graphs/graph_generators.py index 17d65711459..307c056744f 100644 --- a/src/sage/graphs/graph_generators.py +++ b/src/sage/graphs/graph_generators.py @@ -814,7 +814,7 @@ def extra_property(x): yield copyfun(gg) if copy else gg elif augment == 'edges': if vertices is None: - from sage.rings.all import Integer + from sage.rings.integer import Integer vertices = Integer(0) while True: for g in self(vertices, loops=loops, sparse=sparse): diff --git a/src/sage/groups/class_function.py b/src/sage/groups/class_function.py index 60d0318ac97..94abb43d5f6 100644 --- a/src/sage/groups/class_function.py +++ b/src/sage/groups/class_function.py @@ -26,7 +26,7 @@ from sage.structure.sage_object import SageObject from sage.structure.richcmp import richcmp, richcmp_method from sage.interfaces.gap import gap -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.rings.all import CyclotomicField from sage.libs.gap.element import GapElement from sage.libs.gap.libgap import libgap diff --git a/src/sage/groups/finitely_presented_named.py b/src/sage/groups/finitely_presented_named.py index fbaf8e29357..c9a534a75be 100644 --- a/src/sage/groups/finitely_presented_named.py +++ b/src/sage/groups/finitely_presented_named.py @@ -59,7 +59,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.groups.free_group import FreeGroup from sage.groups.finitely_presented import FinitelyPresentedGroup from sage.libs.gap.libgap import libgap diff --git a/src/sage/groups/libgap_mixin.py b/src/sage/groups/libgap_mixin.py index 16417aea5e0..e72b5a7aeb3 100644 --- a/src/sage/groups/libgap_mixin.py +++ b/src/sage/groups/libgap_mixin.py @@ -558,7 +558,7 @@ def character_table(self): #how gap handles these groups. G = self._gap_() cl = self.conjugacy_classes() - from sage.rings.all import Integer + from sage.rings.integer import Integer n = Integer(len(cl)) irrG = G.Irr() ct = [[irrG[i][j] for j in range(n)] for i in range(n)] diff --git a/src/sage/groups/pari_group.py b/src/sage/groups/pari_group.py index 128fc1b217d..027bb04b321 100644 --- a/src/sage/groups/pari_group.py +++ b/src/sage/groups/pari_group.py @@ -5,7 +5,7 @@ """ from sage.libs.pari import pari -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.groups.perm_gps.permgroup_named import TransitiveGroup diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 63b6ff674a4..07564615aa0 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -1612,7 +1612,7 @@ def cellular_automaton( rule_number: IntSlider(value=110, description=u'Rule number', max=255) size: IntSlider(value=6, description=u'size of graphic', max=11, min=1) """ - from sage.all import Integer + from sage.rings.integer import Integer if not 0 <= rule_number <= 255: raise ValueError('Invalid rule number') binary_digits = Integer(rule_number).digits(base=2) diff --git a/src/sage/interfaces/maxima_abstract.py b/src/sage/interfaces/maxima_abstract.py index 917059de0ab..af20ffddd21 100644 --- a/src/sage/interfaces/maxima_abstract.py +++ b/src/sage/interfaces/maxima_abstract.py @@ -981,7 +981,7 @@ def unit_quadratic_integer(self, n): sage: u.parent() Number Field in a with defining polynomial x^2 - 13 with a = 3.605551275463990? """ - from sage.rings.all import Integer + from sage.rings.integer import Integer from sage.rings.number_field.number_field import QuadraticField # Take square-free part so sqrt(n) doesn't get simplified # further by maxima @@ -1536,7 +1536,7 @@ def nintegral(self, var='x', a=0, b=1, sage: gp('intnum(x=0,1,exp(-sqrt(x)))') 0.52848223531423071361790491935415653021675547587292866196865279321015401702040079 """ - from sage.rings.all import Integer + from sage.rings.integer import Integer v = self.quad_qags(var, a, b, epsrel=desired_relative_error, limit=maximum_num_subintervals) return v[0], v[1], Integer(v[2]), Integer(v[3]) diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index a163cc31093..0da8527a589 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -27,7 +27,7 @@ """ import sys from sage.structure.sage_object import SageObject -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from .mwrank import _Curvedata, _two_descent, _mw, parse_point_list diff --git a/src/sage/libs/eclib/mwrank.pyx b/src/sage/libs/eclib/mwrank.pyx index 0c20771d558..d8f8b38c136 100644 --- a/src/sage/libs/eclib/mwrank.pyx +++ b/src/sage/libs/eclib/mwrank.pyx @@ -28,7 +28,7 @@ from cysignals.signals cimport sig_on, sig_off from sage.cpython.string cimport char_to_str, str_to_bytes from sage.cpython.string import FS_ENCODING from sage.libs.eclib cimport bigint, Curvedata, mw, two_descent -from sage.rings.all import Integer +from sage.rings.integer import Integer cdef extern from "wrap.cpp": ### misc functions ### diff --git a/src/sage/misc/misc.py b/src/sage/misc/misc.py index fbebd99b3a3..659e83b1208 100644 --- a/src/sage/misc/misc.py +++ b/src/sage/misc/misc.py @@ -759,7 +759,7 @@ def nest(f, n, x): x """ - from sage.rings.all import Integer + from sage.rings.integer import Integer n = Integer(n) if n < 0: diff --git a/src/sage/modular/btquotients/pautomorphicform.py b/src/sage/modular/btquotients/pautomorphicform.py index 5668569ae85..28f1618ee2e 100644 --- a/src/sage/modular/btquotients/pautomorphicform.py +++ b/src/sage/modular/btquotients/pautomorphicform.py @@ -47,7 +47,7 @@ from sage.matrix.matrix_space import MatrixSpace from sage.structure.element import ModuleElement from sage.modules.module import Module -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.matrix.constructor import Matrix, zero_matrix from sage.rings.all import Qp, QQ, ZZ from copy import copy diff --git a/src/sage/modular/modform/defaults.py b/src/sage/modular/modform/defaults.py index 3d064931119..d2b5127cb17 100644 --- a/src/sage/modular/modform/defaults.py +++ b/src/sage/modular/modform/defaults.py @@ -8,7 +8,7 @@ # The default precision for computation and display of q-expansions of # modular forms. -from sage.rings.all import Integer +from sage.rings.integer import Integer DEFAULT_PRECISION = Integer(6) DEFAULT_VARIABLE = 'q' diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index abea0961e0c..fcfaab1e788 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -23,7 +23,7 @@ from sage.modules.free_module_element import is_FreeModuleElement from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.structure.all import parent from sage.misc.cachefunc import cached_method diff --git a/src/sage/modular/modsym/manin_symbol_list.py b/src/sage/modular/modsym/manin_symbol_list.py index dc4226b5db5..187db53bd16 100644 --- a/src/sage/modular/modsym/manin_symbol_list.py +++ b/src/sage/modular/modsym/manin_symbol_list.py @@ -36,7 +36,7 @@ import sage.modular.modsym.p1list as p1list import sage.modular.modsym.g1list as g1list import sage.modular.modsym.ghlist as ghlist -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.structure.parent import Parent from sage.misc.persist import register_unpickle_override from sage.structure.richcmp import richcmp_method, richcmp diff --git a/src/sage/parallel/decorate.py b/src/sage/parallel/decorate.py index 37df8188691..43dd7a8142c 100644 --- a/src/sage/parallel/decorate.py +++ b/src/sage/parallel/decorate.py @@ -4,7 +4,7 @@ import types -from sage.rings.all import Integer +from sage.rings.integer import Integer from .reference import parallel_iter as p_iter_reference from .use_fork import p_iter_fork diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index 8d1dd7639c5..81f2fd7bc25 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -908,7 +908,7 @@ cdef class LocalGenericElement(CommutativeRingElement): from sage.categories.fields import Fields if self.parent() in Fields(): - from sage.rings.all import Integer + from sage.rings.integer import Integer return Integer(0) return self.valuation() diff --git a/src/sage/schemes/affine/affine_morphism.py b/src/sage/schemes/affine/affine_morphism.py index d8dae3b68a0..e95fe3001df 100644 --- a/src/sage/schemes/affine/affine_morphism.py +++ b/src/sage/schemes/affine/affine_morphism.py @@ -61,7 +61,7 @@ from sage.arith.all import gcd -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.rings.finite_rings.finite_field_constructor import is_PrimeFiniteField from sage.rings.fraction_field import FractionField from sage.rings.fraction_field_element import FractionFieldElement diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 1aa7ea7f841..c4c82707c5d 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -74,7 +74,7 @@ from sage.calculus.functions import jacobian -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic from sage.rings.complex_mpfr import ComplexField_class from sage.rings.complex_interval_field import ComplexIntervalField_class diff --git a/src/sage/symbolic/expression_conversions.py b/src/sage/symbolic/expression_conversions.py index 98d2820a361..36882314592 100644 --- a/src/sage/symbolic/expression_conversions.py +++ b/src/sage/symbolic/expression_conversions.py @@ -1542,7 +1542,7 @@ def arithmetic(self, ex, operator): if not any(repr(v) in self.varnames for v in ex.variables()): return self.base_ring(ex) elif operator == _operator.pow: - from sage.rings.all import Integer + from sage.rings.integer import Integer base, exp = ex.operands() return self(base)**Integer(exp) if operator == add_vararg: From 54fa2eef300e3f77bc912c5a3d4cac27fbe00087 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 3 Oct 2021 21:48:48 -0700 Subject: [PATCH 117/378] git grep -l 'all import .*GF' src/sage | xargs sed -E -i.bak $'s/^( *)from sage.*all import GF *$/\1from sage.rings.finite_rings.finite_field_constructor import GF/' --- src/sage/algebras/steenrod/steenrod_algebra.py | 10 +++++----- src/sage/algebras/steenrod/steenrod_algebra_bases.py | 2 +- src/sage/algebras/steenrod/steenrod_algebra_mult.py | 4 ++-- src/sage/groups/matrix_gps/unitary.py | 2 +- src/sage/interfaces/singular.py | 2 +- src/sage/modular/modform/ambient_R.py | 2 +- .../modules/free_quadratic_module_integer_symmetric.py | 2 +- src/sage/rings/fraction_field_FpT.pyx | 2 +- .../rings/padics/padic_capped_absolute_element.pyx | 2 +- .../rings/padics/padic_capped_relative_element.pyx | 2 +- src/sage/rings/padics/padic_fixed_mod_element.pyx | 2 +- src/sage/rings/padics/padic_floating_point_element.pyx | 2 +- src/sage/rings/padics/padic_valuation.py | 2 +- src/sage/rings/polynomial/polynomial_quotient_ring.py | 2 +- src/sage/schemes/elliptic_curves/saturation.py | 2 +- 15 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index d9e1c31a215..e7a01937e10 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -591,7 +591,7 @@ def __init__(self, p=2, basis='milnor', **kwds): from sage.sets.set_from_iterator import EnumeratedSetFromIterator from functools import partial from .steenrod_algebra_bases import steenrod_algebra_basis - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF profile = kwds.get('profile', None) truncation_type = kwds.get('truncation_type', 'auto') self._generic = kwds.get('generic') @@ -1088,7 +1088,7 @@ def homogeneous_component(self, n): sage: max([H[n].dimension() - G[n].dimension() for n in range(100)]) 0 """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF basis = self._basis_fcn(n) M = CombinatorialFreeModule(GF(self.prime()), basis, element_class=self.Element, @@ -1780,7 +1780,7 @@ def _change_basis_on_basis(self, t, basis='milnor'): P^4 P^2 + P^5 P^1 + P^6 """ from sage.matrix.constructor import matrix - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF from .steenrod_algebra_bases import steenrod_algebra_basis,\ convert_from_milnor_matrix from .steenrod_algebra_misc import get_basis_name @@ -2153,7 +2153,7 @@ def __contains__(self, x): sage: A_3.P(1) * A_3.Q(2) in B_3 False """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF p = self.prime() if x in GF(p): return True @@ -2478,7 +2478,7 @@ def an_element(self): sage: SteenrodAlgebra(basis='pst', profile=[3,2,1]).an_element() P^0_1 """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF basis = self.basis_name() p = self.prime() diff --git a/src/sage/algebras/steenrod/steenrod_algebra_bases.py b/src/sage/algebras/steenrod/steenrod_algebra_bases.py index dd3b8912d79..65b5fc89f6a 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_bases.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_bases.py @@ -163,7 +163,7 @@ def convert_to_milnor_matrix(n, basis, p=2, generic='auto'): [1 2 0] """ from sage.matrix.constructor import matrix - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF from .steenrod_algebra import SteenrodAlgebra if generic == 'auto': generic = False if p==2 else True diff --git a/src/sage/algebras/steenrod/steenrod_algebra_mult.py b/src/sage/algebras/steenrod/steenrod_algebra_mult.py index 3de17e9c138..2a359410217 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra_mult.py +++ b/src/sage/algebras/steenrod/steenrod_algebra_mult.py @@ -437,7 +437,7 @@ def milnor_multiplication_odd(m1,m2,p): iterate through the possible matrices: see http://mathweb.scranton.edu/monks/software/Steenrod/steen.html. """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF F = GF(p) (f,s) = m2 # First compute Q_e0 Q_e1 ... P(r1, r2, ...) Q_f0 Q_f1 ... @@ -890,7 +890,7 @@ def make_mono_admissible(mono, p=2, generic=None): sage: SteenrodAlgebra(p=2, basis='adem').Q(2) * (Sq(6) * Sq(2)) # indirect doctest Sq^10 Sq^4 Sq^1 + Sq^10 Sq^5 + Sq^12 Sq^3 + Sq^13 Sq^2 """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF if generic is None: generic = False if p==2 else True F = GF(p) diff --git a/src/sage/groups/matrix_gps/unitary.py b/src/sage/groups/matrix_gps/unitary.py index cefb9b5223b..c144e3b701b 100644 --- a/src/sage/groups/matrix_gps/unitary.py +++ b/src/sage/groups/matrix_gps/unitary.py @@ -49,7 +49,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.all import GF +from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.finite_rings.finite_field_base import is_FiniteField from sage.misc.latex import latex from sage.misc.cachefunc import cached_method diff --git a/src/sage/interfaces/singular.py b/src/sage/interfaces/singular.py index 4c5cf3dfd6b..08f5bcafb5b 100644 --- a/src/sage/interfaces/singular.py +++ b/src/sage/interfaces/singular.py @@ -1629,7 +1629,7 @@ def sage_global_ring(self): else: # it ought to be a finite field q = ZZ(charstr[0].lstrip('ZZ/')) - from sage.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF if q.is_prime(): br = GF(q) else: diff --git a/src/sage/modular/modform/ambient_R.py b/src/sage/modular/modform/ambient_R.py index 9bac23c8970..a99b080062f 100644 --- a/src/sage/modular/modform/ambient_R.py +++ b/src/sage/modular/modform/ambient_R.py @@ -109,7 +109,7 @@ def _compute_q_expansion_basis(self, prec=None): elif c.is_prime_power(): K = self.base_ring() p = K.characteristic().prime_factors()[0] - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF Kp = GF(p) newB = [f.change_ring(K) for f in list(self.__M.cuspidal_subspace().q_integral_basis(prec))] A = Kp**prec diff --git a/src/sage/modules/free_quadratic_module_integer_symmetric.py b/src/sage/modules/free_quadratic_module_integer_symmetric.py index d09578682ea..d872452021b 100644 --- a/src/sage/modules/free_quadratic_module_integer_symmetric.py +++ b/src/sage/modules/free_quadratic_module_integer_symmetric.py @@ -1050,7 +1050,7 @@ def maximal_overlattice(self, p=None): # and trac:11940 if not self.is_even() and (p is None or p==2): raise ValueError("This lattice must be even to admit an even overlattice") - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF L = self if p is None: P = ZZ(self.determinant()).prime_factors() diff --git a/src/sage/rings/fraction_field_FpT.pyx b/src/sage/rings/fraction_field_FpT.pyx index b81535fe5bd..58ee9bf3050 100644 --- a/src/sage/rings/fraction_field_FpT.pyx +++ b/src/sage/rings/fraction_field_FpT.pyx @@ -13,7 +13,7 @@ from cysignals.signals cimport sig_on, sig_off from sage.rings.finite_rings.stdint cimport INTEGER_MOD_INT32_LIMIT from sage.libs.gmp.mpz cimport * -from sage.rings.all import GF +from sage.rings.finite_rings.finite_field_constructor import GF from sage.libs.flint.nmod_poly cimport * from sage.libs.flint.ulong_extras cimport n_jacobi from sage.structure.element cimport Element, ModuleElement, FieldElement diff --git a/src/sage/rings/padics/padic_capped_absolute_element.pyx b/src/sage/rings/padics/padic_capped_absolute_element.pyx index 387dd7c8b65..12ecdc457e8 100644 --- a/src/sage/rings/padics/padic_capped_absolute_element.pyx +++ b/src/sage/rings/padics/padic_capped_absolute_element.pyx @@ -249,7 +249,7 @@ cdef class pAdicCappedAbsoluteElement(CAElement): cdef Integer selfvalue = Integer.__new__(Integer) mpz_set(selfvalue.value, self.value) if field: - from sage.rings.finite_rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.parent().prime())(selfvalue) else: return Mod(selfvalue, modulus) diff --git a/src/sage/rings/padics/padic_capped_relative_element.pyx b/src/sage/rings/padics/padic_capped_relative_element.pyx index bea6c17af19..7626d36cba5 100644 --- a/src/sage/rings/padics/padic_capped_relative_element.pyx +++ b/src/sage/rings/padics/padic_capped_relative_element.pyx @@ -353,7 +353,7 @@ cdef class pAdicCappedRelativeElement(CRElement): # Need to do this better. mpz_mul(selfvalue.value, self.prime_pow.pow_mpz_t_tmp(self.ordp), self.unit) if field: - from sage.rings.finite_rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.parent().prime())(selfvalue) else: return Mod(selfvalue, modulus) diff --git a/src/sage/rings/padics/padic_fixed_mod_element.pyx b/src/sage/rings/padics/padic_fixed_mod_element.pyx index e012cbba9fc..9a663986b19 100644 --- a/src/sage/rings/padics/padic_fixed_mod_element.pyx +++ b/src/sage/rings/padics/padic_fixed_mod_element.pyx @@ -319,7 +319,7 @@ cdef class pAdicFixedModElement(FMElement): selfvalue = PY_NEW(Integer) mpz_set(selfvalue.value, self.value) if field: - from sage.rings.finite_rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.parent().prime())(selfvalue) else: return Mod(selfvalue, modulus) diff --git a/src/sage/rings/padics/padic_floating_point_element.pyx b/src/sage/rings/padics/padic_floating_point_element.pyx index b3eb407918e..2111fa50934 100644 --- a/src/sage/rings/padics/padic_floating_point_element.pyx +++ b/src/sage/rings/padics/padic_floating_point_element.pyx @@ -316,7 +316,7 @@ cdef class pAdicFloatingPointElement(FPElement): # Need to do this better. mpz_mul(selfvalue.value, self.prime_pow.pow_mpz_t_tmp(self.ordp), self.unit) if field: - from sage.rings.finite_rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.parent().prime())(selfvalue) else: return Mod(selfvalue, modulus) diff --git a/src/sage/rings/padics/padic_valuation.py b/src/sage/rings/padics/padic_valuation.py index 5e552bd05f6..190c7cd5f89 100644 --- a/src/sage/rings/padics/padic_valuation.py +++ b/src/sage/rings/padics/padic_valuation.py @@ -1149,7 +1149,7 @@ def residue_ring(self): Finite Field of size 3 """ - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF return GF(self.p()) def _ge_(self, other): diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index b069cdd749c..52b7e1ff9f9 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -1888,7 +1888,7 @@ def _isomorphic_ring(self): # for a finite field, we return the isomorphic simple extensions of # the underlying prime field N = self.cardinality() - from sage.rings.all import GF + from sage.rings.finite_rings.finite_field_constructor import GF isomorphic_ring = GF(N) # the map to GF(N) maps our generator to a root of our modulus in the isomorphic_ring diff --git a/src/sage/schemes/elliptic_curves/saturation.py b/src/sage/schemes/elliptic_curves/saturation.py index 14b172cacbb..3af4d7e712b 100644 --- a/src/sage/schemes/elliptic_curves/saturation.py +++ b/src/sage/schemes/elliptic_curves/saturation.py @@ -50,7 +50,7 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.finite_rings.all import GF +from sage.rings.finite_rings.finite_field_constructor import GF from sage.rings.integer_ring import ZZ from sage.arith.all import kronecker_symbol as kro from sage.structure.sage_object import SageObject From 2446ec922d5ec0ed7bba5906a131ee3f65b185a2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:30:34 -0700 Subject: [PATCH 118/378] git grep -l 'import infinity *$' | xargs sed -i.bak 's/ sage.*all import infinity *$/ sage.rings.infinity import infinity/' --- src/sage/combinat/sf/elementary.py | 2 +- src/sage/combinat/sf/homogeneous.py | 2 +- src/sage/combinat/sf/powersum.py | 2 +- src/sage/rings/finite_rings/integer_mod.pyx | 2 +- .../function_field_valuation.py | 2 +- src/sage/rings/padics/local_generic.py | 4 ++-- .../rings/padics/local_generic_element.pyx | 2 +- src/sage/rings/padics/padic_valuation.py | 8 ++++---- .../rings/valuation/developing_valuation.py | 2 +- src/sage/rings/valuation/gauss_valuation.py | 4 ++-- .../rings/valuation/inductive_valuation.py | 6 +++--- src/sage/rings/valuation/limit_valuation.py | 8 ++++---- src/sage/rings/valuation/trivial_valuation.py | 4 ++-- src/sage/rings/valuation/valuation.py | 6 +++--- src/sage/rings/valuation/valuation_space.py | 20 +++++++++---------- src/sage/structure/gens_py.py | 4 ++-- 16 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/sage/combinat/sf/elementary.py b/src/sage/combinat/sf/elementary.py index 755c3cd51bd..5081f4760fe 100644 --- a/src/sage/combinat/sf/elementary.py +++ b/src/sage/combinat/sf/elementary.py @@ -21,7 +21,7 @@ from sage.combinat.partition import Partition from sage.misc.misc_c import prod from sage.arith.all import factorial, binomial -from sage.rings.all import infinity +from sage.rings.infinity import infinity ################################### # # diff --git a/src/sage/combinat/sf/homogeneous.py b/src/sage/combinat/sf/homogeneous.py index 98162e978dc..3157a9bf0eb 100644 --- a/src/sage/combinat/sf/homogeneous.py +++ b/src/sage/combinat/sf/homogeneous.py @@ -27,7 +27,7 @@ #################################### from . import multiplicative, classical from sage.combinat.partition import Partition -from sage.rings.all import infinity +from sage.rings.infinity import infinity from sage.misc.misc_c import prod from sage.arith.all import factorial, binomial diff --git a/src/sage/combinat/sf/powersum.py b/src/sage/combinat/sf/powersum.py index b4181b239eb..a1926baf803 100644 --- a/src/sage/combinat/sf/powersum.py +++ b/src/sage/combinat/sf/powersum.py @@ -20,7 +20,7 @@ from . import sfa, multiplicative, classical from sage.combinat.partition import Partition from sage.arith.all import divisors -from sage.rings.all import infinity +from sage.rings.infinity import infinity from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.misc.misc_c import prod diff --git a/src/sage/rings/finite_rings/integer_mod.pyx b/src/sage/rings/finite_rings/integer_mod.pyx index ab92c9a8ecb..b1320f4f08a 100644 --- a/src/sage/rings/finite_rings/integer_mod.pyx +++ b/src/sage/rings/finite_rings/integer_mod.pyx @@ -1892,7 +1892,7 @@ cdef class IntegerMod_abstract(FiniteRingElement): r += 1 power *= p if not power.divides(self.__modulus.sageInteger): - from sage.rings.all import infinity + from sage.rings.infinity import infinity return infinity return r diff --git a/src/sage/rings/function_field/function_field_valuation.py b/src/sage/rings/function_field/function_field_valuation.py index bff8ad4b1b3..40d82791499 100644 --- a/src/sage/rings/function_field/function_field_valuation.py +++ b/src/sage/rings/function_field/function_field_valuation.py @@ -923,7 +923,7 @@ def simplify(self, f, error=None, force=False): # if the caller was sure that we should simplify, then we should try to do the best simplification possible error = self(f) if force else self.upper_bound(f) - from sage.all import infinity + from sage.rings.infinity import infinity if error is infinity: return f diff --git a/src/sage/rings/padics/local_generic.py b/src/sage/rings/padics/local_generic.py index 69cc9026bb9..a468efdbdec 100644 --- a/src/sage/rings/padics/local_generic.py +++ b/src/sage/rings/padics/local_generic.py @@ -1055,7 +1055,7 @@ def _test_add_bigoh(self, **options): tester = self._tester(**options) for x in tester.some_elements(): tester.assertEqual(x.add_bigoh(x.precision_absolute()), x) - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester.assertEqual(x.add_bigoh(infinity), x) tester.assertEqual(x.add_bigoh(x.precision_absolute()+1), x) @@ -1276,7 +1276,7 @@ def _matrix_smith_form(self, M, transformation, integral, exact): [O(5^10) O(5^10)] [O(5^10) O(5^10)] """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity from .precision_error import PrecisionError from copy import copy n = M.nrows() diff --git a/src/sage/rings/padics/local_generic_element.pyx b/src/sage/rings/padics/local_generic_element.pyx index 8d1dd7639c5..2a1c0b32dac 100644 --- a/src/sage/rings/padics/local_generic_element.pyx +++ b/src/sage/rings/padics/local_generic_element.pyx @@ -997,7 +997,7 @@ cdef class LocalGenericElement(CommutativeRingElement): from sage.categories.all import Fields if self.parent() in Fields(): v = self.valuation() - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self.valuation() is not infinity: shift = shift << v diff --git a/src/sage/rings/padics/padic_valuation.py b/src/sage/rings/padics/padic_valuation.py index 5e552bd05f6..7efc8513961 100644 --- a/src/sage/rings/padics/padic_valuation.py +++ b/src/sage/rings/padics/padic_valuation.py @@ -48,7 +48,7 @@ from sage.structure.factory import UniqueFactory from sage.misc.cachefunc import cached_method -from sage.rings.all import infinity +from sage.rings.infinity import infinity class PadicValuationFactory(UniqueFactory): r""" @@ -1068,7 +1068,7 @@ def simplify(self, x, error=None, force=False): if error is None: error = self(x) - from sage.rings.all import infinity + from sage.rings.infinity import infinity if error is infinity: return x # we need to scale by the ramification index because p-adics use a @@ -1245,7 +1245,7 @@ def simplify(self, x, error=None, force=False, size_heuristic_bound=32): v = self(x) if error is None: error = v - from sage.rings.all import infinity + from sage.rings.infinity import infinity if error is infinity: return x if error < v: @@ -1326,7 +1326,7 @@ def inverse(self, x, precision): if precision <= 0: return self.domain().one() - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self(x) > 0 or precision is infinity: raise ValueError("element has no approximate inverse in this ring") diff --git a/src/sage/rings/valuation/developing_valuation.py b/src/sage/rings/valuation/developing_valuation.py index ab06e85791e..3750d777bd1 100644 --- a/src/sage/rings/valuation/developing_valuation.py +++ b/src/sage/rings/valuation/developing_valuation.py @@ -289,7 +289,7 @@ def _call_(self, f): """ f = self.domain().coerce(f) - from sage.rings.all import infinity + from sage.rings.infinity import infinity if f.is_zero(): return infinity diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index 557edc00149..b329466617e 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -795,7 +795,7 @@ def lower_bound(self, f): 1 """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity coefficients = f.coefficients(sparse=True) coefficients.reverse() ret = infinity @@ -826,7 +826,7 @@ def upper_bound(self, f): f = self.domain().coerce(f) coefficients = f.coefficients(sparse=True) if not coefficients: - from sage.rings.all import infinity + from sage.rings.infinity import infinity return infinity else: return self._base_valuation.upper_bound(coefficients[-1]) diff --git a/src/sage/rings/valuation/inductive_valuation.py b/src/sage/rings/valuation/inductive_valuation.py index f4b9090f1af..56aee6ef9e3 100644 --- a/src/sage/rings/valuation/inductive_valuation.py +++ b/src/sage/rings/valuation/inductive_valuation.py @@ -803,7 +803,7 @@ def mac_lane_step(self, G, principal_part_bound=None, assume_squarefree=False, a if check and not assume_squarefree and not G.is_squarefree(): raise ValueError("G must be squarefree") - from sage.rings.all import infinity + from sage.rings.infinity import infinity assert self(G) is not infinity # this is a valuation and G is non-zero ret = [] @@ -1105,7 +1105,7 @@ def _equivalence_reduction(self, f, coefficients=None, valuations=None, degree_b R = self.equivalence_unit(-valuation) R = next(self.coefficients(R)) fR_valuations = [vv - valuation for vv in valuations] - from sage.rings.all import infinity + from sage.rings.infinity import infinity fR_coefficients = [next(self.coefficients(c * R)) if vv is not infinity and vv == 0 else 0 for c, vv in zip(coefficients, fR_valuations)] @@ -1566,7 +1566,7 @@ def _test_lift_to_key(self, **options): # check that augmentation produces a valuation with roots of F # in the residue ring - from sage.rings.all import infinity + from sage.rings.infinity import infinity w = self.augmentation(f, infinity) F = F.change_ring(w.residue_ring()) roots = F.roots(multiplicities=False) diff --git a/src/sage/rings/valuation/limit_valuation.py b/src/sage/rings/valuation/limit_valuation.py index f3c89f2b704..1b6e85983de 100644 --- a/src/sage/rings/valuation/limit_valuation.py +++ b/src/sage/rings/valuation/limit_valuation.py @@ -346,7 +346,7 @@ def _repr_(self): [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2 , … ] """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity from .augmented_valuation import AugmentedValuation_base if self._initial_approximation(self._G) is not infinity: if isinstance(self._initial_approximation, AugmentedValuation_base): @@ -489,7 +489,7 @@ def _call_(self, f): """ self._improve_approximation_for_call(f) if self._G.divides(f): - from sage.rings.all import infinity + from sage.rings.infinity import infinity return infinity return self._approximation(f) @@ -519,7 +519,7 @@ def _improve_approximation(self): [ Gauss valuation induced by 2-adic valuation, v(t + 1) = 1/2, v(t^2 + 1) = +Infinity ] """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self._approximation(self._G) is infinity: # an infinite valuation can not be improved further return @@ -585,7 +585,7 @@ def _improve_approximation_for_call(self, f): for all future computations.) """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self._approximation(self._approximation.phi()) is infinity: # an infinite valuation can not be improved further return diff --git a/src/sage/rings/valuation/trivial_valuation.py b/src/sage/rings/valuation/trivial_valuation.py index 8d1070bf5cf..abf91cdc025 100644 --- a/src/sage/rings/valuation/trivial_valuation.py +++ b/src/sage/rings/valuation/trivial_valuation.py @@ -174,7 +174,7 @@ def _call_(self, x): +Infinity """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity return infinity def _repr_(self): @@ -302,7 +302,7 @@ def _call_(self, x): 0 """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity return infinity if x == 0 else self.codomain().zero() def _repr_(self): diff --git a/src/sage/rings/valuation/valuation.py b/src/sage/rings/valuation/valuation.py index 3c75e0a22cc..947cc804b28 100644 --- a/src/sage/rings/valuation/valuation.py +++ b/src/sage/rings/valuation/valuation.py @@ -108,7 +108,7 @@ def is_equivalent(self, f, g): True """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self(f) is infinity: return self(g) is infinity @@ -879,7 +879,7 @@ def mac_lane_approximant(self, G, valuation, approximants = None): # Check that valuation is an approximant for a valuation # on domain that extends its restriction to the base field. - from sage.rings.all import infinity + from sage.rings.infinity import infinity if valuation(G) is not infinity: v = valuation while not v.is_gauss_valuation(): @@ -982,7 +982,7 @@ def montes_factorization(self, G, assume_squarefree=False, required_precision=No """ if required_precision is None: - from sage.rings.all import infinity + from sage.rings.infinity import infinity required_precision = infinity R = G.parent() diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 705e3831799..09a321b9ba7 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -364,7 +364,7 @@ def is_trivial(self): False """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity if self(self.domain().one()) is infinity: # the constant infinity return True @@ -689,7 +689,7 @@ def scale(self, scalar): +Infinity """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity if scalar is infinity: from .trivial_valuation import TrivialPseudoValuation return TrivialPseudoValuation(self.domain()) @@ -796,7 +796,7 @@ def _strictly_separating_element(self, other): 2/3 """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity numerator = self._weakly_separating_element(other) n = self(numerator) @@ -1081,7 +1081,7 @@ def _test_is_negative_pseudo_valuation(self, **options): if not self.is_negative_pseudo_valuation(): X = self.domain().some_elements() for x in tester.some_elements(X): - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester.assertNotEqual(self(x), -infinity) def _test_bounds(self, **options): @@ -1246,7 +1246,7 @@ def _test_infinite_zero(self, **options): """ tester = self._tester(**options) - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester.assertEqual(self(self.domain().zero()), infinity) def _test_mul(self, **options): @@ -1263,7 +1263,7 @@ def _test_mul(self, **options): S = self.domain().some_elements() from itertools import product for x,y in tester.some_elements(product(S,S)): - from sage.rings.all import infinity + from sage.rings.infinity import infinity if set([self(x), self(y)]) == set([infinity, -infinity]): continue tester.assertEqual(self(x*y),self(x)+self(y)) @@ -1293,7 +1293,7 @@ def _test_no_infinite_units(self, **options): if self.is_negative_pseudo_valuation(): return - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester = self._tester(**options) for x in tester.some_elements(self.domain().some_elements()): if self(x) is infinity: @@ -1309,7 +1309,7 @@ def _test_value_group(self, **options): sage: v._test_value_group() """ - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester = self._tester(**options) # check consistency of trivial valuations first if self.is_trivial(): @@ -1523,7 +1523,7 @@ def _test_no_infinite_nonzero(self, **options): if not self.is_discrete_valuation(): return - from sage.rings.all import infinity + from sage.rings.infinity import infinity tester = self._tester(**options) for x in tester.some_elements(self.domain().some_elements()): if self(x) is infinity: @@ -1630,7 +1630,7 @@ def _test_inverse(self, **options): tester = self._tester(**options) for x in tester.some_elements(self.domain().some_elements()): - from sage.rings.all import infinity + from sage.rings.infinity import infinity for prec in (0, 1, 42, infinity): try: y = self.inverse(x, prec) diff --git a/src/sage/structure/gens_py.py b/src/sage/structure/gens_py.py index 2ff623adfad..c5a4bca56ec 100644 --- a/src/sage/structure/gens_py.py +++ b/src/sage/structure/gens_py.py @@ -19,7 +19,7 @@ def multiplicative_iterator(M): - from sage.rings.all import infinity + from sage.rings.infinity import infinity G = M.gens() if len(G) == 0: yield M(1) @@ -46,7 +46,7 @@ def multiplicative_iterator(M): def abelian_iterator(M): - from sage.rings.all import infinity + from sage.rings.infinity import infinity G = M.gens() if len(G) == 0: yield M(0) From 9b83d92deedf1d87a781c2a94b621768d7edef0b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:43:17 -0700 Subject: [PATCH 119/378] src/sage/combinat: Remove all-import of infinity --- src/sage/combinat/cluster_algebra_quiver/cluster_seed.py | 6 ++++-- src/sage/combinat/cluster_algebra_quiver/mutation_class.py | 3 ++- src/sage/combinat/cluster_algebra_quiver/quiver.py | 4 +++- .../cluster_algebra_quiver/quiver_mutation_type.py | 7 ++++--- src/sage/combinat/combinat.py | 5 ++++- src/sage/combinat/sf/sfa.py | 6 +++++- 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py index 59abf94470f..dc7b23b4d78 100644 --- a/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py +++ b/src/sage/combinat/cluster_algebra_quiver/cluster_seed.py @@ -37,9 +37,11 @@ from itertools import islice from sage.structure.sage_object import SageObject from copy import copy -from sage.rings.all import QQ, infinity +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity from sage.rings.integer_ring import ZZ -from sage.rings.all import FractionField, PolynomialRing +from sage.rings.fraction_field import FractionField +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.fraction_field_element import FractionFieldElement from sage.sets.all import Set from sage.graphs.digraph import DiGraph diff --git a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py index 32fe50b567d..f8954fcc00d 100644 --- a/src/sage/combinat/cluster_algebra_quiver/mutation_class.py +++ b/src/sage/combinat/cluster_algebra_quiver/mutation_class.py @@ -20,7 +20,8 @@ import time from sage.groups.perm_gps.partn_ref.refinement_graphs import search_tree, get_orbits -from sage.rings.all import ZZ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.infinity import infinity from sage.graphs.all import DiGraph from sage.combinat.cluster_algebra_quiver.quiver_mutation_type import _edge_list_to_matrix diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver.py b/src/sage/combinat/cluster_algebra_quiver/quiver.py index dedef28db11..48a9bd9164d 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver.py @@ -39,7 +39,9 @@ from sage.structure.sage_object import SageObject from copy import copy -from sage.rings.all import ZZ, CC, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.all import CC +from sage.rings.infinity import infinity from sage.graphs.all import Graph, DiGraph from sage.graphs.views import EdgesView from sage.arith.misc import gcd diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index f697451a99c..c6bd3d27056 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -22,11 +22,12 @@ from sage.structure.sage_object import SageObject from copy import copy from sage.structure.unique_representation import UniqueRepresentation -from sage.misc.all import cached_method -from sage.rings.all import ZZ, infinity +from sage.misc.cachefunc import cached_method +from sage.rings.integer_ring import ZZ +from sage.rings.infinite import infinity from sage.graphs.all import Graph, DiGraph from sage.arith.all import binomial, euler_phi -from sage.all import prod +from sage.misc.misc_c import prod from sage.matrix.constructor import matrix diff --git a/src/sage/combinat/combinat.py b/src/sage/combinat/combinat.py index d366cc15930..de9c86a2175 100644 --- a/src/sage/combinat/combinat.py +++ b/src/sage/combinat/combinat.py @@ -150,7 +150,10 @@ # **************************************************************************** from typing import Iterator -from sage.rings.all import ZZ, QQ, Integer, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.integer import Integer +from sage.rings.infinity import infinity from sage.arith.all import bernoulli, factorial from sage.rings.polynomial.polynomial_element import Polynomial from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing diff --git a/src/sage/combinat/sf/sfa.py b/src/sage/combinat/sf/sfa.py index 739b642ade1..baf6b62fd17 100644 --- a/src/sage/combinat/sf/sfa.py +++ b/src/sage/combinat/sf/sfa.py @@ -212,7 +212,11 @@ # http://www.gnu.org/licenses/ #***************************************************************************** from sage.misc.cachefunc import cached_method -from sage.rings.all import Integer, PolynomialRing, QQ, ZZ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.integer import Integer +from sage.rings.infinity import infinity +from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing from sage.rings.polynomial.polynomial_element import is_Polynomial from sage.rings.polynomial.multi_polynomial import is_MPolynomial from sage.combinat.partition import _Partitions, Partitions, Partitions_n, Partition From 0224b35edb5890b844f91a4a46f8b1e0aae0ee5c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:47:34 -0700 Subject: [PATCH 120/378] src/sage/rings/valuation: Remove all-import of infinity --- src/sage/rings/valuation/augmented_valuation.py | 3 ++- src/sage/rings/valuation/gauss_valuation.py | 3 ++- src/sage/rings/valuation/inductive_valuation.py | 3 ++- src/sage/rings/valuation/scaled_valuation.py | 3 ++- src/sage/rings/valuation/valuation_space.py | 4 +++- src/sage/rings/valuation/value_group.py | 4 +++- 6 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/sage/rings/valuation/augmented_valuation.py b/src/sage/rings/valuation/augmented_valuation.py index d733851bf7b..863a2c080d6 100644 --- a/src/sage/rings/valuation/augmented_valuation.py +++ b/src/sage/rings/valuation/augmented_valuation.py @@ -157,7 +157,8 @@ from .inductive_valuation import FinalInductiveValuation, NonFinalInductiveValuation, FiniteInductiveValuation, InfiniteInductiveValuation, InductiveValuation from sage.misc.cachefunc import cached_method -from sage.rings.all import infinity, QQ +from sage.rings.infinity import infinity +from sage.rings.rational_field import QQ from sage.structure.factory import UniqueFactory diff --git a/src/sage/rings/valuation/gauss_valuation.py b/src/sage/rings/valuation/gauss_valuation.py index b329466617e..ef59c605002 100644 --- a/src/sage/rings/valuation/gauss_valuation.py +++ b/src/sage/rings/valuation/gauss_valuation.py @@ -265,7 +265,8 @@ def valuations(self, f, coefficients=None, call_error=False): yield self._base_valuation(f[0]) return - from sage.rings.all import infinity, QQ + from sage.rings.infinity import infinity + from sage.rings.rational_field import QQ if f == self.domain().gen(): yield infinity yield QQ(0) diff --git a/src/sage/rings/valuation/inductive_valuation.py b/src/sage/rings/valuation/inductive_valuation.py index 56aee6ef9e3..31479167c15 100644 --- a/src/sage/rings/valuation/inductive_valuation.py +++ b/src/sage/rings/valuation/inductive_valuation.py @@ -413,7 +413,8 @@ def _test_EF(self, **options): tester = self._tester(**options) chain = self.augmentation_chain() for w,v in zip(chain, chain[1:]): - from sage.rings.all import infinity, ZZ + from sage.rings.infinity import infinity + from sage.rings.integer_ring import ZZ if w(w.phi()) is infinity: tester.assertEqual(w.E(), v.E()) tester.assertIn(w.E(), ZZ) diff --git a/src/sage/rings/valuation/scaled_valuation.py b/src/sage/rings/valuation/scaled_valuation.py index 70f6717eed1..6e34d3ce95d 100644 --- a/src/sage/rings/valuation/scaled_valuation.py +++ b/src/sage/rings/valuation/scaled_valuation.py @@ -46,7 +46,8 @@ def create_key(self, base, s): True """ - from sage.rings.all import infinity, QQ + from sage.rings.infinity import infinity + from sage.rings.rational_field import QQ if s is infinity or s not in QQ or s <= 0: # for these values we can not return a TrivialValuation() in # create_object() because that would override that instance's diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 09a321b9ba7..a8cc69f7312 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -161,7 +161,9 @@ def _get_action_(self, S, op, self_on_left): """ from operator import mul - from sage.rings.all import QQ, InfinityRing, ZZ + from sage.rings.infinity import infinity + from sage.rings.rational_field import QQ + from sage.rings.integer_ring import ZZ if op == mul and (S is InfinityRing or S is QQ or S is ZZ): return ScaleAction(S, self, not self_on_left, op) return None diff --git a/src/sage/rings/valuation/value_group.py b/src/sage/rings/valuation/value_group.py index bc5d0840df1..cc0edf113bc 100644 --- a/src/sage/rings/valuation/value_group.py +++ b/src/sage/rings/valuation/value_group.py @@ -28,7 +28,9 @@ from sage.structure.parent import Parent from sage.structure.unique_representation import UniqueRepresentation -from sage.rings.all import QQ, ZZ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity from sage.misc.cachefunc import cached_method From 3c5750cbb82ab0482a0b56f8ed7f23df632115c2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:49:13 -0700 Subject: [PATCH 121/378] src/sage/modular/abvar: Remove all-import of infinity --- src/sage/modular/abvar/lseries.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/modular/abvar/lseries.py b/src/sage/modular/abvar/lseries.py index 046b305f3ff..11ca70142a5 100644 --- a/src/sage/modular/abvar/lseries.py +++ b/src/sage/modular/abvar/lseries.py @@ -22,7 +22,11 @@ ########################################################################### from sage.structure.sage_object import SageObject -from sage.rings.all import Integer, infinity, ZZ, QQ, CC +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.integer import Integer +from sage.rings.infinity import infinity +from sage.rings.all import CC from sage.modules.free_module import span from sage.misc.misc_c import prod From aa797a5488d4110907d81e1a59d9a366c5f2ec8a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:50:52 -0700 Subject: [PATCH 122/378] src/sage/rings/polynomial: Remove all-import of infinity --- src/sage/rings/polynomial/real_roots.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/real_roots.pyx b/src/sage/rings/polynomial/real_roots.pyx index ba57c1ba4f6..ccebbfba87f 100644 --- a/src/sage/rings/polynomial/real_roots.pyx +++ b/src/sage/rings/polynomial/real_roots.pyx @@ -134,7 +134,10 @@ from https://wiki.sagemath.org/days4schedule . from copy import copy import time -from sage.rings.all import ZZ, QQ, RR, AA, RealField, RealIntervalField, RIF, RDF, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import RR, AA, RealField, RealIntervalField, RIF, RDF from sage.arith.all import binomial, factorial from sage.misc.randstate import randstate from sage.modules.all import vector, FreeModule From bb3ca7a8e3a4867480b7bb58008420aca4fafc48 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:57:02 -0700 Subject: [PATCH 123/378] src/sage/modular/modform_hecketriangle: Remove all-import of infinity --- src/sage/modular/modform_hecketriangle/abstract_ring.py | 5 ++++- src/sage/modular/modform_hecketriangle/abstract_space.py | 7 +++++-- src/sage/modular/modform_hecketriangle/constructor.py | 5 ++++- src/sage/modular/modform_hecketriangle/functors.py | 4 +++- src/sage/modular/modform_hecketriangle/graded_ring.py | 3 ++- .../modular/modform_hecketriangle/graded_ring_element.py | 4 +++- .../modform_hecketriangle/hecke_triangle_group_element.py | 4 +++- .../modular/modform_hecketriangle/hecke_triangle_groups.py | 5 ++++- .../modular/modform_hecketriangle/series_constructor.py | 5 ++++- src/sage/modular/modform_hecketriangle/space.py | 4 +++- 10 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/sage/modular/modform_hecketriangle/abstract_ring.py b/src/sage/modular/modform_hecketriangle/abstract_ring.py index 6d22fe7ab01..387d87f1b05 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_ring.py +++ b/src/sage/modular/modform_hecketriangle/abstract_ring.py @@ -16,7 +16,10 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import FractionField, PolynomialRing, PowerSeriesRing, ZZ, QQ, infinity +from sage.rings.infinity import infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.all import FractionField, PolynomialRing, PowerSeriesRing from sage.algebras.free_algebra import FreeAlgebra from sage.structure.parent import Parent diff --git a/src/sage/modular/modform_hecketriangle/abstract_space.py b/src/sage/modular/modform_hecketriangle/abstract_space.py index abea0961e0c..e073fc1b42c 100644 --- a/src/sage/modular/modform_hecketriangle/abstract_space.py +++ b/src/sage/modular/modform_hecketriangle/abstract_space.py @@ -16,14 +16,17 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, QQ, infinity, AlgebraicField, I +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import AlgebraicField, I from sage.rings.polynomial.polynomial_ring import is_PolynomialRing from sage.rings.power_series_ring import is_PowerSeriesRing from sage.rings.laurent_series_ring import is_LaurentSeriesRing from sage.modules.free_module_element import is_FreeModuleElement from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector -from sage.rings.all import Integer +from sage.rings.integer import Integer from sage.structure.all import parent from sage.misc.cachefunc import cached_method diff --git a/src/sage/modular/modform_hecketriangle/constructor.py b/src/sage/modular/modform_hecketriangle/constructor.py index 6a292e63b3f..5423fc47564 100644 --- a/src/sage/modular/modform_hecketriangle/constructor.py +++ b/src/sage/modular/modform_hecketriangle/constructor.py @@ -16,7 +16,10 @@ # https://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, QQ, infinity, PolynomialRing, FractionField +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import PolynomialRing, FractionField def rational_type(f, n=ZZ(3), base_ring=ZZ): diff --git a/src/sage/modular/modform_hecketriangle/functors.py b/src/sage/modular/modform_hecketriangle/functors.py index 103915c1af2..989f7b8e30e 100644 --- a/src/sage/modular/modform_hecketriangle/functors.py +++ b/src/sage/modular/modform_hecketriangle/functors.py @@ -16,7 +16,9 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.all import ZZ, QQ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity from sage.categories.functor import Functor from sage.categories.pushout import ConstructionFunctor diff --git a/src/sage/modular/modform_hecketriangle/graded_ring.py b/src/sage/modular/modform_hecketriangle/graded_ring.py index 03552c409ad..42325e3423e 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring.py @@ -16,7 +16,8 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.infinity import infinity from sage.rings.ring import CommutativeAlgebra from sage.categories.all import CommutativeAlgebras diff --git a/src/sage/modular/modform_hecketriangle/graded_ring_element.py b/src/sage/modular/modform_hecketriangle/graded_ring_element.py index 18f4957e0f5..bbea13eb078 100644 --- a/src/sage/modular/modform_hecketriangle/graded_ring_element.py +++ b/src/sage/modular/modform_hecketriangle/graded_ring_element.py @@ -16,7 +16,9 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, infinity, LaurentSeries, O +from sage.rings.integer_ring import ZZ +from sage.rings.infinity import infinity +from sage.rings.all import LaurentSeries, O from sage.functions.all import exp from sage.rings.number_field.number_field import QuadraticField from sage.symbolic.all import pi diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py index c2b9899602d..cf230339323 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_group_element.py @@ -20,7 +20,9 @@ from sage.misc.misc_c import prod from sage.misc.cachefunc import cached_method -from sage.rings.all import AA, QQbar, ZZ, infinity, CC +from sage.rings.integer_ring import ZZ +from sage.rings.infinity import infinity +from sage.rings.all import AA, QQbar, CC from sage.groups.matrix_gps.group_element import MatrixGroupElement_generic from sage.geometry.hyperbolic_space.hyperbolic_interface import HyperbolicPlane diff --git a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py index 7db8db7a192..1bede5f3a0a 100644 --- a/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py +++ b/src/sage/modular/modform_hecketriangle/hecke_triangle_groups.py @@ -16,7 +16,10 @@ # https://www.gnu.org/licenses/ # **************************************************************************** -from sage.rings.all import ZZ, QQ, AA, AlgebraicField, infinity, I, PolynomialRing, NumberField +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import AA, AlgebraicField, I, PolynomialRing, NumberField from sage.functions.all import cos, exp, sec from sage.functions.gamma import psi1 from sage.symbolic.all import pi diff --git a/src/sage/modular/modform_hecketriangle/series_constructor.py b/src/sage/modular/modform_hecketriangle/series_constructor.py index 7a19f1a639e..3ed32e7d77e 100644 --- a/src/sage/modular/modform_hecketriangle/series_constructor.py +++ b/src/sage/modular/modform_hecketriangle/series_constructor.py @@ -20,7 +20,10 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, QQ, infinity, PowerSeriesRing +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import PowerSeriesRing from sage.rings.big_oh import O from sage.arith.all import bernoulli, sigma, rising_factorial diff --git a/src/sage/modular/modform_hecketriangle/space.py b/src/sage/modular/modform_hecketriangle/space.py index 758b33420af..84323cf0ab9 100644 --- a/src/sage/modular/modform_hecketriangle/space.py +++ b/src/sage/modular/modform_hecketriangle/space.py @@ -16,7 +16,9 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.all import ZZ, QQ, infinity +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity from sage.modules.module import Module from sage.modules.free_module import FreeModule From 8e096f4766f59cfaea1e31b9b69f4c573683bace Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 22:58:00 -0700 Subject: [PATCH 124/378] src/sage/modular/modsym: Remove all-import of infinity --- src/sage/modular/modsym/space.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sage/modular/modsym/space.py b/src/sage/modular/modsym/space.py index a4b1378547e..4d818262a1c 100644 --- a/src/sage/modular/modsym/space.py +++ b/src/sage/modular/modsym/space.py @@ -31,7 +31,11 @@ import sage.modular.hecke.all as hecke from sage.arith.all import divisors, next_prime from sage.rings.fast_arith import prime_range -from sage.rings.all import PowerSeriesRing, Integer, QQ, ZZ, infinity, Zmod +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.integer import Integer +from sage.rings.infinity import infinity +from sage.rings.all import PowerSeriesRing, Zmod from sage.rings.number_field.number_field_base import is_NumberField from sage.structure.all import Sequence, SageObject from sage.structure.richcmp import (richcmp_method, richcmp, From 58eb1f9b9961521082f5c1c334d8f1a7abbfb87c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 23:00:08 -0700 Subject: [PATCH 125/378] src/sage/rings/valuation/valuation_space.py: Remove all-import of infinity --- src/sage/rings/valuation/valuation_space.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index a8cc69f7312..3acac1f8e82 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -1195,7 +1195,8 @@ def _test_scale(self, **options): """ tester = self._tester(**options) - from sage.rings.all import infinity, QQ + from sage.rings.rational_field import QQ + from sage.rings.infinity import infinity from .trivial_valuation import TrivialValuation, TrivialPseudoValuation tester.assertEqual(QQ(0)*self, TrivialValuation(self.domain())) From bc2d9700597861a712c7080a5a11ff8b3c2dbc71 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 20 Oct 2021 23:01:17 -0700 Subject: [PATCH 126/378] src/sage/schemes/elliptic_curves/height.py: Remove all-import of infinity --- src/sage/schemes/elliptic_curves/height.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/elliptic_curves/height.py b/src/sage/schemes/elliptic_curves/height.py index b717369aac8..de9cbc670de 100644 --- a/src/sage/schemes/elliptic_curves/height.py +++ b/src/sage/schemes/elliptic_curves/height.py @@ -30,9 +30,13 @@ import math import bisect -from sage.rings.all import (ZZ, QQ, RR, RDF, RIF, CC, CDF, CIF, infinity) +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.infinity import infinity +from sage.rings.all import RR, RDF, RIF, CC, CDF, CIF -from sage.misc.all import cached_method, cartesian_product_iterator +from sage.misc.cachefunc import cached_method +from sage.misc.all import cartesian_product_iterator from sage.arith.all import lcm, factorial from sage.ext.fast_callable import fast_callable from sage.functions.log import log, exp From c658a23ba1111a4a0b272b32eddae05a45cac162 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Oct 2021 09:52:51 -0700 Subject: [PATCH 127/378] src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py: Fix typo --- .../combinat/cluster_algebra_quiver/quiver_mutation_type.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py index c6bd3d27056..f13a8ab552f 100644 --- a/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +++ b/src/sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py @@ -24,7 +24,7 @@ from sage.structure.unique_representation import UniqueRepresentation from sage.misc.cachefunc import cached_method from sage.rings.integer_ring import ZZ -from sage.rings.infinite import infinity +from sage.rings.infinity import infinity from sage.graphs.all import Graph, DiGraph from sage.arith.all import binomial, euler_phi from sage.misc.misc_c import prod From 97861cd5bc0c1a516c8a01434754f71ccbfc6f79 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Oct 2021 09:54:42 -0700 Subject: [PATCH 128/378] src/sage/rings/valuation/valuation_space.py: Fix typo --- src/sage/rings/valuation/valuation_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/valuation/valuation_space.py b/src/sage/rings/valuation/valuation_space.py index 3acac1f8e82..759d9fc2981 100644 --- a/src/sage/rings/valuation/valuation_space.py +++ b/src/sage/rings/valuation/valuation_space.py @@ -161,7 +161,7 @@ def _get_action_(self, S, op, self_on_left): """ from operator import mul - from sage.rings.infinity import infinity + from sage.rings.infinity import InfinityRing from sage.rings.rational_field import QQ from sage.rings.integer_ring import ZZ if op == mul and (S is InfinityRing or S is QQ or S is ZZ): From 78de558b9d6e852d42c384a3f35b7d47731d8aa5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Oct 2021 16:13:05 -0700 Subject: [PATCH 129/378] src/sage/rings/real_double_element_gsl.pyx: Remove module-level import of sage.rings.complex_double to remove cyclic imports --- src/sage/rings/real_double_element_gsl.pyx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/real_double_element_gsl.pyx b/src/sage/rings/real_double_element_gsl.pyx index 3b446998886..f5d62d89d58 100644 --- a/src/sage/rings/real_double_element_gsl.pyx +++ b/src/sage/rings/real_double_element_gsl.pyx @@ -6,8 +6,6 @@ cimport libc.math from cysignals.signals cimport sig_on, sig_off -import sage.rings.complex_double - from sage.arith.constants cimport * from sage.libs.gsl.all cimport * @@ -52,7 +50,8 @@ cdef class RealDoubleElement_gsl(RealDoubleElement): return RealDoubleElement(float('nan')) if self._value < 0: if GSL_IS_EVEN(n): - return self._complex_double_(sage.rings.complex_double.CDF).nth_root(n) + from sage.rings.complex_double import CDF + return self._complex_double_(CDF).nth_root(n) else: return - ( (-self) ** (float(1)/n) ) else: From 2cc2fa71426e061bd030e85177766cd7c5dd05c4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Oct 2021 18:15:00 -0700 Subject: [PATCH 130/378] src/sage/rings/real_double.pyx: Replace cimport from cypari.convert by method-local import --- src/sage/rings/real_double.pyx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 7356600a482..2e22009fbef 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -56,8 +56,6 @@ gsl_set_error_handler_off() import math, operator -from cypari2.convert cimport new_gen_from_double - import sage.rings.integer import sage.rings.rational @@ -1669,6 +1667,7 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(1.5).__pari__() 1.50000000000000 """ + from cypari2.convert import new_gen_from_double return new_gen_from_double(self._value) From d641dc6a081eb018a694a78795e8a23097604757 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Oct 2021 18:15:57 -0700 Subject: [PATCH 131/378] src/sage/rings/complex_double.pyx: Move PARI conversion functions to src/sage/libs/pari/ --- .../libs/pari/convert_sage_complex_double.pxd | 6 +++ .../libs/pari/convert_sage_complex_double.pyx | 48 +++++++++++++++++ src/sage/rings/complex_double.pyx | 51 +++---------------- 3 files changed, 62 insertions(+), 43 deletions(-) create mode 100644 src/sage/libs/pari/convert_sage_complex_double.pxd create mode 100644 src/sage/libs/pari/convert_sage_complex_double.pyx diff --git a/src/sage/libs/pari/convert_sage_complex_double.pxd b/src/sage/libs/pari/convert_sage_complex_double.pxd new file mode 100644 index 00000000000..ded6cce2221 --- /dev/null +++ b/src/sage/libs/pari/convert_sage_complex_double.pxd @@ -0,0 +1,6 @@ +from cypari2.gen cimport Gen +from sage.rings.complex_double cimport ComplexDoubleElement + +cdef inline ComplexDoubleElement pari_to_cdf(Gen g) + +cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self) diff --git a/src/sage/libs/pari/convert_sage_complex_double.pyx b/src/sage/libs/pari/convert_sage_complex_double.pyx new file mode 100644 index 00000000000..308aa456ae4 --- /dev/null +++ b/src/sage/libs/pari/convert_sage_complex_double.pyx @@ -0,0 +1,48 @@ +from cysignals.signals cimport sig_on, sig_off + +from sage.libs.gsl.complex cimport * + +from cypari2.paridecl cimport * +from cypari2.convert cimport new_gen_from_double, new_t_COMPLEX_from_double + + +cdef inline ComplexDoubleElement pari_to_cdf(Gen g): + """ + Create a CDF element from a PARI ``gen``. + + EXAMPLES:: + + sage: CDF(pari("Pi")) + 3.141592653589793 + sage: CDF(pari("1 + I/2")) + 1.0 + 0.5*I + + TESTS: + + Check that we handle PARI errors gracefully, see :trac:`17329`:: + + sage: CDF(-151.386325246 + 992.34771962*I).zeta() + Traceback (most recent call last): + ... + PariError: overflow in t_REAL->double conversion + sage: CDF(pari(x^2 + 5)) + Traceback (most recent call last): + ... + PariError: incorrect type in gtofp (t_POL) + """ + cdef ComplexDoubleElement z = ComplexDoubleElement.__new__(ComplexDoubleElement) + sig_on() + if typ(g.g) == t_COMPLEX: + z._complex = gsl_complex_rect(gtodouble(gel(g.g, 1)), gtodouble(gel(g.g, 2))) + else: + z._complex = gsl_complex_rect(gtodouble(g.g), 0.0) + sig_off() + return z + + +cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self): + + if not self._complex.imag: + return new_gen_from_double(self._complex.real) + else: + return new_t_COMPLEX_from_double(self._complex.real, self._complex.imag) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index aa45ef96602..16b829519c1 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -70,12 +70,9 @@ AUTHORS: import operator from cpython.object cimport Py_NE -from cysignals.signals cimport sig_on, sig_off from sage.misc.randstate cimport randstate, current_randstate -from cypari2.paridecl cimport * - from sage.libs.gsl.complex cimport * cdef extern from "": @@ -92,8 +89,12 @@ from sage.structure.richcmp cimport rich_to_bool from sage.categories.morphism cimport Morphism from sage.structure.coerce cimport is_numpy_type -from cypari2.gen cimport Gen as pari_gen -from cypari2.convert cimport new_gen_from_double, new_t_COMPLEX_from_double +try: + from cypari2.gen import Gen as pari_gen + from cypari2.convert_sage_complex_double import pari_to_cdf + +except ImportError: + pari_gen = () from . import complex_mpfr @@ -718,38 +719,6 @@ def is_ComplexDoubleElement(x): """ return isinstance(x, ComplexDoubleElement) -cdef inline ComplexDoubleElement pari_to_cdf(pari_gen g): - """ - Create a CDF element from a PARI ``gen``. - - EXAMPLES:: - - sage: CDF(pari("Pi")) - 3.141592653589793 - sage: CDF(pari("1 + I/2")) - 1.0 + 0.5*I - - TESTS: - - Check that we handle PARI errors gracefully, see :trac:`17329`:: - - sage: CDF(-151.386325246 + 992.34771962*I).zeta() - Traceback (most recent call last): - ... - PariError: overflow in t_REAL->double conversion - sage: CDF(pari(x^2 + 5)) - Traceback (most recent call last): - ... - PariError: incorrect type in gtofp (t_POL) - """ - cdef ComplexDoubleElement z = ComplexDoubleElement.__new__(ComplexDoubleElement) - sig_on() - if typ(g.g) == t_COMPLEX: - z._complex = gsl_complex_rect(gtodouble(gel(g.g, 1)), gtodouble(gel(g.g, 2))) - else: - z._complex = gsl_complex_rect(gtodouble(g.g), 0.0) - sig_off() - return z cdef class ComplexDoubleElement(FieldElement): """ @@ -1161,10 +1130,8 @@ cdef class ComplexDoubleElement(FieldElement): sage: pari(CDF(I)) 1.00000000000000*I """ - if not self._complex.imag: - return new_gen_from_double(self._complex.real) - else: - return new_t_COMPLEX_from_double(self._complex.real, self._complex.imag) + from sage.libs.pari.convert_sage_complex_double import new_gen_from_complex_double_element + return new_gen_from_complex_double_element(self) def __mpc__(self): """ @@ -2255,8 +2222,6 @@ cdef class ComplexDoubleElement(FieldElement): sage: eta(z) 0.7420487758365647 + 0.1988313702299107*I """ - cdef GEN a, b, c, y, t - if self._complex.imag <= 0: raise ValueError("value must be in the upper half plane") From d77eb85ccfed864616b493a5baec7653ecdec96b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 10:25:34 -0700 Subject: [PATCH 132/378] sage.geometry: Add missing # optional tags --- .../hyperbolic_space/hyperbolic_geodesic.py | 8 ++++---- src/sage/geometry/polyhedron/base.py | 2 +- .../combinatorial_face.pyx | 2 +- src/sage/geometry/polyhedron/plot.py | 18 +++++++++--------- src/sage/geometry/voronoi_diagram.py | 14 +++++++------- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index 9ddee0b6437..b0d5e1e1daa 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -2028,14 +2028,14 @@ def plot(self, boundary=True, **options): Then some generic geodesics:: - sage: PD.get_geodesic(-0.5, 0.3+0.4*I).plot() # optional - sage.plot + sage: PD.get_geodesic(-0.5, 0.3+0.4*I).plot() # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: g = PD.get_geodesic(-1, exp(3*I*pi/7)) - sage: G = g.plot(linestyle="dashed",color="red"); G # optional - sage.plot + sage: G = g.plot(linestyle="dashed",color="red"); G # optional - sage.plot Graphics object consisting of 2 graphics primitives sage: h = PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)) - sage: H = h.plot(thickness=6, color="orange"); H # optional - sage.plot - Graphics object consisting of 2 graphics primitives + sage: H = h.plot(thickness=6, color="orange"); H # optional - sage.plot + Graphics object consisting of 2 graphics primitives # optional - sage.plot sage: show(G+H) .. PLOT:: diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index fd34e454c1e..e246b3e187c 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -11147,7 +11147,7 @@ def affine_hull_projection(self, sage: Pentagon = polytopes.dodecahedron().faces(2)[0].as_polyhedron() # optional - sage.rings.number_field sage: P = Pentagon.affine_hull_projection(orthonormal=True, extend=True) # optional - sage.rings.number_field sage: _, c= P.is_inscribed(certificate=True) # optional - sage.rings.number_field - sage: c + sage: c # optional - sage.rings.number_field (0.4721359549995794?, 0.6498393924658126?) sage: circumradius = (c-vector(P.vertices()[0])).norm() # optional - sage.rings.number_field sage: p = polytopes.regular_polygon(5) # optional - sage.rings.number_field diff --git a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx index 98f3ab0c769..2f300cebfc1 100644 --- a/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx +++ b/src/sage/geometry/polyhedron/combinatorial_polyhedron/combinatorial_face.pyx @@ -96,7 +96,7 @@ cdef class CombinatorialFace(SageObject): Obtain a combinatorial face from an index of the face lattice:: sage: F = C.face_lattice() # optional - sage.combinat - sage: F._elements[3] + sage: F._elements[3] # optional - sage.combinat 34 sage: C.face_by_face_lattice_index(29) A 1-dimensional face of a 5-dimensional combinatorial polyhedron diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index 3c8e2055139..cde0769cd68 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -1131,23 +1131,23 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): It correctly handles various degenerate cases:: - sage: Polyhedron(lines=[[1,0,0],[0,1,0],[0,0,1]]).plot() # whole space # optional - sage.plot + sage: Polyhedron(lines=[[1,0,0],[0,1,0],[0,0,1]]).plot() # whole space # optional - sage.plot Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], + sage: Polyhedron(vertices=[[1,1,1]], rays=[[1,0,0]], # optional - sage.plot ....: lines=[[0,1,0],[0,0,1]]).plot() # half space Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]], + sage: Polyhedron(vertices=[[1,1,1]], # optional - sage.plot ....: lines=[[0,1,0],[0,0,1]]).plot() # R^2 in R^3 Graphics3d Object - sage: Polyhedron(rays=[[0,1,0],[0,0,1]], lines=[[1,0,0]]).plot() # quadrant wedge in R^2 # optional - sage.plot + sage: Polyhedron(rays=[[0,1,0],[0,0,1]], lines=[[1,0,0]]).plot() # quadrant wedge in R^2 # optional - sage.plot Graphics3d Object sage: Polyhedron(rays=[[0,1,0]], lines=[[1,0,0]]).plot() # upper half plane in R^3 # optional - sage.plot Graphics3d Object - sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 # optional - sage.plot + sage: Polyhedron(lines=[[1,0,0]]).plot() # R^1 in R^2 # optional - sage.plot Graphics3d Object - sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 # optional - sage.plot + sage: Polyhedron(rays=[[0,1,0]]).plot() # Half-line in R^3 # optional - sage.plot Graphics3d Object - sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 # optional - sage.plot + sage: Polyhedron(vertices=[[1,1,1]]).plot() # point in R^3 # optional - sage.plot Graphics3d Object The origin is not included, if it is not in the polyhedron (:trac:`23555`):: @@ -1155,8 +1155,8 @@ def render_3d(self, point_opts=None, line_opts=None, polygon_opts=None): sage: Q = Polyhedron([[100],[101]]) sage: P = Q*Q*Q; P A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices - sage: p = P.plot() # optional - sage.plot - sage: p.bounding_box() + sage: p = P.plot() # optional - sage.plot + sage: p.bounding_box() # optional - sage.plot ((100.0, 100.0, 100.0), (101.0, 101.0, 101.0)) """ pplt = None diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index d5c7ee2fd24..a854f5651c9 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -264,16 +264,16 @@ def plot(self, cell_colors=None, **kwds): sage: P = [[0.671, 0.650], [0.258, 0.767], [0.562, 0.406], [0.254, 0.709], [0.493, 0.879]] - sage: V = VoronoiDiagram(P); S=V.plot() # optional - sage.plot - sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) + sage: V = VoronoiDiagram(P); S=V.plot() # optional - sage.plot + sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) # optional - sage.plot sage: S=V.plot(cell_colors={0:'red', 1:'blue', 2:'green', 3:'white', 4:'yellow'}) # optional - sage.plot - sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) + sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) # optional - sage.plot - sage: S=V.plot(cell_colors=['red','blue','red','white', 'white']) # optional - sage.plot - sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) + sage: S=V.plot(cell_colors=['red','blue','red','white', 'white']) # optional - sage.plot + sage: show(S, xmin=0, xmax=1, ymin=0, ymax=1, aspect_ratio=1, axes=false) # optional - sage.plot - sage: S=V.plot(cell_colors='something else') # optional - sage.plot + sage: S=V.plot(cell_colors='something else') # optional - sage.plot Traceback (most recent call last): ... AssertionError: 'cell_colors' must be a list or a dictionary @@ -282,7 +282,7 @@ def plot(self, cell_colors=None, **kwds): Trying to plot a Voronoi diagram of dimension other than 2 gives an error:: - sage: VoronoiDiagram([[1, 2, 3], [6, 5, 4]]).plot() # optional - sage.plot + sage: VoronoiDiagram([[1, 2, 3], [6, 5, 4]]).plot() # optional - sage.plot Traceback (most recent call last): ... NotImplementedError: Plotting of 3-dimensional Voronoi diagrams not From 905ead9543b570dc8296568ae083b7356e4976e5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 12:28:24 -0700 Subject: [PATCH 133/378] sage.features.PythonModule: Record the exception message as part of the reason --- src/sage/features/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/features/__init__.py b/src/sage/features/__init__.py index 839bde0d8d4..1d6e075fe49 100644 --- a/src/sage/features/__init__.py +++ b/src/sage/features/__init__.py @@ -823,6 +823,6 @@ def _is_present(self): import importlib try: importlib.import_module(self.name) - except ImportError: - return FeatureTestResult(self, False, reason="Failed to import `{name}`.".format(name=self.name)) - return FeatureTestResult(self, True, reason="Successfully imported `{name}`.".format(name=self.name)) + except ImportError as exception: + return FeatureTestResult(self, False, reason=f"Failed to import `{self.name}`: {exception}") + return FeatureTestResult(self, True, reason=f"Successfully imported `{self.name}`.") From 7755df9fb6c97c00d6f29f8cb84231c3edd6bb66 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 12:29:21 -0700 Subject: [PATCH 134/378] sage.doctest.control, sage.features.sagemath: If --verbose is used, log the feature test results and reasons --- src/sage/doctest/control.py | 7 +++++-- src/sage/features/sagemath.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/doctest/control.py b/src/sage/doctest/control.py index 858d8cb5679..73bd457963a 100644 --- a/src/sage/doctest/control.py +++ b/src/sage/doctest/control.py @@ -406,10 +406,13 @@ def __init__(self, options, args): options.optional.add(pkg['name']) from sage.features import package_systems - options.optional.update(system.name for system in package_systems()) + options.optional.update(system.name + for system in package_systems()) + logger = sys.stderr if options.verbose else None from sage.features.sagemath import sage_features - options.optional.update(feature.name for feature in sage_features()) + options.optional.update(feature.name + for feature in sage_features(logger=logger)) # Check that all tags are valid for o in options.optional: diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 2af7def3668..5eb6a8fd820 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -50,7 +50,7 @@ def __init__(self): spkg="sagemath_symbolics") -def sage_features(): +def sage_features(logger=None): """ Return features corresponding to parts of the Sage library. @@ -80,5 +80,8 @@ def sage_features(): sage__rings__number_field(), sage__rings__real_double(), sage__symbolic()]: - if feature.is_present(): + result = feature.is_present() + if logger: + logger.write(f'{result}, reason: {result.reason}\n') + if result: yield feature From f32b99248efbf2655dd50768d970ff72f6d814eb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 12:31:46 -0700 Subject: [PATCH 135/378] src/sage/features/sagemath.py (sage.combinat): Fix the name of the tested PythonModule --- src/sage/features/sagemath.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/features/sagemath.py b/src/sage/features/sagemath.py index 5eb6a8fd820..88b607b5e0c 100644 --- a/src/sage/features/sagemath.py +++ b/src/sage/features/sagemath.py @@ -12,7 +12,7 @@ def __init__(self): # Testing whether sage.combinat itself can be imported is meaningless. # Hence, we test a Python module within the package. JoinFeature.__init__(self, 'sage.combinat', - [PythonModule('sage.combinat.combinations')]) + [PythonModule('sage.combinat.combination')]) class sage__graphs(JoinFeature): From 7c32b0e57ac59c43e626d94c7e9dd5de857de34d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 14:50:44 -0700 Subject: [PATCH 136/378] src/sage/ext/fast_callable.pyx: Use sage.rings.abc --- src/sage/ext/fast_callable.pyx | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index d54d501226c..9a40b7a25e3 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -302,9 +302,7 @@ AUTHOR: import operator from copy import copy -from sage.rings.real_mpfr cimport RealField_class, RealNumber -from sage.rings.complex_mpfr import ComplexField_class -from sage.rings.all import RDF, CDF +import sage.rings.abc from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.structure.element cimport parent @@ -469,7 +467,7 @@ def fast_callable(x, domain=None, vars=None, etb = ExpressionTreeBuilder(vars=vars, domain=domain) et = x._fast_callable_(etb) - if isinstance(domain, RealField_class): + if isinstance(domain, sage.rings.abc.RealField): import sage.ext.interpreters.wrapper_rr builder = sage.ext.interpreters.wrapper_rr.Wrapper_rr @@ -477,20 +475,20 @@ def fast_callable(x, domain=None, vars=None, len(vars), domain) - elif isinstance(domain, ComplexField_class): + elif isinstance(domain, sage.rings.abc.ComplexField): import sage.ext.interpreters.wrapper_cc builder = sage.ext.interpreters.wrapper_cc.Wrapper_cc str = InstructionStream(sage.ext.interpreters.wrapper_cc.metadata, len(vars), domain) - elif domain == RDF or domain is float: + elif isinstance(domain, sage.rings.abc.RealDoubleField) or domain is float: import sage.ext.interpreters.wrapper_rdf builder = sage.ext.interpreters.wrapper_rdf.Wrapper_rdf str = InstructionStream(sage.ext.interpreters.wrapper_rdf.metadata, len(vars), domain) - elif domain == CDF: + elif isinstance(domain, sage.rings.abc.ComplexDoubleField): import sage.ext.interpreters.wrapper_cdf builder = sage.ext.interpreters.wrapper_cdf.Wrapper_cdf str = InstructionStream(sage.ext.interpreters.wrapper_cdf.metadata, From a3dd5ce69784843b61757633e5631eda913201e0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 14:54:46 -0700 Subject: [PATCH 137/378] src/sage/geometry/voronoi_diagram.py: Use sage.rings.abc --- src/sage/geometry/voronoi_diagram.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index 1859a5e0c1a..a60720bf3be 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -17,8 +17,7 @@ from sage.geometry.polyhedron.constructor import Polyhedron from sage.rings.qqbar import AA from sage.rings.rational_field import QQ -from sage.rings.real_double import RDF -from sage.rings.real_mpfr import RealField_class +import sage.rings.abc from sage.geometry.triangulation.point_configuration import PointConfiguration from sage.modules.free_module_element import vector from sage.plot.all import line, point, rainbow, plot @@ -103,9 +102,10 @@ def __init__(self, points): self._n = self._points.n_points() if not self._n or self._points.base_ring().is_subring(QQ): self._base_ring = QQ - elif self._points.base_ring() in [RDF, AA]: + elif isinstance(self._points.base_ring(), sage.rings.abc.RealDoubleField) or self._points.base_ring() == AA: self._base_ring = self._points.base_ring() - elif isinstance(self._points.base_ring(), RealField_class): + elif isinstance(self._points.base_ring(), sage.rings.abc.RealField): + from sage.rings.real_double import RDF self._base_ring = RDF self._points = PointConfiguration([[RDF(cor) for cor in poi] for poi in self._points]) From 5fe33f8a83d2e6f025e4735dfc53880e021b127d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 14:57:59 -0700 Subject: [PATCH 138/378] src/sage/groups/misc_gps/argument_groups.py: Use sage.rings.abc --- src/sage/groups/lie_gps/nilpotent_lie_group.py | 4 ++-- src/sage/groups/misc_gps/argument_groups.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/groups/lie_gps/nilpotent_lie_group.py b/src/sage/groups/lie_gps/nilpotent_lie_group.py index 1138454eb80..bc41359b510 100644 --- a/src/sage/groups/lie_gps/nilpotent_lie_group.py +++ b/src/sage/groups/lie_gps/nilpotent_lie_group.py @@ -26,7 +26,7 @@ from sage.misc.cachefunc import cached_method from sage.misc.repr import repr_lincomb from sage.modules.free_module_element import vector -from sage.rings.real_mpfr import RealField_class +import sage.rings.abc from sage.structure.element import MultiplicativeGroupElement from sage.symbolic.ring import SR, var @@ -229,7 +229,7 @@ def __init__(self, L, name, **kwds): R = L.base_ring() category = kwds.pop('category', None) category = LieGroups(R).or_subcategory(category) - if isinstance(R, RealField_class): + if isinstance(R, sage.rings.abc.RealField): structure = RealDifferentialStructure() else: structure = DifferentialStructure() diff --git a/src/sage/groups/misc_gps/argument_groups.py b/src/sage/groups/misc_gps/argument_groups.py index 1cf801fad85..1c81c361294 100644 --- a/src/sage/groups/misc_gps/argument_groups.py +++ b/src/sage/groups/misc_gps/argument_groups.py @@ -46,7 +46,7 @@ from sage.structure.parent import Parent from sage.structure.richcmp import richcmp_by_eq_and_lt from sage.structure.unique_representation import UniqueRepresentation - +import sage.rings.abc class AbstractArgument(MultiplicativeGroupElement): r""" @@ -1870,13 +1870,13 @@ def create_key_and_extra_args(self, if domain is not None: if domain in (ZZ, QQ, AA) \ - or isinstance(domain, (RealField_class, - RealIntervalField_class, - RealBallField)): + or isinstance(domain, (sage.rings.abc.RealField, + sage.rings.abc.RealIntervalField, + sage.rings.abc.RealBallField)): return (SignGroup, ()), kwds - elif isinstance(domain, (ComplexField_class, - ComplexIntervalField_class, - ComplexBallField)): + elif isinstance(domain, (sage.rings.abc.ComplexField, + sage.rings.abc.ComplexIntervalField, + sage.rings.abc.ComplexBallField)): return (UnitCircleGroup, (domain._real_field(),)), kwds else: return (ArgumentByElementGroup, (domain,)), kwds From d7a472b4a605d87fa819b7c7c973e9a9fcad0bff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 15:00:15 -0700 Subject: [PATCH 139/378] src/sage/manifolds: Use sage.rings.abc --- src/sage/manifolds/manifold.py | 12 ++++++------ src/sage/manifolds/vector_bundle.py | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/sage/manifolds/manifold.py b/src/sage/manifolds/manifold.py index 1b62341fc84..70250784db8 100644 --- a/src/sage/manifolds/manifold.py +++ b/src/sage/manifolds/manifold.py @@ -328,9 +328,9 @@ from sage.categories.fields import Fields from sage.categories.manifolds import Manifolds from sage.categories.homset import Hom +import sage.rings.abc from sage.rings.all import CC -from sage.rings.real_mpfr import RR, RealField_class -from sage.rings.complex_mpfr import ComplexField_class +from sage.rings.real_mpfr import RR from sage.misc.prandom import getrandbits from sage.misc.cachefunc import cached_method from sage.rings.integer import Integer @@ -545,9 +545,9 @@ def __init__(self, n, name, field, structure, base_manifold=None, if field not in Fields(): raise TypeError("the argument 'field' must be a field") self._field = field - if isinstance(field, RealField_class): + if isinstance(field, sage.rings.abc.RealField): self._field_type = 'real' - elif isinstance(field, ComplexField_class): + elif isinstance(field, sage.rings.abc.ComplexField): self._field_type = 'complex' else: self._field_type = 'neither_real_nor_complex' @@ -2957,7 +2957,7 @@ def Manifold(dim, name, latex_name=None, field='real', structure='smooth', unique_tag = lambda: getrandbits(128)*_manifold_id if structure in ['topological', 'top']: - if field == 'real' or isinstance(field, RealField_class): + if field == 'real' or isinstance(field, sage.rings.abc.RealField): structure = RealTopologicalStructure() else: structure = TopologicalStructure() @@ -2985,7 +2985,7 @@ def Manifold(dim, name, latex_name=None, field='real', structure='smooth', "not compatible with a smooth structure") else: diff_degree = infinity - if field == 'real' or isinstance(field, RealField_class): + if field == 'real' or isinstance(field, sage.rings.abc.RealField): structure = RealDifferentialStructure() else: structure = DifferentialStructure() diff --git a/src/sage/manifolds/vector_bundle.py b/src/sage/manifolds/vector_bundle.py index 42a77c9f87e..49c0b72f1bd 100644 --- a/src/sage/manifolds/vector_bundle.py +++ b/src/sage/manifolds/vector_bundle.py @@ -37,9 +37,9 @@ from sage.structure.category_object import CategoryObject from sage.categories.vector_bundles import VectorBundles from sage.structure.unique_representation import UniqueRepresentation +import sage.rings.abc from sage.rings.all import CC -from sage.rings.real_mpfr import RR, RealField_class -from sage.rings.complex_mpfr import ComplexField_class +from sage.rings.real_mpfr import RR from sage.rings.integer import Integer from sage.manifolds.vector_bundle_fiber import VectorBundleFiber @@ -218,9 +218,9 @@ def __init__(self, rank, name, base_space, field='real', self._field_type = field else: self._field = field - if isinstance(field, RealField_class): + if isinstance(field, sage.rings.abc.RealField): self._field_type = 'real' - elif isinstance(field, ComplexField_class): + elif isinstance(field, sage.rings.abc.ComplexField): self._field_type = 'complex' else: self._field_type = 'neither_real_nor_complex' From 373b2330802f07737a3a0bdb0b7e641485961670 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 16:59:30 -0700 Subject: [PATCH 140/378] src/sage/matrix/misc.pyx: Use sage.rings.abc --- src/sage/matrix/misc.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/misc.pyx b/src/sage/matrix/misc.pyx index c7fc1c70161..220f8866b0e 100644 --- a/src/sage/matrix/misc.pyx +++ b/src/sage/matrix/misc.pyx @@ -40,7 +40,7 @@ from sage.rings.rational_field import QQ from sage.rings.integer cimport Integer from sage.arith.all import previous_prime, CRT_basis -from sage.rings.real_mpfr cimport RealField_class +cimport sage.rings.abc from sage.rings.real_mpfr cimport RealNumber @@ -510,7 +510,7 @@ def hadamard_row_bound_mpfr(Matrix A): ... OverflowError: cannot convert float infinity to integer """ - if not isinstance(A.base_ring(), RealField_class): + if not isinstance(A.base_ring(), sage.rings.abc.RealField): raise TypeError("A must have base field an mpfr real field.") cdef RealNumber a, b From ec8f8af2b085568c3469bfbf2bbe2ec48c568655 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:01:44 -0700 Subject: [PATCH 141/378] src/sage/quadratic_forms/quadratic_form__split_local_covering.py: Use sage.rings.abc --- .../quadratic_forms/quadratic_form__split_local_covering.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py index afd1ee350c3..84164d4fa9f 100644 --- a/src/sage/quadratic_forms/quadratic_form__split_local_covering.py +++ b/src/sage/quadratic_forms/quadratic_form__split_local_covering.py @@ -11,7 +11,8 @@ from sage.quadratic_forms.extras import extend_to_primitive from sage.quadratic_forms.quadratic_form import QuadraticForm__constructor, is_QuadraticForm -from sage.rings.real_mpfr import RealField_class, RealField +import sage.rings.abc +from sage.rings.real_mpfr import RealField from sage.rings.real_double import RDF from sage.matrix.matrix_space import MatrixSpace from sage.matrix.constructor import matrix @@ -84,7 +85,7 @@ def cholesky_decomposition(self, bit_prec = 53): """ ## Check that the precision passed is allowed. - if isinstance(self.base_ring(), RealField_class) and (self.base_ring().prec() < bit_prec): + if isinstance(self.base_ring(), sage.rings.abc.RealField) and (self.base_ring().prec() < bit_prec): raise RuntimeError("Oops! The precision requested is greater than that of the given quadratic form!") ## 1. Initialization From c039cecccde4d6ddf18569ce4b7fca9e2d958fb1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:06:21 -0700 Subject: [PATCH 142/378] src/sage/rings/asymptotic/growth_group.py: Use sage.rings.abc --- src/sage/rings/asymptotic/growth_group.py | 42 ++++++++--------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/src/sage/rings/asymptotic/growth_group.py b/src/sage/rings/asymptotic/growth_group.py index 5a0c9265d34..d088e838f67 100644 --- a/src/sage/rings/asymptotic/growth_group.py +++ b/src/sage/rings/asymptotic/growth_group.py @@ -240,6 +240,7 @@ from sage.structure.unique_representation import (CachedRepresentation, UniqueRepresentation) from sage.structure.richcmp import richcmp_by_eq_and_lt +import sage.rings.abc from .misc import WithLocals @@ -3622,13 +3623,12 @@ def _convert_(self, data): from sage.symbolic.ring import SR return self._convert_(SR(data)) - from sage.symbolic.ring import SymbolicRing from sage.rings.polynomial.polynomial_ring import PolynomialRing_general from sage.rings.polynomial.multi_polynomial_ring_base import \ MPolynomialRing_base from sage.rings.power_series_ring import PowerSeriesRing_generic import operator - if isinstance(P, SymbolicRing): + if isinstance(P, sage.rings.abc.SymbolicRing): if data.operator() == operator.pow: base, exponent = data.operands() if str(base) == var: @@ -4419,10 +4419,9 @@ def __init__(self, base, *args, **kwds): sage: forget() """ from warnings import warn - from sage.symbolic.ring import SymbolicRing super(ExponentialGrowthGroup, self).__init__(base, *args, **kwds) - if isinstance(base, SymbolicRing) and not self._an_element_base_() > 0: + if isinstance(base, sage.rings.abc.SymbolicRing) and not self._an_element_base_() > 0: warn("When using the Exponential {}, make " "assumptions on the used symbolic elements.\n" "In particular, use something like " @@ -4552,9 +4551,8 @@ def _convert_(self, data): import operator from sage.functions.log import Function_exp from sage.symbolic.operators import mul_vararg - from sage.symbolic.ring import SymbolicRing - if isinstance(P, SymbolicRing): + if isinstance(P, sage.rings.abc.SymbolicRing): op = data.operator() if op == operator.pow: base, exponent = data.operands() @@ -4654,20 +4652,13 @@ def _split_raw_element_(base): (-x, -1) sage: forget() """ - from sage.rings.complex_arb import ComplexBallField - from sage.rings.complex_mpfr import ComplexField_class - from sage.rings.complex_interval_field import ComplexIntervalField_class from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ - from sage.rings.real_arb import RealBallField - from sage.rings.real_mpfr import RealField_class - from sage.rings.real_mpfi import RealIntervalField_class from sage.rings.qqbar import AA from sage.structure.element import parent - from sage.symbolic.ring import SymbolicRing P = base.parent() - if isinstance(P, SymbolicRing): + if isinstance(P, sage.rings.abc.SymbolicRing): try: base = base.pyobject() except TypeError: @@ -4675,17 +4666,17 @@ def _split_raw_element_(base): else: P = base.parent() - if P in (ZZ, QQ, AA) or isinstance(P, (SymbolicRing, - RealField_class, - RealIntervalField_class, - RealBallField)): + if P in (ZZ, QQ, AA) or isinstance(P, (sage.rings.abc.SymbolicRing, + sage.rings.abc.RealField, + sage.rings.abc.RealIntervalField, + sage.rings.abc.RealBallField)): if base > 0: return base, None if base < 0: return -base, -1 - elif isinstance(P, (ComplexField_class, - ComplexIntervalField_class, - ComplexBallField)): + elif isinstance(P, (sage.rings.abc.ComplexField, + sage.rings.abc.ComplexIntervalField, + sage.rings.abc.ComplexBallField)): size = abs(base) direction = base / size return size, direction @@ -4847,9 +4838,6 @@ def factory(cls, from sage.categories.cartesian_product import cartesian_product from sage.groups.misc_gps.argument_groups import AbstractArgumentGroup from sage.groups.misc_gps.argument_groups import ArgumentGroup - from sage.rings.complex_arb import ComplexBallField - from sage.rings.complex_mpfr import ComplexField_class - from sage.rings.complex_interval_field import ComplexIntervalField_class from sage.rings.number_field.number_field import NumberField_cyclotomic from sage.rings.qqbar import QQbar, AA @@ -4861,9 +4849,9 @@ def factory(cls, UU = cls._non_growth_group_class_( ArgumentGroup(domain=base), var) groups = (EE, UU) - elif isinstance(base, (ComplexField_class, - ComplexIntervalField_class, - ComplexBallField)): + elif isinstance(base, (sage.rings.abc.ComplexField, + sage.rings.abc.ComplexIntervalField, + sage.rings.abc.ComplexBallField)): EE = cls(base._real_field(), var, **kwds) UU = cls._non_growth_group_class_( ArgumentGroup(exponents=base._real_field()), var) From 034bac71306bc89e6160e71bb5910194e73b6f5a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:11:07 -0700 Subject: [PATCH 143/378] src/sage/rings/complex_double.pyx: Use sage.rings.abc --- src/sage/rings/complex_double.pyx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 9038f2dd14f..691eade3ea4 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -82,6 +82,7 @@ cdef extern from "": double complex csqrt(double complex) double cabs(double complex) +import sage.rings.abc cimport sage.rings.ring cimport sage.rings.integer @@ -436,11 +437,10 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): return FloatToCDF(S) from .rational_field import QQ from .real_lazy import RLF - from .real_mpfr import RR, RealField_class - from .complex_mpfr import ComplexField_class + from .real_mpfr import RR if S is ZZ or S is QQ or S is RDF or S is RLF: return FloatToCDF(S) - if isinstance(S, RealField_class): + if isinstance(S, sage.rings.abc.RealField): if S.prec() >= 53: return FloatToCDF(S) else: @@ -455,7 +455,7 @@ cdef class ComplexDoubleField_class(sage.rings.abc.ComplexDoubleField): return None elif RR.has_coerce_map_from(S): return FloatToCDF(RR) * RR._internal_coerce_map_from(S) - elif isinstance(S, ComplexField_class) and S.prec() >= 53: + elif isinstance(S, sage.rings.abc.ComplexField) and S.prec() >= 53: return complex_mpfr.CCtoCDF(S, self) elif CC.has_coerce_map_from(S): return complex_mpfr.CCtoCDF(CC, self) * CC._internal_coerce_map_from(S) From f3dd7cc0eaae1719d9be830fec93075baa7962fc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:14:26 -0700 Subject: [PATCH 144/378] src/sage/rings/polynomial/multi_polynomial_ideal.py: Use sage.rings.abc --- src/sage/rings/polynomial/multi_polynomial_ideal.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 560dcc8c25d..d12c0ff5331 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2573,8 +2573,7 @@ def _variety(T, V, v=None): if d == -1: return [] - import sage.rings.complex_mpfr as CCmod - if isinstance(self.base_ring(), CCmod.ComplexField_class): + if isinstance(self.base_ring(), sage.rings.abc.ComplexField): verbose("Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.", level=0) P = self.ring() if ring is not None: From 6dce213c91101dda546db134bff73a3282c4385b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:16:38 -0700 Subject: [PATCH 145/378] src/sage/schemes/projective/projective_morphism.py: Use sage.rings.abc --- src/sage/schemes/projective/projective_morphism.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 1aa7ea7f841..62f505b099f 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -74,6 +74,7 @@ from sage.calculus.functions import jacobian +import sage.rings.abc from sage.rings.all import Integer from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic from sage.rings.complex_mpfr import ComplexField_class @@ -1605,7 +1606,8 @@ def rational_preimages(self, Q, k=1): raise TypeError("must be an endomorphism of projective space") if not Q in self.codomain(): raise TypeError("point must be in codomain of self") - if isinstance(BR.base_ring(),(ComplexField_class, RealField_class,RealIntervalField_class, ComplexIntervalField_class)): + if isinstance(BR.base_ring(), (sage.rings.abc.ComplexField, sage.rings.abc.RealField, + sage.rings.abc.RealIntervalField, sage.rings.abc.ComplexIntervalField)): raise NotImplementedError("not implemented over precision fields") PS = self.domain().ambient_space() N = PS.dimension_relative() From 7e8f0bb9aaa88d5d73b20e671e262c9320f1f5a6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:18:00 -0700 Subject: [PATCH 146/378] src/sage/rings/real_double.pyx: Use sage.rings.abc --- src/sage/rings/real_double.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 405153db6b9..9fc00418b7d 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -360,8 +360,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): if S is ZZ or S is QQ or S is RLF: return ToRDF(S) - from .real_mpfr import RR, RealField_class - if isinstance(S, RealField_class): + if isinstance(S, sage.rings.abc.RealField): if S.prec() >= 53: return ToRDF(S) else: @@ -373,6 +372,7 @@ cdef class RealDoubleField_class(sage.rings.abc.RealDoubleField): else: return None + from .real_mpfr import RR connecting = RR._internal_coerce_map_from(S) if connecting is not None: return ToRDF(RR) * connecting From fbf6666479e7a54761459288af9b5d1772158934 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:30:13 -0700 Subject: [PATCH 147/378] src/sage/rings/continued_fraction.py: Use sage.rings.abc --- src/sage/rings/continued_fraction.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index cf5f8b1f9eb..ebe687da65f 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -2451,12 +2451,11 @@ def continued_fraction_list(x, type="std", partial_convergents=False, cf = None - from sage.rings.real_arb import RealBallField - from sage.rings.real_mpfi import RealIntervalField, RealIntervalField_class from sage.rings.real_mpfr import RealLiteral if isinstance(x, RealLiteral): + from sage.rings.real_mpfi import RealIntervalField x = RealIntervalField(x.prec())(x) - if isinstance(x.parent(), (RealIntervalField_class, RealBallField)): + if isinstance(x.parent(), (sage.rings.abc.RealIntervalField, sage.rings.abc.RealBallField)): cf = continued_fraction(rat_interval_cf_list( x.lower().exact_rational(), x.upper().exact_rational())) @@ -2658,8 +2657,8 @@ def continued_fraction(x, value=None): except AttributeError: pass - from .real_mpfi import RealIntervalField if is_real is False: + from .real_mpfi import RealIntervalField # we cannot rely on the answer of .is_real() for elements of the # symbolic ring. The thing below is a dirty temporary hack. RIF = RealIntervalField(53) From 9f17894b3cbb88ba2372f6192aca277b3c9d0706 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:30:38 -0700 Subject: [PATCH 148/378] src/sage/matrix/matrix_space.py: Use sage.rings.abc --- src/sage/matrix/matrix_space.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/matrix/matrix_space.py b/src/sage/matrix/matrix_space.py index 99e57196f3f..2b90c3cba19 100644 --- a/src/sage/matrix/matrix_space.py +++ b/src/sage/matrix/matrix_space.py @@ -252,8 +252,7 @@ def get_matrix_class(R, nrows, ncols, sparse, implementation): from . import matrix_symbolic_dense return matrix_symbolic_dense.Matrix_symbolic_dense - from sage.rings.complex_arb import ComplexBallField - if isinstance(R, ComplexBallField): + if isinstance(R, sage.rings.abc.ComplexBallField): from . import matrix_complex_ball_dense return matrix_complex_ball_dense.Matrix_complex_ball_dense From 2dd97ba6475ca39128fbba35be268f7598a70d41 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:31:13 -0700 Subject: [PATCH 149/378] src/sage/rings/asymptotic/asymptotic_ring.py: Use sage.rings.abc --- src/sage/rings/asymptotic/asymptotic_ring.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/asymptotic/asymptotic_ring.py b/src/sage/rings/asymptotic/asymptotic_ring.py index f7e3d0c235e..86bc4740a73 100644 --- a/src/sage/rings/asymptotic/asymptotic_ring.py +++ b/src/sage/rings/asymptotic/asymptotic_ring.py @@ -418,6 +418,7 @@ from sage.structure.element import CommutativeAlgebraElement from sage.structure.unique_representation import UniqueRepresentation from sage.misc.defaults import series_precision +import sage.rings.abc from sage.rings.all import RIF from .misc import WithLocals @@ -2964,8 +2965,7 @@ def plot_comparison(self, variable, function, values, rescaled=True, points = self.compare_with_values(variable, function, values, rescaled=rescaled, ring=ring) - from sage.rings.real_mpfi import RealIntervalField_class - if isinstance(ring, RealIntervalField_class): + if isinstance(ring, sage.rings.abc.RealIntervalField): if not all(p[1].relative_diameter() <= relative_tolerance for p in points): raise ValueError('Numerical noise is too high, the ' 'comparison is inaccurate') From 41b7860659543b8de40d90d97b3f1794218ccd05 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:33:06 -0700 Subject: [PATCH 150/378] src/sage/rings/convert/mpfi.pyx: Use sage.rings.abc --- src/sage/rings/convert/mpfi.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/convert/mpfi.pyx b/src/sage/rings/convert/mpfi.pyx index a7d1561ec09..67ccbefdb7e 100644 --- a/src/sage/rings/convert/mpfi.pyx +++ b/src/sage/rings/convert/mpfi.pyx @@ -20,10 +20,10 @@ from sage.libs.mpfi cimport * from sage.arith.long cimport integer_check_long from sage.cpython.string cimport bytes_to_str from sage.structure.element cimport Element, parent +import sage.rings.abc from ..integer cimport Integer from ..rational cimport Rational from ..real_mpfi cimport RealIntervalFieldElement, RealIntervalField_class -from ..complex_interval_field import ComplexIntervalField_class from ..real_mpfr cimport RealNumber from ..real_double cimport RealDoubleElement from ..complex_mpfr cimport ComplexNumber @@ -188,7 +188,7 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: except AttributeError: pass else: - if not isinstance(field, ComplexIntervalField_class): + if not isinstance(field, sage.rings.abc.ComplexIntervalField): field = field.complex_field() e = m(field) mpfi_swap(re, e.__re) From 5d2e72c12c240ada6dc0658702d3d28a6e9296a0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:34:50 -0700 Subject: [PATCH 151/378] src/sage/rings/infinity.py: Use sage.rings.abc --- src/sage/rings/infinity.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index dfa0b9b6423..6bbacbe31e9 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -220,6 +220,7 @@ from sage.structure.element import RingElement, InfinityElement from sage.structure.richcmp import rich_to_bool, richcmp from sage.misc.fast_methods import Singleton +import sage.rings.abc import sage.rings.integer import sage.rings.rational @@ -1261,15 +1262,8 @@ def _coerce_map_from_(self, R): from sage.structure.coerce import parent_is_real_numerical if parent_is_real_numerical(R): return True - from sage.rings.real_mpfi import RealIntervalField_class - if isinstance(R, RealIntervalField_class): + if isinstance(R, (sage.rings.abc.RealIntervalField, sage.rings.abc.RealBallField)): return True - try: - from sage.rings.real_arb import RealBallField - if isinstance(R, RealBallField): - return True - except ImportError: - pass return False def _pushout_(self, other): From a66552906a62ad9e4836092da2cf7be65f6d7eac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:37:41 -0700 Subject: [PATCH 152/378] src/sage/rings/polynomial/polynomial_ring.py: Use sage.rings.abc --- src/sage/rings/polynomial/polynomial_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polynomial_ring.py b/src/sage/rings/polynomial/polynomial_ring.py index 82ff837a2b5..8616e5626ea 100644 --- a/src/sage/rings/polynomial/polynomial_ring.py +++ b/src/sage/rings/polynomial/polynomial_ring.py @@ -1997,7 +1997,7 @@ def __init__(self, base_ring, name="x", sparse=False, element_class=None, catego element_class = Polynomial_relative_number_field_dense elif isinstance(base_ring, sage.rings.abc.RealField): element_class = PolynomialRealDense - elif isinstance(base_ring, sage.rings.complex_arb.ComplexBallField): + elif isinstance(base_ring, sage.rings.abc.ComplexBallField): from sage.rings.polynomial.polynomial_complex_arb import Polynomial_complex_arb element_class = Polynomial_complex_arb else: From c8b9aaf25d92aad524586d19e1af3ac51c15f680 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:44:28 -0700 Subject: [PATCH 153/378] src/sage/ext/fast_callable.pyx: Fix up imports --- src/sage/ext/fast_callable.pyx | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/sage/ext/fast_callable.pyx b/src/sage/ext/fast_callable.pyx index 9a40b7a25e3..9e3f206ead8 100644 --- a/src/sage/ext/fast_callable.pyx +++ b/src/sage/ext/fast_callable.pyx @@ -468,40 +468,33 @@ def fast_callable(x, domain=None, vars=None, et = x._fast_callable_(etb) if isinstance(domain, sage.rings.abc.RealField): - import sage.ext.interpreters.wrapper_rr - builder = sage.ext.interpreters.wrapper_rr.Wrapper_rr - + from sage.ext.interpreters.wrapper_rr import Wrapper_rr as builder str = InstructionStream(sage.ext.interpreters.wrapper_rr.metadata, len(vars), domain) elif isinstance(domain, sage.rings.abc.ComplexField): - import sage.ext.interpreters.wrapper_cc - builder = sage.ext.interpreters.wrapper_cc.Wrapper_cc + from sage.ext.interpreters.wrapper_cc import Wrapper_cc as builder str = InstructionStream(sage.ext.interpreters.wrapper_cc.metadata, len(vars), domain) elif isinstance(domain, sage.rings.abc.RealDoubleField) or domain is float: - import sage.ext.interpreters.wrapper_rdf - builder = sage.ext.interpreters.wrapper_rdf.Wrapper_rdf + from sage.ext.interpreters.wrapper_rdf import Wrapper_rdf as builder str = InstructionStream(sage.ext.interpreters.wrapper_rdf.metadata, len(vars), domain) elif isinstance(domain, sage.rings.abc.ComplexDoubleField): - import sage.ext.interpreters.wrapper_cdf - builder = sage.ext.interpreters.wrapper_cdf.Wrapper_cdf + from sage.ext.interpreters.wrapper_cdf import Wrapper_cdf as builder str = InstructionStream(sage.ext.interpreters.wrapper_cdf.metadata, len(vars), domain) elif domain is None: - import sage.ext.interpreters.wrapper_py - builder = sage.ext.interpreters.wrapper_py.Wrapper_py + from sage.ext.interpreters.wrapper_py import Wrapper_py as builder str = InstructionStream(sage.ext.interpreters.wrapper_py.metadata, len(vars)) else: - import sage.ext.interpreters.wrapper_el - builder = sage.ext.interpreters.wrapper_el.Wrapper_el + from sage.ext.interpreters.wrapper_el import Wrapper_el as builder str = InstructionStream(sage.ext.interpreters.wrapper_el.metadata, len(vars), domain) From 8c38baf7f95b27b95a29feaf291c0e526d7a1378 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 17:54:57 -0700 Subject: [PATCH 154/378] src/sage/rings/continued_fraction.py: Add missing import --- src/sage/rings/continued_fraction.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index ebe687da65f..94e5ecf25e0 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -207,6 +207,7 @@ from sage.structure.sage_object import SageObject from sage.structure.richcmp import richcmp_method, rich_to_bool +import sage.rings.abc from .integer import Integer from .integer_ring import ZZ from .infinity import Infinity From 30eee2e294e1c4e396327783c6f29d9b3412b737 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 22 Oct 2021 18:07:31 -0700 Subject: [PATCH 155/378] src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py: Add another missing # optional - sage.plot --- src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py index b0d5e1e1daa..c624c15081c 100644 --- a/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +++ b/src/sage/geometry/hyperbolic_space/hyperbolic_geodesic.py @@ -2036,7 +2036,7 @@ def plot(self, boundary=True, **options): sage: h = PD.get_geodesic(exp(2*I*pi/11), exp(1*I*pi/11)) sage: H = h.plot(thickness=6, color="orange"); H # optional - sage.plot Graphics object consisting of 2 graphics primitives # optional - sage.plot - sage: show(G+H) + sage: show(G+H) # optional - sage.plot .. PLOT:: From f6f322316529e1724122965cb5723bdf5acd5b76 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 30 Sep 2021 23:32:44 +0800 Subject: [PATCH 156/378] update GSL to 2.7 --- build/pkgs/gsl/checksums.ini | 6 +- build/pkgs/gsl/package-version.txt | 2 +- src/sage/libs/gsl/complex.pxd | 6 +- src/sage/libs/gsl/types.pxd | 4 +- src/sage/plot/complex_plot.pyx | 7 +- src/sage/rings/complex_double.pyx | 71 ++++++++++--------- src/sage/rings/complex_mpfr.pyx | 6 +- src/sage/rings/convert/mpfi.pyx | 7 +- src/sage/symbolic/pynac_impl.pxi | 4 +- .../autogen/interpreters/specs/cdf.py | 6 +- 10 files changed, 62 insertions(+), 57 deletions(-) diff --git a/build/pkgs/gsl/checksums.ini b/build/pkgs/gsl/checksums.ini index 0d63c733eb6..affe99b550f 100644 --- a/build/pkgs/gsl/checksums.ini +++ b/build/pkgs/gsl/checksums.ini @@ -1,5 +1,5 @@ tarball=gsl-VERSION.tar.gz -sha1=9273164b6bdf60d0577518a1c1310eff6659e3dd -md5=bda73a3dd5ff2f30b5956764399db6e7 -cksum=1462047518 +sha1=29179db0d746f422bb0ceca2cbda4de107a2c651 +md5=9e47e81caaebcd92b7aca27a5348df74 +cksum=2494121348 upstream_url=https://ftp.gnu.org/gnu/gsl/gsl-VERSION.tar.gz diff --git a/build/pkgs/gsl/package-version.txt b/build/pkgs/gsl/package-version.txt index 5154b3f68e9..1effb003408 100644 --- a/build/pkgs/gsl/package-version.txt +++ b/build/pkgs/gsl/package-version.txt @@ -1 +1 @@ -2.6 +2.7 diff --git a/src/sage/libs/gsl/complex.pxd b/src/sage/libs/gsl/complex.pxd index d0e6f9f33a2..b6e0a16fbb1 100644 --- a/src/sage/libs/gsl/complex.pxd +++ b/src/sage/libs/gsl/complex.pxd @@ -10,11 +10,11 @@ cdef extern from "gsl/gsl_complex.h": int GSL_COMPLEX_EQ(gsl_complex z1,gsl_complex z2) - double GSL_SET_COMPLEX(gsl_complex * zp, double x, double y) + void GSL_SET_COMPLEX(gsl_complex * zp, double x, double y) - double GSL_SET_REAL(gsl_complex * zp, double x) + void GSL_SET_REAL(gsl_complex * zp, double x) - double GSL_SET_IMAG(gsl_complex * zp, double y) + void GSL_SET_IMAG(gsl_complex * zp, double y) cdef extern from "gsl/gsl_complex_math.h": diff --git a/src/sage/libs/gsl/types.pxd b/src/sage/libs/gsl/types.pxd index 04b9e17a501..217738be893 100644 --- a/src/sage/libs/gsl/types.pxd +++ b/src/sage/libs/gsl/types.pxd @@ -43,9 +43,7 @@ cdef extern from "gsl/gsl_complex.h": ctypedef double * gsl_complex_packed_ptr ctypedef struct gsl_complex: - double dat[2] - double real "dat[0]" - double imag "dat[1]" + pass cdef extern from "gsl/gsl_block_double.h": diff --git a/src/sage/plot/complex_plot.pyx b/src/sage/plot/complex_plot.pyx index d688b6e4996..acebaa95d62 100644 --- a/src/sage/plot/complex_plot.pyx +++ b/src/sage/plot/complex_plot.pyx @@ -29,11 +29,11 @@ from sage.arith.srange import srange from libc.math cimport hypot, atan2, atan, log, sqrt from sage.arith.constants cimport M_PI as PI +from sage.libs.gsl.complex cimport * cdef inline ComplexDoubleElement new_CDF_element(double x, double y): z = ComplexDoubleElement.__new__(ComplexDoubleElement) - z._complex.real = x - z._complex.imag = y + GSL_SET_COMPLEX(&z._complex, x, y) return z @@ -113,7 +113,8 @@ def complex_to_rgb(z_values): z = zz else: z = CDF(zz) - x, y = z._complex.dat + x = GSL_REAL(z._complex) + y = GSL_IMAG(z._complex) mag = hypot(x, y) arg = atan2(y, x) # math module arctan has range from -pi to pi, so cut along negative x-axis diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 9038f2dd14f..0e94161063c 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -806,7 +806,7 @@ cdef class ComplexDoubleElement(FieldElement): True """ return (ComplexDoubleElement, - (self._complex.real, self._complex.imag)) + (GSL_REAL(self._complex), GSL_IMAG(self._complex))) cdef ComplexDoubleElement _new_c(self, gsl_complex x): """ @@ -871,13 +871,13 @@ cdef class ComplexDoubleElement(FieldElement): sage: 4.3 > CDF(5,1) False """ - if left._complex.real < (right)._complex.real: + if GSL_REAL(left._complex) < GSL_REAL((right)._complex): return rich_to_bool(op, -1) - if left._complex.real > (right)._complex.real: + if GSL_REAL(left._complex) > GSL_REAL((right)._complex): return rich_to_bool(op, 1) - if left._complex.imag < (right)._complex.imag: + if GSL_IMAG(left._complex) < GSL_IMAG((right)._complex): return rich_to_bool(op, -1) - if left._complex.imag > (right)._complex.imag: + if GSL_IMAG(left._complex) > GSL_IMAG((right)._complex): return rich_to_bool(op, 1) return rich_to_bool(op, 0) @@ -903,8 +903,10 @@ cdef class ComplexDoubleElement(FieldElement): ... IndexError: index n must be 0 or 1 """ - if n >= 0 and n <= 1: - return self._complex.dat[n] + if n == 0: + return GSL_REAL(self._complex) + if n == 1: + return GSL_IMAG(self._complex) raise IndexError("index n must be 0 or 1") def _magma_init_(self, magma): @@ -978,9 +980,9 @@ cdef class ComplexDoubleElement(FieldElement): sage: float(abs(CDF(1,1))) 1.4142135623730951 """ - if self._complex.imag: + if GSL_IMAG(self._complex): raise TypeError(f"unable to convert {self} to float; use abs() or real_part() as desired") - return self._complex.real + return GSL_REAL(self._complex) def __complex__(self): """ @@ -994,7 +996,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: complex(CDF(a)) (2303-3939j) """ - return complex(self._complex.real, self._complex.imag) + return complex(GSL_REAL(self._complex), GSL_IMAG(self._complex)) def _interface_init_(self, I=None): """ @@ -1052,7 +1054,8 @@ cdef class ComplexDoubleElement(FieldElement): sage: type(_) """ - x, y = self._complex.dat + x = GSL_REAL(self._complex) + y = GSL_IMAG(self._complex) import sympy return sympy.Float(x) + sympy.Float(y) * sympy.I @@ -1085,7 +1088,8 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(0) 0.0 """ - x, y = self._complex.dat + x = GSL_REAL(self._complex) + y = GSL_IMAG(self._complex) if x == 0: if y == 0: # Not sure what to do with the signs of the real and @@ -1136,8 +1140,8 @@ cdef class ComplexDoubleElement(FieldElement): sage: format(CDF(0, 0), '+#.4') '+0.000' """ - return complex_mpfr._format_complex_number(self._complex.real, - self._complex.imag, + return complex_mpfr._format_complex_number(GSL_REAL(self._complex), + GSL_IMAG(self._complex), format_spec) def _latex_(self): @@ -1171,10 +1175,10 @@ cdef class ComplexDoubleElement(FieldElement): sage: pari(CDF(I)) 1.00000000000000*I """ - if not self._complex.imag: - return new_gen_from_double(self._complex.real) + if not GSL_IMAG(self._complex): + return new_gen_from_double(GSL_REAL(self._complex)) else: - return new_t_COMPLEX_from_double(self._complex.real, self._complex.imag) + return new_t_COMPLEX_from_double(GSL_REAL(self._complex), GSL_IMAG(self._complex)) def __mpc__(self): """ @@ -1189,7 +1193,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: mpc(c) mpc('2.0+1.0j') """ - return gmpy2.mpc(self._complex.dat[0], self._complex.dat[1]) + return gmpy2.mpc(GSL_REAL(self._complex), GSL_IMAG(self._complex)) ####################################################################### # Arithmetic @@ -1471,7 +1475,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: a.real_part() 3.0 """ - return RealDoubleElement(self._complex.real) + return RealDoubleElement(GSL_REAL(self._complex)) real_part = real @@ -1487,7 +1491,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: a.imag_part() -2.0 """ - return RealDoubleElement(self._complex.imag) + return RealDoubleElement(GSL_IMAG(self._complex)) imag_part = imag @@ -1728,9 +1732,9 @@ cdef class ComplexDoubleElement(FieldElement): res = gsl_complex_rect(1, 0) elif other == -1: res = gsl_complex_inverse(self._complex) - elif not self._complex.imag: + elif not GSL_IMAG(self._complex): # If self is real, the result should be real too - real = self._complex.real ** other + real = GSL_REAL(self._complex) ** other res = gsl_complex_rect(real, 0) else: # General case @@ -1738,9 +1742,9 @@ cdef class ComplexDoubleElement(FieldElement): return self._new_c(res) cpdef _pow_int(self, other): - if not self._complex.imag: + if not GSL_IMAG(self._complex): # If self is real, the result should be real too - real = self._complex.real ** other + real = GSL_REAL(self._complex) ** other res = gsl_complex_rect(real, 0) else: # General case @@ -2267,10 +2271,10 @@ cdef class ComplexDoubleElement(FieldElement): """ cdef GEN a, b, c, y, t - if self._complex.imag <= 0: + if GSL_IMAG(self._complex) <= 0: raise ValueError("value must be in the upper half plane") - if self._complex.imag > 100000 and not omit_frac: + if GSL_IMAG(self._complex) > 100000 and not omit_frac: # To the precision of doubles for such large imaginary # part, the answer is automatically 0. If we don't do # this, PARI can easily underflow. @@ -2410,13 +2414,13 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(-1,0).gamma() Infinity """ - if not self._complex.imag: - if self._complex.real == 0: + if not GSL_IMAG(self._complex): + if GSL_REAL(self._complex) == 0: from .infinity import unsigned_infinity return unsigned_infinity try: from sage.rings.all import Integer, CC - if Integer(self._complex.real) < 0: + if Integer(GSL_REAL(self._complex)) < 0: return CC(self).gamma() except TypeError: pass @@ -2451,7 +2455,7 @@ cdef class ComplexDoubleElement(FieldElement): sage: zeta(CDF(1)) Infinity """ - if self._complex.real == 1 and self._complex.imag == 0: + if GSL_REAL(self._complex) == 1 and GSL_IMAG(self._complex) == 0: from .infinity import unsigned_infinity return unsigned_infinity return pari_to_cdf(self.__pari__().zeta()) @@ -2643,8 +2647,8 @@ cdef inline double complex extract_double_complex(ComplexDoubleElement x): Return the value of ``x`` as a c99 complex double. """ cdef double complex z - z.real = x._complex.real - z.imag = x._complex.imag + z.real = GSL_REAL(x._complex) + z.imag = GSL_IMAG(x._complex) return z @@ -2654,6 +2658,5 @@ cdef inline ComplexDoubleElement ComplexDoubleElement_from_doubles(double re, do imaginary parts. """ z = ComplexDoubleElement.__new__(ComplexDoubleElement) - z._complex.real = re - z._complex.imag = im + GSL_SET_COMPLEX(&z._complex, re, im) return z diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index b419914f23f..6768ec76234 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -52,6 +52,7 @@ from .integer cimport Integer from .complex_double cimport ComplexDoubleElement from .real_mpfr cimport RealNumber +from sage.libs.gsl.complex cimport * from sage.libs.mpmath.utils cimport mpfr_to_mpfval from sage.rings.integer_ring import ZZ @@ -3450,8 +3451,9 @@ cdef class CCtoCDF(Map): 0.7071067811865476 + 0.7071067811865475*I """ z = ComplexDoubleElement.__new__(ComplexDoubleElement) - z._complex.real = mpfr_get_d((x).__re, MPFR_RNDN) - z._complex.imag = mpfr_get_d((x).__im, MPFR_RNDN) + GSL_SET_COMPLEX(&z._complex, + mpfr_get_d((x).__re, MPFR_RNDN), + mpfr_get_d((x).__im, MPFR_RNDN)) return z diff --git a/src/sage/rings/convert/mpfi.pyx b/src/sage/rings/convert/mpfi.pyx index a7d1561ec09..0e5e68c8825 100644 --- a/src/sage/rings/convert/mpfi.pyx +++ b/src/sage/rings/convert/mpfi.pyx @@ -16,6 +16,7 @@ from cpython.complex cimport PyComplex_RealAsDouble, PyComplex_ImagAsDouble from sage.libs.mpfr cimport * from sage.libs.mpfi cimport * +from sage.libs.gsl.complex cimport * from sage.arith.long cimport integer_check_long from sage.cpython.string cimport bytes_to_str @@ -135,11 +136,11 @@ cdef int mpfi_set_sage(mpfi_ptr re, mpfi_ptr im, x, field, int base) except -1: if isinstance(x, ComplexDoubleElement): zd = x if im is NULL: - if zd._complex.imag: + if GSL_IMAG(zd._complex): raise TypeError(f"unable to convert complex number {x!r} to real interval") else: - mpfi_set_d(im, zd._complex.imag) - mpfi_set_d(re, zd._complex.real) + mpfi_set_d(im, GSL_IMAG(zd._complex)) + mpfi_set_d(re, GSL_REAL(zd._complex)) return 0 else: # not a Sage Element # Real diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index 880a07faf17..4b46fc69133 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -1734,7 +1734,7 @@ cdef py_log(x): return math.log(real) elif real < 0: res = gsl_complex_log(gsl_complex_rect(real, 0)) - return PyComplex_FromDoubles(res.real, res.imag) + return PyComplex_FromDoubles(GSL_REAL(res), GSL_IMAG(res)) else: return float('-inf') elif type(x) is complex: @@ -1743,7 +1743,7 @@ cdef py_log(x): if real == 0 and imag == 0: return float('-inf') res = gsl_complex_log(gsl_complex_rect(real, imag)) - return PyComplex_FromDoubles(res.real, res.imag) + return PyComplex_FromDoubles(GSL_REAL(res), GSL_IMAG(res)) elif isinstance(x, Integer): return x.log().n() elif hasattr(x, 'log'): diff --git a/src/sage_setup/autogen/interpreters/specs/cdf.py b/src/sage_setup/autogen/interpreters/specs/cdf.py index 1921c807c80..7f09c3b6a5c 100644 --- a/src/sage_setup/autogen/interpreters/specs/cdf.py +++ b/src/sage_setup/autogen/interpreters/specs/cdf.py @@ -157,6 +157,7 @@ def __init__(self): """) self.pyx_header = ri(0, """ + from sage.libs.gsl.complex cimport * from sage.rings.complex_double cimport ComplexDoubleElement import sage.rings.complex_double cdef object CDF = sage.rings.complex_double.CDF @@ -168,12 +169,11 @@ def __init__(self): cdef inline double_complex CDE_to_dz(zz): cdef ComplexDoubleElement z = (zz if isinstance(zz, ComplexDoubleElement) else CDF(zz)) - return z._complex.real + _Complex_I * z._complex.imag + return GSL_REAL(z._complex) + _Complex_I * GSL_IMAG(z._complex) cdef inline ComplexDoubleElement dz_to_CDE(double_complex dz): cdef ComplexDoubleElement z = ComplexDoubleElement.__new__(ComplexDoubleElement) - z._complex.real = creal(dz) - z._complex.imag = cimag(dz) + GSL_SET_COMPLEX(&z._complex, creal(dz), cimag(dz)) return z cdef public bint cdf_py_call_helper(object fn, From f681abb442a578c5fa5686a337fc5adf5ae2485d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 8 Apr 2021 15:16:03 -0700 Subject: [PATCH 157/378] build/bin/sage-spkg: Also source sage-src-env-config so that SAGE_VENV is available --- build/bin/sage-spkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 7f390e3a0f2..7f778954d24 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -498,7 +498,7 @@ export PKG_NAME="$PKG_NAME" export PKG_BASE="$PKG_BASE" export PKG_VER="$PKG_VER" -for lib in "\$SAGE_ROOT/build/bin/sage-dist-helpers" "\$SAGE_SRC/bin/sage-env-config" "\$SAGE_SRC/bin/sage-env" "\$SAGE_ROOT/build/bin/sage-build-env-config" "\$SAGE_ROOT/build/bin/sage-build-env"; do +for lib in "\$SAGE_ROOT/build/bin/sage-dist-helpers" "\$SAGE_SRC/bin/sage-src-env-config" "\$SAGE_SRC/bin/sage-env-config" "\$SAGE_SRC/bin/sage-env" "\$SAGE_ROOT/build/bin/sage-build-env-config" "\$SAGE_ROOT/build/bin/sage-build-env"; do source "\$lib" if [ \$? -ne 0 ]; then echo >&2 "Error: failed to source \$lib" From 271f765fc84fb1e61182d4bd0afbacd66a2d0084 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 23 Oct 2021 19:00:14 +0200 Subject: [PATCH 158/378] trac #32748: better handling of networkx graphs in (di)graph constructor --- src/sage/graphs/digraph.py | 44 ++------ src/sage/graphs/graph.py | 40 +++---- src/sage/graphs/graph_input.py | 190 +++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 62 deletions(-) diff --git a/src/sage/graphs/digraph.py b/src/sage/graphs/digraph.py index bcf919c4a7d..4047a09c127 100644 --- a/src/sage/graphs/digraph.py +++ b/src/sage/graphs/digraph.py @@ -419,12 +419,12 @@ class DiGraph(GenericGraph): RuntimeError: the string seems corrupt: valid characters are ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ - #. A NetworkX XDiGraph:: + #. A NetworkX MultiDiGraph:: sage: import networkx sage: g = networkx.MultiDiGraph({0: [1, 2, 3], 2: [4]}) sage: DiGraph(g) - Digraph on 5 vertices + Multi-digraph on 5 vertices #. A NetworkX digraph:: @@ -697,12 +697,9 @@ def __init__(self, data=None, pos=None, loops=None, format=None, else: format = 'dict_of_lists' if format is None and hasattr(data, 'adj'): - import networkx - if isinstance(data, (networkx.Graph, networkx.MultiGraph)): - data = data.to_directed() - format = 'NX' - elif isinstance(data, (networkx.DiGraph, networkx.MultiDiGraph)): - format = 'NX' + # the input is a networkx (Multi)(Di)Graph + format = 'NX' + if (format is None and hasattr(data, 'vcount') and hasattr(data, 'get_edgelist')): @@ -804,34 +801,13 @@ def __init__(self, data=None, pos=None, loops=None, format=None, from_dict_of_lists(self, data, loops=loops, multiedges=multiedges, weighted=weighted) elif format == 'NX': - # adjust for empty dicts instead of None in NetworkX default edge - # labels - if convert_empty_dict_labels_to_None is None: - convert_empty_dict_labels_to_None = (format == 'NX') - + from sage.graphs.graph_input import from_networkx_graph + from_networkx_graph(self, data, + weighted=weighted, multiedges=multiedges, loops=loops, + convert_empty_dict_labels_to_None=convert_empty_dict_labels_to_None) if weighted is None: - import networkx - if isinstance(data, networkx.DiGraph): - weighted = False - if multiedges is None: - multiedges = False - if loops is None: - loops = False - else: - weighted = True - if multiedges is None: - multiedges = data.multiedges - if loops is None: - loops = data.selfloops - if convert_empty_dict_labels_to_None: - r = lambda x: None if x == {} else x - else: - r = lambda x: x + weighted = self.allows_multiple_edges() - self.allow_multiple_edges(multiedges, check=False) - self.allow_loops(loops, check=False) - self.add_vertices(data.nodes()) - self.add_edges((u, v, r(l)) for u, v, l in data.edges(data=True)) elif format == 'igraph': if not data.is_directed(): raise ValueError("a *directed* igraph graph was expected. To " diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 4d37caa6bbb..75fb6241f23 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -797,7 +797,7 @@ class Graph(GenericGraph): sage: import networkx sage: g = networkx.MultiGraph({0:[1,2,3], 2:[4]}) sage: Graph(g) - Graph on 5 vertices + Multi-graph on 5 vertices #. A NetworkX graph:: @@ -1096,11 +1096,8 @@ def __init__(self, data=None, pos=None, loops=None, format=None, elif isinstance(val, dict): format = 'dict_of_dicts' if format is None and hasattr(data, 'adj'): - import networkx - if isinstance(data, (networkx.DiGraph, networkx.MultiDiGraph)): - data = data.to_undirected() - elif isinstance(data, (networkx.Graph, networkx.MultiGraph)): - format = 'NX' + # the input is a networkx (Multi)(Di)Graph + format = 'NX' if (format is None and hasattr(data, 'vcount') and @@ -1183,29 +1180,15 @@ def __init__(self, data=None, pos=None, loops=None, format=None, self.name(data.name()) self.set_vertices(data.get_vertices()) data._backend.subgraph_given_vertices(self._backend, data) + elif format == 'NX': - if convert_empty_dict_labels_to_None is not False: - r = lambda x: None if x=={} else x - else: - r = lambda x: x + from sage.graphs.graph_input import from_networkx_graph + from_networkx_graph(self, data, + weighted=weighted, multiedges=multiedges, loops=loops, + convert_empty_dict_labels_to_None=convert_empty_dict_labels_to_None) if weighted is None: - import networkx - if isinstance(data, networkx.Graph): - weighted = False - if multiedges is None: - multiedges = False - if loops is None: - loops = False - else: - weighted = True - if multiedges is None: - multiedges = True - if loops is None: - loops = True - self.allow_loops(loops, check=False) - self.allow_multiple_edges(multiedges, check=False) - self.add_vertices(data.nodes()) - self.add_edges((u,v,r(l)) for u,v,l in data.edges(data=True)) + weighted = self.allows_multiple_edges() + elif format == 'igraph': if data.is_directed(): raise ValueError("An *undirected* igraph graph was expected. "+ @@ -6392,7 +6375,8 @@ def cliques_get_max_clique_graph(self): sage: (G.cliques_get_max_clique_graph()).show(figsize=[2,2]) """ import networkx - return Graph(networkx.make_max_clique_graph(self.networkx_graph(), create_using=networkx.MultiGraph())) + return Graph(networkx.make_max_clique_graph(self.networkx_graph(), create_using=networkx.MultiGraph()), + multiedges=False) @doc_index("Clique-related methods") def cliques_get_clique_bipartite(self, **kwds): diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 77f93b96bf4..88f8bdad705 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -561,6 +561,196 @@ def from_dict_of_lists(G, D, loops=False, multiedges=False, weighted=False): for v in D[u]: G._backend.add_edge(u, v, None, is_directed) +def from_networkx_graph(G, gnx, weighted=None, loops=None, multiedges=None, + convert_empty_dict_labels_to_None=None): + r""" + Fill `G` with the data of a NetworkX (di)graph. + + + INPUT: + + - ``G`` -- a :class:`Graph` or :class:`DiGraph` + + - ``gnx`` -- a NetworkX ``Graph``, ``MultiGraph``, ``DiGraph`` or + ``MultiDiGraph`` + + - ``weighted`` -- boolean (default: ``None``); whether graph thinks of + itself as weighted or not. See + :meth:`~sage.graphs.generic_graph.GenericGraph.weighted`. + + - ``loops`` -- boolean (default: ``None``); whether to allow loops + + - ``multiedges`` -- boolean (default: ``None``); whether to allow multiple + edges + + - ``convert_empty_dict_labels_to_None`` -- boolean (default: ``None``); + whether to replace the default edge labels used by NetworkX (empty + dictionaries) by ``None``, the default Sage edge label. When set to + ``False``, empty dictionaries are not converted to ``None``. + + EXAMPLES: + + Feeding a :class:`Graph` with a NetworkX ``Graph``:: + + sage: from sage.graphs.graph_input import from_networkx_graph + sage: import networkx + sage: G = Graph() + sage: _ = gnx = networkx.Graph() + sage: _ = gnx.add_edge(0, 1) + sage: _ = gnx.add_edge(1, 2) + sage: from_networkx_graph(G, gnx) + sage: G.edges(sort=True, labels=False) + [(0, 1), (1, 2)] + + Feeding a :class:`Graph` with a NetworkX ``MultiGraph``:: + + sage: G = Graph() + sage: gnx = networkx.MultiGraph() + sage: _ = gnx.add_edge(0, 1) + sage: _ = gnx.add_edge(0, 1) + sage: from_networkx_graph(G, gnx) + sage: G.edges(labels=False) + [(0, 1), (0, 1)] + sage: G = Graph() + sage: from_networkx_graph(G, gnx, multiedges=False) + sage: G.edges(labels=False) + [(0, 1)] + + When feeding a :class:`Graph` `G` with a NetworkX ``DiGraph`` `D`, `G` has + one edge `(u, v)` whenever `D` has arc `(u, v)` or `(v, u)` or both:: + + sage: G = Graph() + sage: D = networkx.DiGraph() + sage: _ = D.add_edge(0, 1) + sage: from_networkx_graph(G, D) + sage: G.edges(labels=False) + [(0, 1)] + sage: G = Graph() + sage: _ = D.add_edge(1, 0) + sage: from_networkx_graph(G, D) + sage: G.edges(labels=False) + [(0, 1)] + + When feeding a :class:`Graph` `G` with a NetworkX ``MultiDiGraph`` `D`, the + number of edges between `u` and `v` in `G` is the maximum between the number + of arcs `(u, v)` and the number of arcs `(v, u)` in D`:: + + sage: G = Graph() + sage: D = networkx.MultiDiGraph() + sage: _ = D.add_edge(0, 1) + sage: _ = D.add_edge(1, 0) + sage: _ = D.add_edge(1, 0) + sage: D.edges() + OutMultiEdgeDataView([(0, 1), (1, 0), (1, 0)]) + sage: from_networkx_graph(G, D) + sage: G.edges(labels=False) + [(0, 1), (0, 1)] + + Feeding a :class:`DiGraph` with a NetworkX ``DiGraph``:: + + sage: from sage.graphs.graph_input import from_networkx_graph + sage: import networkx + sage: G = DiGraph() + sage: _ = gnx = networkx.DiGraph() + sage: _ = gnx.add_edge(0, 1) + sage: _ = gnx.add_edge(1, 2) + sage: from_networkx_graph(G, gnx) + sage: G.edges(sort=True, labels=False) + [(0, 1), (1, 2)] + + Feeding a :class:`DiGraph` with a NetworkX ``MultiDiGraph``:: + + sage: G = DiGraph() + sage: gnx = networkx.MultiDiGraph() + sage: _ = gnx.add_edge(0, 1) + sage: _ = gnx.add_edge(0, 1) + sage: from_networkx_graph(G, gnx) + sage: G.edges(labels=False) + [(0, 1), (0, 1)] + sage: G = DiGraph() + sage: from_networkx_graph(G, gnx, multiedges=False) + sage: G.edges(labels=False) + [(0, 1)] + + When feeding a :class:`DiGraph` `G` with a NetworkX ``Graph`` `H`, `G` has + both arcs `(u, v)` and `(v, u)` if `G` has edge `(u, v)`:: + + sage: G = DiGraph() + sage: H = networkx.Graph() + sage: _ = H.add_edge(0, 1) + sage: from_networkx_graph(G, H) + sage: G.edges(labels=False, sort=True) + [(0, 1), (1, 0)] + + When feeding a :class:`DiGraph` `G` with a NetworkX ``MultiGraph`` `H`, `G` + has `k` arcs `(u, v)` and `k` arcs `(v, u)` if `H` has `k` edges `(u, v)`, + unless parameter ``multiedges`` is set to ``False``:: + + sage: G = DiGraph() + sage: H = networkx.MultiGraph() + sage: _ = H.add_edge(0, 1) + sage: _ = H.add_edge(0, 1) + sage: _ = H.add_edge(0, 1) + sage: H.edges() + MultiEdgeDataView([(0, 1), (0, 1), (0, 1)]) + sage: from_networkx_graph(G, H) + sage: G.edges(labels=False, sort=True) + [(0, 1), (0, 1), (0, 1), (1, 0), (1, 0), (1, 0)] + sage: G = DiGraph() + sage: from_networkx_graph(G, H, multiedges=False) + sage: G.edges(labels=False, sort=True) + [(0, 1), (1, 0)] + + TESTS: + + The first parameter must be a :class:`Graph` or :class:`DiGraph`:: + + sage: from sage.graphs.graph_input import from_networkx_graph + sage: from_networkx_graph("foo", "bar") + Traceback (most recent call last): + ... + ValueError: the first parameter must a Sage Graph or DiGraph + + The second parameter must be a NetworkX ``Graph``, ``MultiGraph``, + ``DiGraph`` or ``MultiDiGraph``:: + + sage: from sage.graphs.graph_input import from_networkx_graph + sage: from_networkx_graph(Graph(), "bar") + Traceback (most recent call last): + ... + ValueError: the second parameter must be a NetworkX (Multi)(Di)Graph + """ + from sage.graphs.graph import Graph + from sage.graphs.digraph import DiGraph + if not isinstance(G, (Graph, DiGraph)): + raise ValueError("the first parameter must a Sage Graph or DiGraph") + import networkx + if not isinstance(gnx, (networkx.Graph, networkx.DiGraph)): + raise ValueError("the second parameter must be a NetworkX (Multi)(Di)Graph") + + if G.is_directed() != gnx.is_directed(): + if gnx.is_directed(): + gnx = gnx.to_undirected() + else: + gnx = gnx.to_directed() + + if weighted is None: + if multiedges is None: + multiedges = gnx.is_multigraph() + if loops is None: + loops = any(u == v for u, v in gnx.edges()) + + G.allow_loops(loops, check=False) + G.allow_multiple_edges(multiedges, check=False) + G.add_vertices(gnx.nodes()) + G.set_vertices(gnx.nodes(data=True)) + if convert_empty_dict_labels_to_None is not False: + def r(l): + return None if l == {} else l + G.add_edges((u, v, r(l)) for u, v, l in gnx.edges(data=True)) + else: + G.add_edges(gnx.edges(data=True)) + from sage.misc.rest_index_of_methods import gen_rest_table_index import sys __doc__ = __doc__.format(INDEX_OF_FUNCTIONS=gen_rest_table_index(sys.modules[__name__])) From 7438449576052a809cfa460d7d21ee9338fcaef0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 10:41:41 -0700 Subject: [PATCH 159/378] src/bin/sage-env: Do not skip the script if SAGE_ENV_SOURCED was set but SAGE_VENV has changed --- src/bin/sage-env | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bin/sage-env b/src/bin/sage-env index ac8506ffba6..1f3339cf25d 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -131,7 +131,9 @@ fi # Don't execute the commands more than once for the same version of -# sage-env. Check this after checking the validity of SAGE_ROOT, but +# sage-env... for the same combination of SAGE_LOCAL and SAGE_VENV. +# +# Check this after checking the validity of SAGE_ROOT, but # before modifying its value. # # The idea of versioning is that SAGE_ENV_SOURCED will be set to a @@ -147,13 +149,14 @@ fi # - sage-5.4: version 2 (#13395) # - sage-5.10: version 3 (#14699) # - sage-6.0: version 4 (#14715) +# - sage-9.5: version 5 (#32745) # -SAGE_ENV_VERSION=4 +SAGE_ENV_VERSION="5:$SAGE_LOCAL:$SAGE_VENV" if [ "$SAGE_ENV_SOURCED" = "$SAGE_ENV_VERSION" ]; then # Already sourced, nothing to do. return 0 fi -export SAGE_ENV_SOURCED=$SAGE_ENV_VERSION +export SAGE_ENV_SOURCED="$SAGE_ENV_VERSION" if [ -n "$NEW_SAGE_ROOT" ]; then export SAGE_ROOT="$NEW_SAGE_ROOT" From b07c8e3a33d235e1fd2879e2e6808a1ced1bcd4a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 10:42:19 -0700 Subject: [PATCH 160/378] build/bin/sage-spkg: Remove workaround of setting of PATH in the generated package scripts --- build/bin/sage-spkg | 1 - 1 file changed, 1 deletion(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 7f778954d24..317450c01e7 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -506,7 +506,6 @@ for lib in "\$SAGE_ROOT/build/bin/sage-dist-helpers" "\$SAGE_SRC/bin/sage-src-en exit 1 fi done -export PATH="$SAGE_INST_LOCAL/bin:$PATH" export SAGE_INST_LOCAL="$SAGE_INST_LOCAL" From e7e2f3f76ccd799bbc0e4ba3b38db0790536aa2a Mon Sep 17 00:00:00 2001 From: "John H. Palmieri" Date: Sat, 23 Oct 2021 10:45:30 -0700 Subject: [PATCH 161/378] trac 32587: add pkgconf as order-only dependency for gsl, add library path for gsl configure --- build/pkgs/gsl/dependencies | 2 +- build/pkgs/gsl/spkg-install.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/gsl/dependencies b/build/pkgs/gsl/dependencies index 052eb4373db..576809127c7 100644 --- a/build/pkgs/gsl/dependencies +++ b/build/pkgs/gsl/dependencies @@ -1,4 +1,4 @@ -$(BLAS) +$(BLAS) | pkgconf ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/gsl/spkg-install.in b/build/pkgs/gsl/spkg-install.in index 179b78963a1..ef156a7a5c5 100644 --- a/build/pkgs/gsl/spkg-install.in +++ b/build/pkgs/gsl/spkg-install.in @@ -1,5 +1,5 @@ cd src -sdh_configure LIBS="`pkg-config --libs-only-l cblas` -lm" +sdh_configure LIBS="`pkg-config --libs-only-l cblas` -lm" LDFLAGS="$LDFLAGS `pkg-config --libs-only-L cblas`" sdh_make sdh_make_install From 59d7245435b006946504f7c6a84aef42cbe66648 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 13:02:52 -0700 Subject: [PATCH 162/378] build/pkgs/numpy/spkg-install.in: Make sure that site.cfg contains the directories of SAGE_LOCAL --- build/pkgs/numpy/spkg-install.in | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build/pkgs/numpy/spkg-install.in b/build/pkgs/numpy/spkg-install.in index b7dc3a67295..cb567c82bee 100644 --- a/build/pkgs/numpy/spkg-install.in +++ b/build/pkgs/numpy/spkg-install.in @@ -16,7 +16,11 @@ if [ "$UNAME" = "CYGWIN" ]; then export CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE" fi -python3 ../lapack_conf.py +# Trac #32746: pkg-config omits -I and -L flags that refer to directories +# that are already on CPATH, LIBRARY_PATH. +# But our script tries to obtain the list of include_dirs and library_dirs +# from pkg-config! +(unset CPATH LIBRARY_PATH; python3 ../lapack_conf.py) # Make sure that the fortran objects are compiled with -fPIC export FFLAGS="$FFLAGS -fPIC" From 1dc709ce75e5899b6196c44c076321963be7cba2 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 5 Oct 2021 23:17:17 -0700 Subject: [PATCH 163/378] sage.rings.{integer,rational}: Copy numbers abc registration here from sage.rings.numbers_abc --- src/sage/rings/integer.pyx | 5 +++++ src/sage/rings/rational.pyx | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 56de0fc858a..15f2c6c0d5b 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -7564,3 +7564,8 @@ cdef double mpz_get_d_nearest(mpz_t x) except? -648555075988944.5: if resultsign < 0: d = -d return ldexp(d, shift) + + +# Support Python's numbers abstract base class +import numbers +numbers.Integral.register(Integer) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 6e02cf4387d..ea9436d81bd 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -4297,3 +4297,8 @@ cdef class long_to_Q(Morphism): 'Native' """ return "Native" + + +# Support Python's numbers abstract base class +import numbers +numbers.Rational.register(Rational) From 8024209b2e872b8428ead1d2f7c5777a73c5fb73 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 15:27:04 -0700 Subject: [PATCH 164/378] sage.rings.numbers_abc: Move remaining numbers abc registrations to the individual implementation modules --- src/sage/rings/complex_double.pyx | 5 +++++ src/sage/rings/complex_mpc.pyx | 5 +++++ src/sage/rings/complex_mpfr.pyx | 5 +++++ src/sage/rings/numbers_abc.py | 24 ++---------------------- src/sage/rings/qqbar.py | 6 ++++++ src/sage/rings/real_double.pyx | 5 +++++ src/sage/rings/real_mpfr.pyx | 5 +++++ 7 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 9038f2dd14f..204066e4904 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -2657,3 +2657,8 @@ cdef inline ComplexDoubleElement ComplexDoubleElement_from_doubles(double re, do z._complex.real = re z._complex.imag = im return z + + +# Support Python's numbers abstract base class +import numbers +numbers.Complex.register(ComplexDoubleElement) diff --git a/src/sage/rings/complex_mpc.pyx b/src/sage/rings/complex_mpc.pyx index e7f287aa9c9..b6780014030 100644 --- a/src/sage/rings/complex_mpc.pyx +++ b/src/sage/rings/complex_mpc.pyx @@ -2575,3 +2575,8 @@ cdef class CCtoMPC(Map): y = (self.codomain())._new() mpc_set_fr_fr(y.value, (z).__re, (z).__im, rnd) return y + + +# Support Python's numbers abstract base class +import numbers +from sage.rings.complex_mpc import MPComplexNumber diff --git a/src/sage/rings/complex_mpfr.pyx b/src/sage/rings/complex_mpfr.pyx index b419914f23f..91a6d47fd45 100644 --- a/src/sage/rings/complex_mpfr.pyx +++ b/src/sage/rings/complex_mpfr.pyx @@ -3610,3 +3610,8 @@ def _format_complex_number(real, imag, format_spec): "complex format specifier") result = format(result, align + width) return result + + +# Support Python's numbers abstract base class +import numbers +numbers.Complex.register(ComplexNumber) diff --git a/src/sage/rings/numbers_abc.py b/src/sage/rings/numbers_abc.py index 17290651196..478a0b36408 100644 --- a/src/sage/rings/numbers_abc.py +++ b/src/sage/rings/numbers_abc.py @@ -14,8 +14,6 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -import numbers - def register_sage_classes(): """ @@ -65,23 +63,5 @@ def register_sage_classes(): sage: isscalar(4/17) True """ - from sage.rings.integer import Integer - from sage.rings.rational import Rational - from sage.rings.real_mpfr import RealNumber - from sage.rings.real_double import RealDoubleElement - from sage.rings.complex_mpfr import ComplexNumber - from sage.rings.complex_double import ComplexDoubleElement - from sage.rings.complex_mpc import MPComplexNumber - from sage.rings.qqbar import AlgebraicReal, AlgebraicNumber - - numbers.Integral.register(Integer) - numbers.Rational.register(Rational) - numbers.Real.register(RealNumber) - numbers.Real.register(RealDoubleElement) - numbers.Real.register(AlgebraicReal) - numbers.Complex.register(ComplexNumber) - numbers.Complex.register(MPComplexNumber) - numbers.Complex.register(ComplexDoubleElement) - numbers.Complex.register(AlgebraicNumber) - -register_sage_classes() + from sage.misc.superseded import deprecation + deprecation(32641, "register_sage_classes is a deprecated no-op") diff --git a/src/sage/rings/qqbar.py b/src/sage/rings/qqbar.py index ae926cde625..2cc17707a47 100644 --- a/src/sage/rings/qqbar.py +++ b/src/sage/rings/qqbar.py @@ -8546,3 +8546,9 @@ def get_AA_golden_ratio(): AA_golden_ratio_generator = AlgebraicGenerator(AA_golden_ratio_nf, ANRoot(AAPoly.gen()**2 - AAPoly.gen() - 1, RIF(1.618, 1.6181))) AA_golden_ratio = AlgebraicReal(ANExtensionElement(AA_golden_ratio_generator, AA_golden_ratio_nf.gen())) return AA_golden_ratio + + +# Support Python's numbers abstract base class +import numbers +numbers.Real.register(AlgebraicReal) +numbers.Complex.register(AlgebraicNumber) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 405153db6b9..b22897510c0 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -2943,3 +2943,8 @@ cdef double_repr(double x): if v < 0: return "-infinity" return "NaN" + + +# Support Python's numbers abstract base class +import numbers +numbers.Real.register(RealDoubleElement) diff --git a/src/sage/rings/real_mpfr.pyx b/src/sage/rings/real_mpfr.pyx index 774ab916659..a5bfcc070e8 100644 --- a/src/sage/rings/real_mpfr.pyx +++ b/src/sage/rings/real_mpfr.pyx @@ -6122,3 +6122,8 @@ def create_RealField(*args, **kwds): deprecation(24511, "Please import create_RealField from sage.rings.real_field") from sage.rings.real_field import create_RealField as cr return cr(*args, **kwds) + + +# Support Python's numbers abstract base class +import numbers +numbers.Real.register(RealNumber) From 0226a92f647ae459926f0d6f04bf5df7b15ed0cd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:04:33 -0700 Subject: [PATCH 165/378] sage.rings.abc: Add pAdicRingGeneric, pAdicFieldGeneric; deprecate is_pAdicRing, is_pAdicField --- src/sage/rings/abc.pyx | 18 ++++++++++++++++++ src/sage/rings/padics/generic_nodes.py | 10 ++++++++-- .../rings/polynomial/polynomial_element.pyx | 3 +-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/abc.pyx b/src/sage/rings/abc.pyx index 2c5e2253150..1440a30f569 100644 --- a/src/sage/rings/abc.pyx +++ b/src/sage/rings/abc.pyx @@ -1,6 +1,8 @@ """ Abstract base classes for rings """ +from sage.rings.ring import EuclideanDomain + cdef class RealField(Field): r""" @@ -79,3 +81,19 @@ class Order: """ pass + + +class pAdicRing(EuclideanDomain): + r""" + Abstract base class for :class:`~sage.rings.padics.generic_nodes.pAdicRingGeneric`. + """ + + pass + + +class pAdicField(Field): + r""" + Abstract base class for :class:`~sage.rings.padics.generic_nodes.pAdicFieldGeneric`. + """ + + pass diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 00c6b63f5df..0eacec21b3c 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -24,6 +24,7 @@ from sage.rings.padics.local_generic import LocalGeneric from sage.rings.padics.padic_generic import pAdicGeneric from sage.rings.ring import EuclideanDomain, Field +import sage.rings.abc from sage.rings.padics.padic_base_generic import pAdicBaseGeneric from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ @@ -1191,9 +1192,12 @@ def is_pAdicRing(R): sage: is_pAdicRing(RR) False """ + from sage.misc.superseded import deprecation + deprecation(32750, "is_pAdicRing is deprecated; use isinstance(..., sage.rings.abc.pAdicRing) instead") return isinstance(R, pAdicRingGeneric) -class pAdicRingGeneric(pAdicGeneric, EuclideanDomain): + +class pAdicRingGeneric(pAdicGeneric, sage.rings.abc.pAdicRing): def is_field(self, proof = True): """ Return whether this ring is actually a field, ie ``False``. @@ -1331,10 +1335,12 @@ def is_pAdicField(R): sage: is_pAdicField(Qp(17)) True """ + from sage.misc.superseded import deprecation + deprecation(32750, "is_pAdicField is deprecated; use isinstance(..., sage.rings.abc.pAdicField) instead") return isinstance(R, pAdicFieldGeneric) -class pAdicFieldGeneric(pAdicGeneric, Field): +class pAdicFieldGeneric(pAdicGeneric, sage.rings.abc.pAdicField): pass #def class_field(self, group=None, map=None, generators=None): diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 056c39152f0..161c99ebffe 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -104,7 +104,6 @@ from sage.rings.integer_ring import ZZ, is_IntegerRing from sage.rings.integer cimport Integer, smallInteger from sage.libs.gmp.mpz cimport * from sage.rings.fraction_field import is_FractionField -from sage.rings.padics.generic_nodes import is_pAdicRing, is_pAdicField from sage.rings.padics.padic_generic import pAdicGeneric from sage.structure.category_object cimport normalize_names @@ -8025,7 +8024,7 @@ cdef class Polynomial(CommutativeAlgebraElement): real_field = RealField(L.prec()) return self.change_ring(real_field).roots(ring=L, multiplicities=multiplicities, algorithm=algorithm) - elif (is_pAdicRing(L) or is_pAdicField(L)) and L.absolute_degree() == 1: + elif isinstance(L, (sage.rings.abc.pAdicRing, sage.rings.abc.pAdicField)) and L.absolute_degree() == 1: p = L.prime() n = L.precision_cap() try: From 1893620abb20b4a0d08c4654a8be88a2c5a62044 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:06:13 -0700 Subject: [PATCH 166/378] src/sage/dynamics/arithmetic_dynamics/projective_ds.py: Use sage.rings.abc.pAdicRing, pAdicField --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 27f9c39b583..c731b9abb82 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -872,10 +872,9 @@ def dynatomic_polynomial(self, period): PHI = PHI(fm._polys) / PHI(fm1._polys) #even when the ring can be passed to singular in quo_rem, #it can't always do the division, so we call Maxima - from sage.rings.padics.generic_nodes import is_pAdicField, is_pAdicRing if period != [0,1]: #period==[0,1] we don't need to do any division BR = self.domain().base_ring().base_ring() - if not (is_pAdicRing(BR) or is_pAdicField(BR)): + if not isinstance(BR, (sage.rings.abc.pAdicRing, sage.rings.abc.pAdicField)): try: QR2 = PHI.numerator()._maxima_().divide(PHI.denominator()) if not QR2[1].sage(): From 8422015957e564ab96d03ee6a12b3ce46db820e1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:09:58 -0700 Subject: [PATCH 167/378] src/sage/modular/overconvergent/genus0.py: Use sage.rings.abc.pAdicField --- src/sage/modular/overconvergent/genus0.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index 1a39e7fea33..7d5f7988ce8 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -184,7 +184,9 @@ from sage.structure.element import Vector, ModuleElement from sage.structure.richcmp import richcmp from sage.plot.plot import plot -from sage.rings.all import (O, Infinity, ZZ, QQ, pAdicField, PolynomialRing, PowerSeriesRing, is_pAdicField) +from sage.rings.integer_ring import ZZ +from sage.rings.rational_field import QQ +from sage.rings.all import (O, Infinity, pAdicField, PolynomialRing, PowerSeriesRing) import weakref from .weightspace import WeightSpace_constructor as WeightSpace, WeightCharacter @@ -295,7 +297,7 @@ def __init__(self, prime, weight, radius, base_ring, prec, char): self._p = prime - if not ( base_ring == QQ or is_pAdicField(base_ring) ): + if not ( base_ring == QQ or isinstance(base_ring, sage.rings.abc.pAdicField) ): raise TypeError("Base ring must be QQ or a p-adic field") if base_ring != QQ and base_ring.prime() != self._p: @@ -1033,9 +1035,9 @@ def slopes(self, n, use_recurrence=False): [0, 2, 4, 6, 8] """ if self.base_ring() == QQ: - slopelist=self.cps_u(n).truncate().newton_slopes(self.prime()) - elif is_pAdicField(self.base_ring()): - slopelist=self.cps_u(n).truncate().newton_slopes() + slopelist = self.cps_u(n).truncate().newton_slopes(self.prime()) + elif isinstance(self.base_ring(), sage.rings.abc.pAdicField): + slopelist = self.cps_u(n).truncate().newton_slopes() else: print("slopes are only defined for base field QQ or a p-adic field") return [-i for i in slopelist] @@ -1574,7 +1576,7 @@ def r_ord(self, r): s = self.parent().radius() F = self.parent().base_ring() - if not is_pAdicField(F): + if not isinstance(F, sage.rings.abc.pAdicField): F = pAdicField(p) for i in range(self.prec()): @@ -1595,7 +1597,7 @@ def valuation(self): sage: (3^18 * (M.2)).valuation() 18 """ - if is_pAdicField(self.parent().base_ring()): + if isinstance(self.parent().base_ring(), sage.rings.abc.pAdicField): v = lambda u: u.normalized_valuation() else: v = lambda u: u.valuation(self.parent().prime()) @@ -1614,7 +1616,7 @@ def governing_term(self, r): """ p = self.prime() F = self.parent().base_ring() - if not is_pAdicField(F): + if not isinstance(F, sage.rings.abc.pAdicField): F = pAdicField(p) s = self.parent().radius() p = self.prime() From c32b3a239df5961bb9ef03afb9cfed255d6a6665 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:13:20 -0700 Subject: [PATCH 168/378] src/sage/schemes/berkovich: Use sage.rings.abc.pAdicField --- src/sage/schemes/berkovich/berkovich_cp_element.py | 10 +++++----- src/sage/schemes/berkovich/berkovich_space.py | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/schemes/berkovich/berkovich_cp_element.py b/src/sage/schemes/berkovich/berkovich_cp_element.py index ef419c0b50a..1f868be527d 100644 --- a/src/sage/schemes/berkovich/berkovich_cp_element.py +++ b/src/sage/schemes/berkovich/berkovich_cp_element.py @@ -35,10 +35,10 @@ from sage.structure.element import Element from sage.structure.element import Expression +import sage.rings.abc from sage.rings.real_mpfr import RR, is_RealNumber from sage.rings.padics.padic_generic_element import pAdicGenericElement from sage.rings.padics.padic_base_generic import pAdicBaseGeneric -from sage.rings.padics.generic_nodes import is_pAdicField from sage.schemes.projective.projective_space import ProjectiveSpace from sage.schemes.projective.projective_point import SchemeMorphism_point_projective_field from sage.rings.rational_field import QQ @@ -187,7 +187,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= except (TypeError, ValueError): raise TypeError('could not convert %s to %s' % (center, self._base_space)) if self._base_type == 'padic field': - if not is_pAdicField(center.scheme().base_ring()): + if not isinstance(center.scheme().base_ring(), sage.rings.abc.pAdicField): if not isinstance(center.scheme().base_ring(), pAdicBaseGeneric): try: center = (self._base_space)(center) @@ -245,7 +245,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= center = (self._base_space)(center) except (TypeError, ValueError): raise TypeError("could not convert %s to %s" % (center, self._base_space)) - elif not is_pAdicField(center.parent()): + elif not isinstance(center.parent(), sage.rings.abc.pAdicField): # center is padic, not but an element of a padic field. we convert to padic field center = (center.parent().fraction_field())(center) if (center.parent()).prime() != self._p: @@ -291,7 +291,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= except (ValueError, TypeError): raise TypeError("could not convert %s to %s" % (center, self._base_space)) if self._base_type == 'padic field': - if not is_pAdicField(center.scheme().base_ring()): + if not isinstance(center.scheme().base_ring(), sage.rings.abc.pAdicField): if not isinstance(center.scheme().base_ring(), pAdicBaseGeneric): try: center = (self._base_space)(center) @@ -327,7 +327,7 @@ def __init__(self, parent, center, radius=None, power=None, prec=20, space_type= center = (self._base_space)(center) except (TypeError, ValueError): raise TypeError("could not convert %s to %s" % (center, self._base_space)) - elif not is_pAdicField(center.parent()): + elif not isinstance(center.parent(), sage.rings.abc.pAdicField): # center is padic, not but an element of a padic field. we convert to padic field center = (center.parent().fraction_field())(center) if (center.parent()).prime() != self._p: diff --git a/src/sage/schemes/berkovich/berkovich_space.py b/src/sage/schemes/berkovich/berkovich_space.py index 51a0df0a14a..82ba2c17fd6 100644 --- a/src/sage/schemes/berkovich/berkovich_space.py +++ b/src/sage/schemes/berkovich/berkovich_space.py @@ -38,11 +38,11 @@ from sage.schemes.projective.projective_space import is_ProjectiveSpace, ProjectiveSpace from sage.structure.unique_representation import UniqueRepresentation from sage.categories.number_fields import NumberFields +import sage.rings.abc from sage.rings.integer_ring import ZZ from sage.rings.padics.factory import Qp from sage.rings.rational_field import QQ from sage.rings.number_field.number_field_ideal import NumberFieldFractionalIdeal -from sage.rings.padics.generic_nodes import is_pAdicField from sage.categories.topological_spaces import TopologicalSpaces def is_Berkovich(space): @@ -440,7 +440,7 @@ def __init__(self, base, ideal=None): if not ideal.is_prime(): raise ValueError('passed non prime ideal') self._base_type = 'number field' - elif is_pAdicField(base): # change base to Qpbar + elif isinstance(base, sage.rings.abc.pAdicField): # change base to Qpbar prime = base.prime() ideal = None self._base_type = 'padic field' @@ -614,14 +614,14 @@ def __init__(self, base, ideal=None): base = ProjectiveSpace(Qp(base), 1) else: raise ValueError("non-prime passed into Berkovich space") - if base in NumberFields() or is_pAdicField(base): + if base in NumberFields() or isinstance(base, sage.rings.abc.pAdicField): base = ProjectiveSpace(base, 1) if not is_ProjectiveSpace(base): try: base = ProjectiveSpace(base) except: raise ValueError("base of projective Berkovich space must be projective space") - if not (is_pAdicField(base.base_ring())): + if not isinstance(base.base_ring(), sage.rings.abc.pAdicField): if base.base_ring() not in NumberFields(): raise ValueError("base of projective Berkovich space must be " + \ "projective space over Qp or a number field") From 96a778b73920dceb543508b6cf6356685c21aff8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:15:02 -0700 Subject: [PATCH 169/378] src/sage/schemes/elliptic_curves/constructor.py: Use sage.rings.abc.pAdicField --- src/sage/schemes/elliptic_curves/constructor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/constructor.py b/src/sage/schemes/elliptic_curves/constructor.py index 90bc4519082..b84dc217c71 100644 --- a/src/sage/schemes/elliptic_curves/constructor.py +++ b/src/sage/schemes/elliptic_curves/constructor.py @@ -461,7 +461,7 @@ def create_object(self, version, key, **kwds): elif is_NumberField(R): from .ell_number_field import EllipticCurve_number_field return EllipticCurve_number_field(R, x) - elif rings.is_pAdicField(R): + elif isinstance(R, sage.rings.abc.pAdicField): from .ell_padic_field import EllipticCurve_padic_field return EllipticCurve_padic_field(R, x) elif is_FiniteField(R) or (isinstance(R, sage.rings.abc.IntegerModRing) and R.characteristic().is_prime()): From b672836c7ca02c6e2726604a3a2b0289bda572a3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:18:56 -0700 Subject: [PATCH 170/378] src/sage/schemes/hyperelliptic_curves: Use sage.rings.abc.pAdicField --- src/sage/schemes/hyperelliptic_curves/constructor.py | 3 ++- .../hyperelliptic_curves/hyperelliptic_rational_field.py | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index d634c9a1001..9da5baff038 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -24,7 +24,6 @@ from .hyperelliptic_padic_field import HyperellipticCurve_padic_field from .hyperelliptic_g2 import HyperellipticCurve_g2 -from sage.rings.padics.all import is_pAdicField from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.polynomial.polynomial_element import is_Polynomial @@ -251,6 +250,8 @@ def HyperellipticCurve(f, h=0, names=None, PP=None, check_squarefree=True): genus_classes = { 2 : HyperellipticCurve_g2} + is_pAdicField = lambda x: isinstance(x, sage.rings.abc.pAdicField) + fields = [ ("FiniteField", is_FiniteField, HyperellipticCurve_finite_field), ("RationalField", is_RationalField, HyperellipticCurve_rational_field), diff --git a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py index 2267edfdb1f..1e2991ee51b 100644 --- a/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py +++ b/src/sage/schemes/hyperelliptic_curves/hyperelliptic_rational_field.py @@ -7,7 +7,9 @@ # http://www.gnu.org/licenses/ #***************************************************************************** -from sage.rings.padics.all import is_pAdicField, is_pAdicRing, pAdicField +import sage.rings.abc + +from sage.rings.padics.all import pAdicField from sage.schemes.curves.projective_curve import ProjectivePlaneCurve_field @@ -28,7 +30,7 @@ def my_chage_ring(self, R): return HyperellipticCurve(f.change_ring(R), h, "%s,%s"%(x,y)) import sage.schemes.hyperelliptic_curves.monsky_washnitzer as monsky_washnitzer - if is_pAdicField(p) or is_pAdicRing(p): + if isinstance(p, (sage.rings.abc.pAdicField, sage.rings.abc.pAdicRing)): K = p else: K = pAdicField(p, prec) From e1412c7e8dd94c64eb33daf5b9901d89c308e786 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:20:34 -0700 Subject: [PATCH 171/378] src/sage/schemes/projective/projective_morphism.py: Use sage.rings.abc.pAdicField --- src/sage/schemes/projective/projective_morphism.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 1aa7ea7f841..60235a0ebc6 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -74,6 +74,7 @@ from sage.calculus.functions import jacobian +import sage.rings.abc from sage.rings.all import Integer from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic from sage.rings.complex_mpfr import ComplexField_class @@ -987,14 +988,13 @@ def normalize_coordinates(self, **kwds): self.scale_by(R(1) / GCD) # scales by 1/gcd of the coefficients. - from sage.rings.padics.generic_nodes import is_pAdicField if R in _NumberFields: O = R.maximal_order() elif is_FiniteField(R): O = R elif isinstance(R, QuotientRing_generic): O = R.ring() - elif is_pAdicField(R): + elif isinstance(R, sage.rings.abc.pAdicField): O = R.integer_ring() else: O = R From fc7025ae3f49ce90b3cc690816a94a10a4970f21 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:28:02 -0700 Subject: [PATCH 172/378] src/sage/rings/padics/generic_nodes.py: Update doctests with deprecation warning output --- src/sage/rings/padics/generic_nodes.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 0eacec21b3c..6262e0b4065 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -1188,6 +1188,9 @@ def is_pAdicRing(R): EXAMPLES:: sage: is_pAdicRing(Zp(5)) + doctest:warning... + DeprecationWarning: is_pAdicRing is deprecated; use isinstance(..., sage.rings.abc.pAdicRing) instead + See https://trac.sagemath.org/32750 for details. True sage: is_pAdicRing(RR) False @@ -1331,6 +1334,9 @@ def is_pAdicField(R): EXAMPLES:: sage: is_pAdicField(Zp(17)) + doctest:warning... + DeprecationWarning: is_pAdicField is deprecated; use isinstance(..., sage.rings.abc.pAdicField) instead + See https://trac.sagemath.org/32750 for details. False sage: is_pAdicField(Qp(17)) True From 070d05bfc2b9a3890124312676ff25f952e17493 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 23 Oct 2021 19:32:51 -0700 Subject: [PATCH 173/378] src/sage/schemes/projective/projective_morphism.py: Avoid merge conflict --- src/sage/schemes/projective/projective_morphism.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/projective/projective_morphism.py b/src/sage/schemes/projective/projective_morphism.py index 60235a0ebc6..8a1dba33e97 100644 --- a/src/sage/schemes/projective/projective_morphism.py +++ b/src/sage/schemes/projective/projective_morphism.py @@ -74,7 +74,6 @@ from sage.calculus.functions import jacobian -import sage.rings.abc from sage.rings.all import Integer from sage.rings.algebraic_closure_finite_field import AlgebraicClosureFiniteField_generic from sage.rings.complex_mpfr import ComplexField_class @@ -91,6 +90,7 @@ from sage.rings.rational_field import QQ from sage.rings.real_mpfr import RealField_class from sage.rings.real_mpfi import RealIntervalField_class +import sage.rings.abc from sage.schemes.generic.morphism import SchemeMorphism_polynomial From 59271be4d8c81ae9550fb65c399214f4ea439ae8 Mon Sep 17 00:00:00 2001 From: EnderWannabe Date: Sun, 24 Oct 2021 12:07:11 -0700 Subject: [PATCH 174/378] 32750: added missing imports --- src/sage/modular/overconvergent/genus0.py | 1 + src/sage/schemes/hyperelliptic_curves/constructor.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/sage/modular/overconvergent/genus0.py b/src/sage/modular/overconvergent/genus0.py index 7d5f7988ce8..8c5f36fa933 100644 --- a/src/sage/modular/overconvergent/genus0.py +++ b/src/sage/modular/overconvergent/genus0.py @@ -186,6 +186,7 @@ from sage.plot.plot import plot from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ +import sage.rings.abc from sage.rings.all import (O, Infinity, pAdicField, PolynomialRing, PowerSeriesRing) import weakref diff --git a/src/sage/schemes/hyperelliptic_curves/constructor.py b/src/sage/schemes/hyperelliptic_curves/constructor.py index 9da5baff038..f5478623bdf 100644 --- a/src/sage/schemes/hyperelliptic_curves/constructor.py +++ b/src/sage/schemes/hyperelliptic_curves/constructor.py @@ -24,6 +24,7 @@ from .hyperelliptic_padic_field import HyperellipticCurve_padic_field from .hyperelliptic_g2 import HyperellipticCurve_g2 +import sage.rings.abc from sage.rings.rational_field import is_RationalField from sage.rings.finite_rings.finite_field_constructor import is_FiniteField from sage.rings.polynomial.polynomial_element import is_Polynomial From 516bdb33a90b002200e356b91c8a29fccca29435 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 24 Oct 2021 12:08:56 -0700 Subject: [PATCH 175/378] build/bin/sage-dist-helpers (sdh_pip_install): Handle new option --build-isolation --- build/bin/sage-dist-helpers | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 9980b4e22d2..91defc8a0f4 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -240,7 +240,28 @@ sdh_pip_install() { echo "Installing $PKG_NAME" mkdir -p dist rm -f dist/*.whl - python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --no-binary :all: --verbose --no-deps --no-index --isolated --no-build-isolation --ignore-requires-python "$@" || \ + # pip has --no-build-isolation but no flag that turns the default back on... + options="" + build_isolation_option="--no-build-isolation --no-binary :all:" + while [ $# -gt 0 ]; do + case "$1" in + --build-isolation) + # If a package requests build isolation, we allow it to provision + # its build environment using the stored wheels. + # We pass --find-links and remove the --no-binary option. + # The SPKG needs to declare "setuptools_wheel" as a dependency. + build_isolation_option="--find-links=$SAGE_SPKG_WHEELS" + ;; + -*) + ;; + *) + break + ;; + esac + shift + done + options="$options $build_isolation_option" + python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $options "$@" || \ sdh_die "Error building a wheel for $PKG_NAME" sdh_store_and_pip_install_wheel . From e89e2789ecf6c44e9dd31c028c708765545a8dd9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 24 Oct 2021 12:09:22 -0700 Subject: [PATCH 176/378] build/pkgs/packaging: Use --build-isolation --- build/pkgs/packaging/dependencies | 2 +- build/pkgs/packaging/spkg-install.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build/pkgs/packaging/dependencies b/build/pkgs/packaging/dependencies index 4818dfe9b48..2c5e2481b17 100644 --- a/build/pkgs/packaging/dependencies +++ b/build/pkgs/packaging/dependencies @@ -1,4 +1,4 @@ -$(PYTHON) | setuptools pip wheel pyparsing +$(PYTHON) | setuptools pip wheel pyparsing setuptools_wheel ---------- All lines of this file are ignored except the first. diff --git a/build/pkgs/packaging/spkg-install.in b/build/pkgs/packaging/spkg-install.in index deba1bb42bb..dd9cb64a082 100644 --- a/build/pkgs/packaging/spkg-install.in +++ b/build/pkgs/packaging/spkg-install.in @@ -1 +1 @@ -cd src && sdh_pip_install . +cd src && sdh_pip_install --build-isolation . From bc435b3e26a1c68fb2f04c09eb6f3d6e87115000 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 08:28:36 +0200 Subject: [PATCH 177/378] pick up environment variable for random seed --- src/bin/sage-runtests | 3 ++- src/doc/en/developer/doctesting.rst | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index d7a416185f8..25c884a553f 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -56,7 +56,8 @@ if __name__ == "__main__": 'if "build" is listed, will also run tests specific to Sage\'s build/packaging system; ' 'if set to "all", then all tests will be run') parser.add_argument("--randorder", type=int, metavar="SEED", help="randomize order of tests") - parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests") + parser.add_argument("--random-seed", dest="random_seed", type=int, metavar="SEED", help="random seed (integer) for fuzzing doctests", + default=os.environ.get("SAGE_DOCTEST_RANDOM_SEED")) parser.add_argument("--global-iterations", "--global_iterations", type=int, default=0, help="repeat the whole testing process this many times") parser.add_argument("--file-iterations", "--file_iterations", type=int, default=0, help="repeat each file this many times, stopping on the first failure") parser.add_argument("--environment", type=str, default="sage.repl.ipython_kernel.all_jupyter", help="name of a module that provides the global environment for tests") diff --git a/src/doc/en/developer/doctesting.rst b/src/doc/en/developer/doctesting.rst index e26d7329095..7b8aa79554a 100644 --- a/src/doc/en/developer/doctesting.rst +++ b/src/doc/en/developer/doctesting.rst @@ -855,6 +855,9 @@ This seed can be set explicitly to reproduce possible failures:: cpu time: 0.0 seconds cumulative wall time: 0.0 seconds +It can also be set explicitly using the environment variable +``SAGE_DOCTEST_RANDOM_SEED``. + .. _section-optional-doctest-flag: Run Optional Doctests From de0537d7747074268b155d607eda2223b74bcf66 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 25 Oct 2021 08:43:51 +0200 Subject: [PATCH 178/378] 32760 initial --- build/pkgs/database_knotinfo/checksums.ini | 6 +-- .../database_knotinfo/package-version.txt | 2 +- src/sage/databases/knotinfo_db.py | 11 ++-- src/sage/knots/knotinfo.py | 54 +++++++++++-------- src/sage/knots/link.py | 33 ++++++------ 5 files changed, 60 insertions(+), 46 deletions(-) diff --git a/build/pkgs/database_knotinfo/checksums.ini b/build/pkgs/database_knotinfo/checksums.ini index d3e1988a7e1..01afb61648f 100644 --- a/build/pkgs/database_knotinfo/checksums.ini +++ b/build/pkgs/database_knotinfo/checksums.ini @@ -1,5 +1,5 @@ tarball=database_knotinfo-VERSION.tar.gz -sha1=549e3162b2ba6942dede30366072d10e26643f54 -md5=c6487321cd2e0fd6b9f9ee7bdfa19993 -cksum=2255768788 +sha1=187e6b5ee2a935e3a50bc7648b181dfc7cb7bfa2 +md5=90822e09a1a84c8dbb84e20773c367f1 +cksum=1855405219 upstream_url=https://pypi.io/packages/source/d/database_knotinfo/database_knotinfo-VERSION.tar.gz diff --git a/build/pkgs/database_knotinfo/package-version.txt b/build/pkgs/database_knotinfo/package-version.txt index bb805851b41..bb762ff812e 100644 --- a/build/pkgs/database_knotinfo/package-version.txt +++ b/build/pkgs/database_knotinfo/package-version.txt @@ -1 +1 @@ -2021.9.1 +2021.10.1 diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index 8d403b849f1..cc0e2d034db 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -80,6 +80,7 @@ class KnotInfoColumns(Enum): 'Unoriented Rank', 'PD Notation (vector)', 'PD Notation (KnotTheory)', + 'Braid Notation', 'Multivariable Alexander Polynomial', 'HOMFLYPT Polynomial', 'Unoriented', @@ -438,7 +439,7 @@ def version(self): sage: from sage.databases.knotinfo_db import KnotInfoDataBase sage: ki_db = KnotInfoDataBase() - sage: ki_db.version() >= '2021.7.21' # optional database_knotinfo + sage: ki_db.version() >= '2021.10.1' # optional database_knotinfo True """ self._feature.require() @@ -886,14 +887,14 @@ def _test_database(self, **options): '{1,1,1,2,-1,2,3,-2,3}', '{2, {-1, -1}}', '{2, {1, 1}}', - '{4, {1, -2, 3, -2, -1, -2, -3, -2}}', + '{3, {-2, -2, -1, 2, -1}}', '{2, {1, 1, 1, 1}}', '{3, {-1, 2, -1, 2, -1}}', '{3, {-1, 2, -1, 2, -1}}', '{4, {1, -2, 3, -2, 1, -2, -3, -2}}', - '{4, {1, 2, 3, 2, 2, -1, 2, 2, -3, 2}}', - '{4, {1, -2, -2, -2, 3, -2, -1, -2, -3, -2}}', - '{4, {1, 2, -3, 2, -1, 2, 3, 2, 2, 2}}', + '{3, {2, 2, 2, 1, 1, -2, 1}}', + '{3, {-1, 2, -1, -2, -2, -1, -1}}', + '{3, {1, -2, 1, 2, 2, 1, 1}}', '{2, {-1, -1, -1, -1, -1, -1}}' ], dc.braid_index: ['1', '2', '3', '2', '3', '4', '3', '3', '2', '4'], diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index 54b7812a3b0..d26da2cd8bb 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -14,6 +14,11 @@ - ``sage -i database_knotinfo`` (does not install if the current version is present) - ``sage -f database_knotinfo`` (installs even if the current version is present) +This will install a `Python wrapper `__ +for the original databases in Sage. This wrapper perfoms an automatic progress +of version numbers. For more details and further install instructions please see +the correspondig web-page. + To perform all the doctests concerning the usage of the database on the installation add the option ``-c``. In this case (for instance ``sage -f -c database_knotinfo``) the installation breaks on failing tests. @@ -79,7 +84,7 @@ Obtaining an instance of :class:`~sage.groups.braid.Braid`:: sage: L.braid() - s0*s1^-1*s2*s1^-1*s0^-1*s1^-1*s2^-1*s1^-1 + s1^-2*s0^-1*s1*s0^-1 sage: type(_) @@ -255,9 +260,9 @@ def eval_knotinfo(string, locals={}, to_tuple=True): sage: from sage.knots.knotinfo import KnotInfo, eval_knotinfo sage: L = KnotInfo.L4a1_0 sage: L.braid_notation(original=True) - '{4, {1, -2, 3, -2, -1, -2, -3, -2}}' + '{3, {-2, -2, -1, 2, -1}}' sage: eval_knotinfo(_) - (4, (1, -2, 3, -2, -1, -2, -3, -2)) + (3, (-2, -2, -1, 2, -1)) """ if to_tuple: new_string = string.replace('{', '(') @@ -348,7 +353,7 @@ def items(self): sage: L = KnotInfo.L4a1_0 sage: it = L.items sage: [i.name for i in it if i.name.startswith('braid')] - ['braid_index', 'braid_length', 'braid_notation'] + ['braid_index', 'braid_length', 'braid_notation', 'braid_notation_old'] sage: L.items.dt_notation.column_name() 'DT Notation' @@ -376,7 +381,7 @@ def __getitem__(self, item): sage: L[L.items.arc_notation] '{{6, 4}, {3, 5}, {4, 2}, {1, 3}, {2, 6}, {5, 1}}' sage: L[L.items.braid_notation] - '{4, {1, -2, 3, -2, -1, -2, -3, -2}}' + '{3, {-2, -2, -1, 2, -1}}' sage: L[0] Traceback (most recent call last): ... @@ -425,7 +430,7 @@ def _braid_group(self): sage: from sage.knots.knotinfo import KnotInfo sage: L = KnotInfo.L4a1_0 sage: L._braid_group() - Braid group on 4 strands + Braid group on 3 strands """ n = self.braid_index() if n == 1: @@ -589,14 +594,21 @@ def braid_notation(self, original=False): Python tuple representing the braid whose closure is ``self`` in Tietze form. + ..NOTE:: + + There has been a major change to braid representatives for + proper links since version 2021.10.1. The former braid + reresentatives can be obtained by the column + ``braid_notation_old``. + EXAMPLES:: sage: from sage.knots.knotinfo import KnotInfo sage: L = KnotInfo.L4a1_0 sage: L.braid_notation() - (1, -2, 3, -2, -1, -2, -3, -2) + (-2, -2, -1, 2, -1) sage: L.braid_notation(original=True) - '{4, {1, -2, 3, -2, -1, -2, -3, -2}}' + '{3, {-2, -2, -1, 2, -1}}' """ braid_notation = self[self.items.braid_notation] if original: @@ -640,7 +652,7 @@ def braid_index(self): sage: from sage.knots.knotinfo import KnotInfo sage: L = KnotInfo.L4a1_0 sage: L.braid_index() - 4 + 3 """ if self.is_knot(): return int(self[self.items.braid_index]) @@ -720,7 +732,7 @@ def crossing_number(self): sage: KnotInfo.K3_1.crossing_number() 3 sage: Link(KnotInfo.L4a1_0.braid()) - Link with 2 components represented by 8 crossings + Link with 2 components represented by 5 crossings """ return int(self[self.items.crossing_number]) @@ -946,9 +958,9 @@ def is_amphicheiral(self, positive=False): False sage: KnotInfo.L10n59_1.is_amphicheiral() # optional - database_knotinfo True - sage: KnotInfo.L10n59_0.inject() # optional - database_knotinfo - Defining L10n59_0 - sage: L10n59_0.is_amphicheiral() is None # optional - database_knotinfo + sage: KnotInfo.L10n36_0.inject() # optional - database_knotinfo + Defining L10n36_0 + sage: L10n36_0.is_amphicheiral() is None # optional - database_knotinfo True """ if self.is_knot(): @@ -1705,7 +1717,7 @@ def link(self, use_item=db.columns().pd_notation, snappy=False): observe:: sage: L.link(use_item=L.items.braid_notation) - Link with 2 components represented by 8 crossings + Link with 2 components represented by 5 crossings sage: K6_1 = KnotInfo.K6_1 sage: K6_1.link().braid() == K6_1.braid() @@ -1776,14 +1788,14 @@ def is_unique(self): True sage: KnotInfo.L5a1_0.is_unique() False - sage: L = KnotInfo.L7a7_0_0 # optional - database_knotinfo + sage: L = KnotInfo.L9a43_0_1 # optional - database_knotinfo sage: L.series(oriented=True).inject() # optional - database_knotinfo - Defining L7a7 - sage: [(L,L.is_unique()) for L in L7a7] # optional - database_knotinfo - [(, False), - (, None), - (, False), - (, True)] + Defining L9a43 + sage: [(L,L.is_unique()) for L in L9a43] # optional - database_knotinfo + [(, True), + (, False), + (, None), + (, False)] """ # an isotopic pair must have the same unoriented name. So, we can focus # on such series diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index ff7a64eee4f..3ebffa134da 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -3744,40 +3744,41 @@ def get_knotinfo(self, mirror_version=True, unique=True): sage: k11 = KnotInfo.K11n_82.link() # optional - database_knotinfo sage: k11m = k11.mirror_image() # optional - database_knotinfo - sage: k11m.braid() # optional - database_knotinfo - s0*s1^-1*s0*s2^-1*s1*(s1*s2^-1)^2*s2^-2 - sage: k11m.get_knotinfo() # optional - database_knotinfo + sage: k11mr = k11m.reverse() # optional - database_knotinfo + sage: k11mr.get_knotinfo() # optional - database_knotinfo Traceback (most recent call last): ... NotImplementedError: mirror type of this link cannot be uniquely determined use keyword argument `unique` to obtain more details - sage: k11m.get_knotinfo(unique=False) # optional - database_knotinfo + sage: k11mr.get_knotinfo(unique=False) # optional - database_knotinfo [(, '?')] - sage: t = (-1, 2, -1, 2, -1, 3, -2, 3, -2) - sage: l9 = Link(BraidGroup(4)(t)) - sage: l9.get_knotinfo() # optional - database_knotinfo + sage: t = (1, -2, 1, 1, -2, 1, -2, -2) + sage: l8 = Link(BraidGroup(3)(t)) + sage: l8.get_knotinfo() # optional - database_knotinfo Traceback (most recent call last): ... NotImplementedError: this link cannot be uniquely determined use keyword argument `unique` to obtain more details - sage: l9.get_knotinfo(unique=False) # optional - database_knotinfo - [(, False), - (, False)] + sage: l8.get_knotinfo(unique=False) # optional - database_knotinfo + [(, None), + (, None)] - sage: t = (1, 2, 3, -4, 3, -2, -1, 3, -2, 3, -2, 3, -4, 3, -2) - sage: l15 = Link(BraidGroup(5)(t)) - sage: l15.get_knotinfo() # optional - database_knotinfo + sage: t = (2, -3, -3, -2, 3, 3, -2, 3, 1, -2, -2, 1) + sage: l12 = Link(BraidGroup(5)(t)) + sage: l12.get_knotinfo() # optional - database_knotinfo Traceback (most recent call last): ... NotImplementedError: this link having more than 11 crossings cannot be uniquely determined use keyword argument `unique` to obtain more details - sage:l15.get_knotinfo(unique=False) # optional - database_knotinfo - [(, False), - (, False)] + sage: l12.get_knotinfo(unique=False) # optional - database_knotinfo + [(, '?'), + (, None), + (, None), + (, None)] Furthermore, if the result is a complete series of oriented links having the same unoriented name (according to the note above) the option can be From bc1710c61fa8b9abb3f53bec78c121e16ac68ae8 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 12:29:09 +0200 Subject: [PATCH 179/378] fix incorrect import --- src/sage/libs/pari/convert_sage_complex_double.pyx | 2 +- src/sage/rings/complex_double.pyx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/pari/convert_sage_complex_double.pyx b/src/sage/libs/pari/convert_sage_complex_double.pyx index 308aa456ae4..d8aa2a6f037 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pyx +++ b/src/sage/libs/pari/convert_sage_complex_double.pyx @@ -6,7 +6,7 @@ from cypari2.paridecl cimport * from cypari2.convert cimport new_gen_from_double, new_t_COMPLEX_from_double -cdef inline ComplexDoubleElement pari_to_cdf(Gen g): +cpdef ComplexDoubleElement pari_to_cdf(Gen g): """ Create a CDF element from a PARI ``gen``. diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index 50bb012059d..ecc326b4396 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -91,7 +91,7 @@ from sage.structure.coerce cimport is_numpy_type try: from cypari2.gen import Gen as pari_gen - from cypari2.convert_sage_complex_double import pari_to_cdf + from sage.libs.pari.convert_sage_complex_double import pari_to_cdf except ImportError: pari_gen = () From 4902aa183cc94fe47482231af13d2e32cf7358fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 25 Oct 2021 13:52:29 +0200 Subject: [PATCH 180/378] fix E713 and E714 in algebras, categories, monoids, etc --- src/sage/algebras/free_algebra.py | 14 ++++---- src/sage/algebras/group_algebra.py | 7 ++-- src/sage/algebras/hall_algebra.py | 10 +++--- .../lie_conformal_algebra.py | 6 ++-- src/sage/algebras/schur_algebra.py | 8 ++--- src/sage/categories/algebra_modules.py | 4 +-- ...eflection_or_generalized_coxeter_groups.py | 8 ++--- src/sage/categories/finite_groups.py | 2 +- .../categories/finite_permutation_groups.py | 8 ++--- src/sage/categories/posets.py | 2 +- src/sage/categories/ring_ideals.py | 11 +++--- src/sage/categories/semigroups.py | 4 +-- src/sage/crypto/classical.py | 6 ++-- src/sage/functions/orthogonal_polys.py | 2 +- src/sage/functions/other.py | 2 +- src/sage/misc/decorators.py | 8 ++--- src/sage/misc/sage_input.py | 4 +-- src/sage/monoids/string_monoid_element.py | 4 +-- .../quadratic_forms/genera/normal_form.py | 2 +- .../quadratic_forms/genera/spinor_genus.py | 4 +-- ...c_form__local_representation_conditions.py | 36 +++++++++---------- src/sage/sandpiles/sandpile.py | 10 +++--- src/sage/sets/integer_range.py | 6 ++-- 23 files changed, 84 insertions(+), 84 deletions(-) diff --git a/src/sage/algebras/free_algebra.py b/src/sage/algebras/free_algebra.py index b3dc47ba3ff..1165d82c02c 100644 --- a/src/sage/algebras/free_algebra.py +++ b/src/sage/algebras/free_algebra.py @@ -290,16 +290,16 @@ def create_key(self, base_ring, arg1=None, arg2=None, newname += '_' varnames.append(newname) R = PolynomialRing( - PolRing.base(), varnames, - sparse=sparse, order=T) + PolRing.base(), varnames, + sparse=sparse, order=T) return tuple(degrees), R # normalise the generator names from sage.all import Integer if isinstance(arg1, (Integer, int)): arg1, arg2 = arg2, arg1 - if not names is None: + if names is not None: arg1 = names - elif not name is None: + elif name is not None: arg1 = name if arg2 is None: arg2 = len(arg1) @@ -866,13 +866,13 @@ def g_algebra(self, relations, names=None, order='degrevlex', check=True): assert v1 > v2 c_coef = None d_poly = None - for (m,c) in commuted: + for m, c in commuted: if list(m) == [(v2,1),(v1,1)]: c_coef = c - #buggy coercion workaround + # buggy coercion workaround d_poly = commuted - self(c) * self(m) break - assert not c_coef is None,list(m) + assert c_coef is not None, list(m) v2_ind = self.gens().index(v2) v1_ind = self.gens().index(v1) cmat[v2_ind,v1_ind] = c_coef diff --git a/src/sage/algebras/group_algebra.py b/src/sage/algebras/group_algebra.py index e40871376d4..e664e0f9559 100644 --- a/src/sage/algebras/group_algebra.py +++ b/src/sage/algebras/group_algebra.py @@ -108,11 +108,12 @@ def GroupAlgebra(G, R=IntegerRing()): over Rational Field """ if not (G in Magmas() or G in AdditiveMagmas()): - raise ValueError("%s is not a magma or additive magma"%G) - if not R in Rings(): - raise ValueError("%s is not a ring"%R) + raise ValueError("%s is not a magma or additive magma" % G) + if R not in Rings(): + raise ValueError("%s is not a ring" % R) return G.algebra(R) + class GroupAlgebra_class(CombinatorialFreeModule): def _coerce_map_from_(self, S): r""" diff --git a/src/sage/algebras/hall_algebra.py b/src/sage/algebras/hall_algebra.py index a8ea8d18aff..089050d1627 100644 --- a/src/sage/algebras/hall_algebra.py +++ b/src/sage/algebras/hall_algebra.py @@ -5,12 +5,12 @@ - Travis Scrimshaw (2013-10-17): Initial version """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2013 Travis Scrimshaw # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** from sage.misc.misc_c import prod from sage.misc.cachefunc import cached_method @@ -230,7 +230,7 @@ def __init__(self, base_ring, q, prefix='H'): self._q = q try: q_inverse = q**-1 - if not q_inverse in base_ring: + if q_inverse not in base_ring: hopf_structure = False else: hopf_structure = True @@ -580,7 +580,7 @@ def __init__(self, base_ring, q, prefix='I'): self._q = q try: q_inverse = q**-1 - if not q_inverse in base_ring: + if q_inverse not in base_ring: hopf_structure = False else: hopf_structure = True diff --git a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py index 0ec6ca765c3..5c14016eab2 100644 --- a/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py +++ b/src/sage/algebras/lie_conformal_algebras/lie_conformal_algebra.py @@ -320,10 +320,10 @@ def __classcall_private__(cls, R=None, arg0=None, index_set=None, sage: type(V) """ - if not R in CommutativeRings(): - raise ValueError("arg0 must be a commutative ring got {}".format(R)) + if R not in CommutativeRings(): + raise ValueError(f"arg0 must be a commutative ring got {R}") - #This is the only exposed class so we clean keywords here + # This is the only exposed class so we clean keywords here known_keywords = ['category', 'prefix', 'bracket', 'latex_bracket', 'string_quotes', 'sorting_key', 'graded', 'super'] for key in kwds: diff --git a/src/sage/algebras/schur_algebra.py b/src/sage/algebras/schur_algebra.py index 08b921ea160..a700b6b8854 100644 --- a/src/sage/algebras/schur_algebra.py +++ b/src/sage/algebras/schur_algebra.py @@ -18,7 +18,7 @@ of irreducible modules """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010 Eric Webster # Copyright (C) 2011 Hugh Thomas # @@ -26,8 +26,8 @@ # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import itertools @@ -240,7 +240,7 @@ def __init__(self, R, n, r): raise ValueError("n (={}) must be a positive integer".format(n)) if r not in ZZ or r < 0: raise ValueError("r (={}) must be a non-negative integer".format(r)) - if not R in Rings.Commutative(): + if R not in Rings.Commutative(): raise ValueError("R (={}) must be a commutative ring".format(R)) self._n = n diff --git a/src/sage/categories/algebra_modules.py b/src/sage/categories/algebra_modules.py index b74bb51649d..d2e16148fd8 100644 --- a/src/sage/categories/algebra_modules.py +++ b/src/sage/categories/algebra_modules.py @@ -51,8 +51,8 @@ def __init__(self, A): sage: TestSuite(AlgebraModules(QQ['a'])).run() """ from sage.categories.commutative_algebras import CommutativeAlgebras - if not hasattr(A, "base_ring") or not A in CommutativeAlgebras(A.base_ring()): - raise TypeError("A (=%s) must be a commutative algebra"%A) + if not hasattr(A, "base_ring") or A not in CommutativeAlgebras(A.base_ring()): + raise TypeError("A (=%s) must be a commutative algebra" % A) Category_module.__init__(self, A) @classmethod diff --git a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py index 96bcbab9f05..bb58d78cbde 100644 --- a/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py +++ b/src/sage/categories/complex_reflection_or_generalized_coxeter_groups.py @@ -2,15 +2,15 @@ r""" Common category for Generalized Coxeter Groups or Complex Reflection Groups """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2016 Nicolas M. Thiéry # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import itertools from sage.misc.abstract_method import abstract_method @@ -201,7 +201,7 @@ def simple_reflection(self, i): 3 (1,4)(2,8)(3,5)(7,10)(9,11) asdf (2,5)(3,9)(4,6)(8,11)(10,12) """ - if not i in self.index_set(): + if i not in self.index_set(): raise ValueError("%s is not in the Dynkin node set %s" % (i, self.index_set())) return self.one().apply_simple_reflection(i) # don't care about left/right diff --git a/src/sage/categories/finite_groups.py b/src/sage/categories/finite_groups.py index d8802949324..e0adb301ce2 100644 --- a/src/sage/categories/finite_groups.py +++ b/src/sage/categories/finite_groups.py @@ -133,7 +133,7 @@ def cayley_graph_disabled(self, connecting_set=None): connecting_set = self.group_generators() else: for g in connecting_set: - if not g in self: + if g not in self: raise RuntimeError("Each element of the connecting set must be in the group!") connecting_set = [self(g) for g in connecting_set] from sage.graphs.all import DiGraph diff --git a/src/sage/categories/finite_permutation_groups.py b/src/sage/categories/finite_permutation_groups.py index 8c9827dc8b8..8595aef7795 100644 --- a/src/sage/categories/finite_permutation_groups.py +++ b/src/sage/categories/finite_permutation_groups.py @@ -223,10 +223,10 @@ def cycle_index(self, parent = None): """ from sage.categories.modules import Modules if parent is None: - from sage.rings.rational_field import QQ - from sage.combinat.sf.sf import SymmetricFunctions - parent = SymmetricFunctions(QQ).powersum() - elif not parent in Modules.WithBasis: + from sage.rings.rational_field import QQ + from sage.combinat.sf.sf import SymmetricFunctions + parent = SymmetricFunctions(QQ).powersum() + elif parent not in Modules.WithBasis: raise ValueError("`parent` should be a module with basis indexed by partitions") base_ring = parent.base_ring() return parent.sum_of_terms([C.an_element().cycle_type(), base_ring(C.cardinality())] diff --git a/src/sage/categories/posets.py b/src/sage/categories/posets.py index ada869b0403..6ab5657e929 100644 --- a/src/sage/categories/posets.py +++ b/src/sage/categories/posets.py @@ -407,7 +407,7 @@ def order_ideal_toggle(self, I, v): ....: for P in P4) True """ - if not v in I: + if v not in I: if all(u in I for u in self.lower_covers(v)): from sage.sets.set import Set return I.union(Set({v})) diff --git a/src/sage/categories/ring_ideals.py b/src/sage/categories/ring_ideals.py index 569958d364a..51573635ef0 100644 --- a/src/sage/categories/ring_ideals.py +++ b/src/sage/categories/ring_ideals.py @@ -1,20 +1,21 @@ r""" Ring ideals """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2005 David Kohel # William Stein # 2008-2009 Nicolas M. Thiery # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from .category_types import Category_ideal from .modules import Modules from sage.categories.rings import Rings _Rings = Rings() + class RingIdeals(Category_ideal): """ The category of two-sided ideals in a fixed ring. @@ -54,8 +55,8 @@ def __init__(self, R): sage: TestSuite(RingIdeals(ZZ)).run() """ - if not R in _Rings: - raise TypeError("R (=%s) must be a ring"%R) + if R not in _Rings: + raise TypeError("R (=%s) must be a ring" % R) Category_ideal.__init__(self, R) def super_categories(self): diff --git a/src/sage/categories/semigroups.py b/src/sage/categories/semigroups.py index 31da05bd00c..438c33b6e9b 100644 --- a/src/sage/categories/semigroups.py +++ b/src/sage/categories/semigroups.py @@ -304,7 +304,7 @@ def cayley_graph(self, side="right", simple=False, elements = None, generators = from sage.graphs.digraph import DiGraph from .monoids import Monoids from .groups import Groups - if not side in ["left", "right", "twosided"]: + if side not in ["left", "right", "twosided"]: raise ValueError("option 'side' must be 'left', 'right' or 'twosided'") if elements is None: assert self.is_finite(), "elements should be specified for infinite semigroups" @@ -314,7 +314,7 @@ def cayley_graph(self, side="right", simple=False, elements = None, generators = if simple or self in Groups(): result = DiGraph() else: - result = DiGraph(multiedges = True, loops = True) + result = DiGraph(multiedges=True, loops=True) result.add_vertices(elements) if connecting_set is not None: diff --git a/src/sage/crypto/classical.py b/src/sage/crypto/classical.py index 0070fe3f602..39cab2a6f90 100644 --- a/src/sage/crypto/classical.py +++ b/src/sage/crypto/classical.py @@ -1498,11 +1498,11 @@ def inverse_key(self, A): """ S = self.plaintext_space() M = self.key_space() - if not A in M: + if A not in M: raise TypeError("A (= %s) must be a matrix in the key space of %s." % (A, self)) m = self.block_length() MatZZ = MatrixSpace(ZZ, m) - AZ = MatZZ([ [ A[i, j].lift() for j in range(m) ] for i in range(m) ]) + AZ = MatZZ([[A[i, j].lift() for j in range(m)] for i in range(m)]) AZ_adj = AZ.adjugate() u, r, s = xgcd(A.det().lift(), S.ngens()) if u != 1: @@ -3396,7 +3396,7 @@ def inverse_key(self, K, check=True): True """ if check: - if not K in self.key_space(): + if K not in self.key_space(): raise TypeError("Argument K (= %s) is not in the key space." % K) return K**-1 diff --git a/src/sage/functions/orthogonal_polys.py b/src/sage/functions/orthogonal_polys.py index 4c6650f5311..949daced814 100644 --- a/src/sage/functions/orthogonal_polys.py +++ b/src/sage/functions/orthogonal_polys.py @@ -2013,7 +2013,7 @@ def _eval_(self, n, a, b, x): return legendre_P(n, x) if SR(n).is_numeric() and not (n > -1): raise ValueError("n must be greater than -1, got n = {0}".format(n)) - if not n in ZZ: + if n not in ZZ: return from .gamma import gamma s = sum(binomial(n,m) * gamma(a+b+n+m+1) / gamma(a+m+1) * ((x-1)/2)**m for m in range(n+1)) diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index bbccf43c386..dab6531d9bb 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -2328,7 +2328,7 @@ def _eval_(self, x, s): ValueError: not a set: 0 """ from sage.categories.sets_cat import Sets - if not s in Sets(): + if s not in Sets(): raise ValueError("not a set: {}".format(s)) def _latex_(self): diff --git a/src/sage/misc/decorators.py b/src/sage/misc/decorators.py index 6810915ba6c..a41c8413bb8 100644 --- a/src/sage/misc/decorators.py +++ b/src/sage/misc/decorators.py @@ -416,10 +416,10 @@ def argspec(): argspec = sage_getargspec(func) def listForNone(l): - return l if not l is None else [] + return l if l is not None else [] newArgs = [self.name + opt for opt in self.options.keys()] - args = (argspec.args if not argspec.args is None else []) + newArgs - defaults = (argspec.defaults if not argspec.defaults is None else ()) \ + args = (argspec.args if argspec.args is not None else []) + newArgs + defaults = (argspec.defaults if argspec.defaults is not None else ()) \ + tuple(self.options.values()) # Note: argspec.defaults is not always a tuple for some reason return ArgSpec(args, argspec.varargs, argspec.keywords, defaults) @@ -495,7 +495,7 @@ def wrapper(*args, **kwds): #special attribute _sage_argspec_ (see e.g. sage.misc.sageinspect) def argspec(): argspec = sage_getargspec(func) - args = ((argspec.args if not argspec.args is None else []) + + args = ((argspec.args if argspec.args is not None else []) + list(self.options)) defaults = (argspec.defaults or ()) + tuple(self.options.values()) # Note: argspec.defaults is not always a tuple for some reason diff --git a/src/sage/misc/sage_input.py b/src/sage/misc/sage_input.py index ead63fd68b1..0f0d0a788fb 100644 --- a/src/sage/misc/sage_input.py +++ b/src/sage/misc/sage_input.py @@ -1011,9 +1011,9 @@ def gen(self, parent, n=0): R. = ZZ[] y """ - if not parent in self._parent_gens: + if parent not in self._parent_gens: self(parent) - if not parent in self._parent_gens: + if parent not in self._parent_gens: raise ValueError("{} did not register generators for sage_input".format(parent)) gens = self._parent_gens[parent] diff --git a/src/sage/monoids/string_monoid_element.py b/src/sage/monoids/string_monoid_element.py index 6da34db7175..c3032e463f9 100644 --- a/src/sage/monoids/string_monoid_element.py +++ b/src/sage/monoids/string_monoid_element.py @@ -497,7 +497,7 @@ def frequency_distribution(self, length=1, prec=0): [(AB, 0.333333333333333), (BC, 0.333333333333333), (CD, 0.333333333333333)] """ from sage.probability.random_variable import DiscreteProbabilitySpace - if not length in (1, 2): + if length not in (1, 2): raise NotImplementedError("Not implemented") if prec == 0: RR = RealField() @@ -510,7 +510,7 @@ def frequency_distribution(self, length=1, prec=0): Alph = tuple(x * y for x in S.gens() for y in S.gens()) X = {} N = len(self) - length + 1 - eps = RR(Integer(1)/N) + eps = RR(Integer(1) / N) for i in range(N): c = self[i:i+length] if c in X: diff --git a/src/sage/quadratic_forms/genera/normal_form.py b/src/sage/quadratic_forms/genera/normal_form.py index db46afe0d76..2dd43567591 100644 --- a/src/sage/quadratic_forms/genera/normal_form.py +++ b/src/sage/quadratic_forms/genera/normal_form.py @@ -531,7 +531,7 @@ def _homogeneous_normal_form(G, w): e2 = D[-1,-1].unit_part() e = {e1, e2} E = [{1,3}, {1,7}, {5,7}, {3,5}] - if not e in E: + if e not in E: B[-4:,:] = _relations(D[-4:,-4:], 5) * B[-4:,:] D = B * G * B.T e1 = D[-2,-2].unit_part() diff --git a/src/sage/quadratic_forms/genera/spinor_genus.py b/src/sage/quadratic_forms/genera/spinor_genus.py index 6c6cf17f831..e4284fe4d31 100644 --- a/src/sage/quadratic_forms/genera/spinor_genus.py +++ b/src/sage/quadratic_forms/genera/spinor_genus.py @@ -162,12 +162,12 @@ def to_square_class(self, x, p): x = QQ(x) if x == 0: raise ValueError("x must be non zero") - if not p in self._primes: + if p not in self._primes: raise ValueError("not a coordinate prime") v, u = x.val_unit(p) v = v % 2 if v != 0: - raise ValueError("x(=%s) must be a p-adic unit" %x) + raise ValueError("x(=%s) must be a p-adic unit" % x) y = self.one() if p == 2: u = u % 8 diff --git a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py index e1de84c9037..4226acb972b 100644 --- a/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py +++ b/src/sage/quadratic_forms/quadratic_form__local_representation_conditions.py @@ -570,19 +570,19 @@ def is_locally_represented_at_place(self, m, p): True """ - ## Sanity Check - if not m in QQ: - raise TypeError("Oops! m = " + str(m) + " is not a rational number!") + # Sanity Check + if m not in QQ: + raise TypeError("Oops! m = " + str(m) + " is not a rational number!") - ## Representing zero + # Representing zero if m == 0: return True - ## 0-dim'l forms - if self.dim == 0: ## Here m != 0 + # 0-dim'l forms + if self.dim == 0: # Here m != 0 return False - ## 1-dim'l forms + # 1-dim'l forms if self.dim == 1: m1 = QQ(m) / self.coeff if p == infinity: @@ -642,33 +642,33 @@ def is_locally_represented(self, m): False """ - ## Representing zero + # Representing zero if m == 0: return True - ## 0-dim'l forms - if self.dim == 0: ## Here m != 0 + # 0-dim'l forms + if self.dim == 0: # Here m != 0 return False - ## 1-dim'l forms + # 1-dim'l forms if self.dim == 1: m1 = m / self.coeff return (m1 in ZZ) and is_square(m1) - ## Check the generic primes (when n = 2 or n >= 3) + # Check the generic primes (when n = 2 or n >= 3) m_primes = prime_divisors(numerator(m) * denominator(m)) for p in m_primes: - if not p in self.exceptional_primes: - val = valuation(m, p) - if (val < 0): - return False + if p not in self.exceptional_primes: + val = valuation(m, p) + if val < 0: + return False - ## Check the non-generic primes (when n = 2 or n >= 3) + # Check the non-generic primes (when n = 2 or n >= 3) for p in self.exceptional_primes: if not self.is_locally_represented_at_place(m, p): return False - ## If we got here, we're locally represented! + # If we got here, we're locally represented! return True diff --git a/src/sage/sandpiles/sandpile.py b/src/sage/sandpiles/sandpile.py index 04f7f789718..f29d7395d7f 100644 --- a/src/sage/sandpiles/sandpile.py +++ b/src/sage/sandpiles/sandpile.py @@ -1025,10 +1025,9 @@ def out_degree(self, v=None): sage: s.out_degree(2) 3 """ - if not v is None: + if v is not None: return self._out_degrees[v] - else: - return self._out_degrees + return self._out_degrees def _set_in_degrees(self): """ @@ -1065,10 +1064,9 @@ def in_degree(self, v=None): sage: s.in_degree(2) 3 """ - if not v is None: + if v is not None: return self._in_degrees[v] - else: - return self._in_degrees + return self._in_degrees def _set_burning_config(self): r""" diff --git a/src/sage/sets/integer_range.py b/src/sage/sets/integer_range.py index 62138a9ecfb..fe61d24d623 100644 --- a/src/sage/sets/integer_range.py +++ b/src/sage/sets/integer_range.py @@ -696,7 +696,7 @@ def __init__(self, begin, end, step=Integer(1), middle_point=Integer(1)): self._end = end self._step = step self._middle_point = middle_point - if not middle_point in self: + if middle_point not in self: raise ValueError("middle_point is not in the interval") if (begin != Infinity and begin != -Infinity) and \ @@ -764,8 +764,8 @@ def next(self, elt): ... LookupError: 1 not in Integer progression containing 0 with increment 10 and bounded with -Infinity and +Infinity """ - if not elt in self: - raise LookupError('%r not in %r' % (elt,self)) + if elt not in self: + raise LookupError('%r not in %r' % (elt, self)) n = self._middle_point if (elt <= n and self._step > 0) or (elt >= n and self._step < 0): right = 2*n-elt+self._step From 71b62be886046fe6c1fe0eb6b8ba543d90ec0293 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 15:02:31 +0200 Subject: [PATCH 181/378] new_gen_from_double not available as python function --- src/sage/libs/pari/convert_sage_real_double.pxd | 4 ++++ src/sage/libs/pari/convert_sage_real_double.pyx | 5 +++++ src/sage/rings/real_double.pyx | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 src/sage/libs/pari/convert_sage_real_double.pxd create mode 100644 src/sage/libs/pari/convert_sage_real_double.pyx diff --git a/src/sage/libs/pari/convert_sage_real_double.pxd b/src/sage/libs/pari/convert_sage_real_double.pxd new file mode 100644 index 00000000000..12fa7418e69 --- /dev/null +++ b/src/sage/libs/pari/convert_sage_real_double.pxd @@ -0,0 +1,4 @@ +from cypari2.gen cimport Gen +from sage.rings.real_double cimport RealDoubleElement + +cpdef Gen new_gen_from_real_double_element(RealDoubleElement self) diff --git a/src/sage/libs/pari/convert_sage_real_double.pyx b/src/sage/libs/pari/convert_sage_real_double.pyx new file mode 100644 index 00000000000..083a688de3f --- /dev/null +++ b/src/sage/libs/pari/convert_sage_real_double.pyx @@ -0,0 +1,5 @@ +from cypari2.convert cimport new_gen_from_double + +cpdef Gen new_gen_from_real_double_element(RealDoubleElement self): + + return new_gen_from_double(self._value) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 37af401d8e4..2125d431c98 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -1677,8 +1677,8 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(1.5).__pari__() 1.50000000000000 """ - from cypari2.convert import new_gen_from_double - return new_gen_from_double(self._value) + from sage.libs.pari.convert_sage_real_double import new_gen_from_real_double_element + return new_gen_from_real_double_element(self) ########################################### From 64984beb812c93dfc7572eb32b0f4f7c822f9f82 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 15:11:19 +0200 Subject: [PATCH 182/378] coverage --- src/sage/libs/pari/__init__.py | 6 ++++++ src/sage/libs/pari/convert_sage_complex_double.pyx | 14 +++++++++++++- src/sage/libs/pari/convert_sage_real_double.pyx | 8 ++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/pari/__init__.py b/src/sage/libs/pari/__init__.py index 507b98c5098..7b539bf746f 100644 --- a/src/sage/libs/pari/__init__.py +++ b/src/sage/libs/pari/__init__.py @@ -173,6 +173,12 @@ """ def _get_pari_instance(): + """ + TESTS:: + + sage: pari # indirect doctest + Interface to the PARI C library + """ # There are two constraints for the virtual stack size: # 1) on 32-bit systems, even virtual memory can be a scarce # resource since it is limited by 4GB (of which the kernel diff --git a/src/sage/libs/pari/convert_sage_complex_double.pyx b/src/sage/libs/pari/convert_sage_complex_double.pyx index d8aa2a6f037..5a04aff7f6e 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pyx +++ b/src/sage/libs/pari/convert_sage_complex_double.pyx @@ -12,7 +12,7 @@ cpdef ComplexDoubleElement pari_to_cdf(Gen g): EXAMPLES:: - sage: CDF(pari("Pi")) + sage: CDF(pari("Pi")) # indirect doctest 3.141592653589793 sage: CDF(pari("1 + I/2")) 1.0 + 0.5*I @@ -41,7 +41,19 @@ cpdef ComplexDoubleElement pari_to_cdf(Gen g): cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self): + """ + Return PARI version of ``self``, as ``t_COMPLEX`` or ``t_REAL``. + + EXAMPLES:: + sage: from sage.libs.pari.convert_sage_complex_double import new_gen_from_complex_double_element + sage: new_gen_from_complex_double_element(CDF(1,0)) + 1.00000000000000 + sage: new_gen_from_complex_double_element(CDF(0,1)) + 1.00000000000000*I + sage: new_gen_from_complex_double_element(CDF(1,1)) + 1.00000000000000 + 1.00000000000000*I + """ if not self._complex.imag: return new_gen_from_double(self._complex.real) else: diff --git a/src/sage/libs/pari/convert_sage_real_double.pyx b/src/sage/libs/pari/convert_sage_real_double.pyx index 083a688de3f..6d7ffe7038e 100644 --- a/src/sage/libs/pari/convert_sage_real_double.pyx +++ b/src/sage/libs/pari/convert_sage_real_double.pyx @@ -1,5 +1,13 @@ from cypari2.convert cimport new_gen_from_double cpdef Gen new_gen_from_real_double_element(RealDoubleElement self): + """ + Return a PARI representation of ``self``. + EXAMPLES:: + + sage: from sage.libs.pari.convert_sage_real_double import new_gen_from_real_double_element + sage: new_gen_from_real_double_element(RDF(-2.5)) + -2.50000000000000 + """ return new_gen_from_double(self._value) From 4ed58cf7d77ac03c186b45d1455b5e02f2e1b585 Mon Sep 17 00:00:00 2001 From: DavidAyotte Date: Mon, 25 Oct 2021 09:20:29 -0400 Subject: [PATCH 183/378] typo and docstring fixes --- src/sage/modular/modform/element.py | 22 ++++++++++++--------- src/sage/modular/quasimodform/element.py | 25 +++++++++++++----------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/sage/modular/modform/element.py b/src/sage/modular/modform/element.py index bc2aab4450c..505e7b324bf 100644 --- a/src/sage/modular/modform/element.py +++ b/src/sage/modular/modform/element.py @@ -3590,7 +3590,8 @@ def weight(self): def weights_list(self): r""" - Return the list of the weights of all the graded components of the given graded modular form. + Return the list of the weights of all the homogeneous components of the + given graded modular form. EXAMPLES:: @@ -3628,7 +3629,8 @@ def is_homogeneous(self): def _homogeneous_to_polynomial(self, names, gens): r""" - If ``self`` is a homogeneous form, return a polynomial `P(x_0,..., x_n)` corresponding to ``self``. + Return a polynomial `P(x_0,..., x_n)` corresponding to the given homogeneous graded form. + Each variable `x_i` of the returned polynomial correspond to a generator `g_i` of the list ``gens`` (following the order of the list) @@ -3747,10 +3749,11 @@ def to_polynomial(self, names='x', gens=None): def serre_derivative(self): r""" - Return the Serre derivative of the given graded modular form. If ``self`` - is a modular form of weight `k`, then the returned modular form will be - of weight `k + 2`. If the form is not homogeneous, then this method sums - the Serre derivative of each homogeneous components. + Return the Serre derivative of the given graded modular form. + + If ``self`` is a modular form of weight `k`, then the returned modular + form will be of weight `k + 2`. If the form is not homogeneous, then + this method sums the Serre derivative of each homogeneous component. EXAMPLES:: @@ -3778,10 +3781,11 @@ def serre_derivative(self): def derivative(self, name='E2'): r""" - Return the derivative `q \frac{d}{dq}` of the given graded form. Note - that this method returns an element of a new parent, that is a + Return the derivative `q \frac{d}{dq}` of the given graded form. + + Note that this method returns an element of a new parent, that is a quasimodular form. If the form is not homogeneous, then this method sums - the derivative of each homogeneous components. + the derivative of each homogeneous component. INPUT: diff --git a/src/sage/modular/quasimodform/element.py b/src/sage/modular/quasimodform/element.py index b6e248bc9b0..dfb68d53f58 100644 --- a/src/sage/modular/quasimodform/element.py +++ b/src/sage/modular/quasimodform/element.py @@ -293,7 +293,7 @@ def is_one(self): def is_graded_modular_form(self): r""" - Return ``True`` if the given quasiform is a graded modular forms element + Return ``True`` if the given quasimodular form is a graded modular forms element and ``False`` otherwise. EXAMPLES:: @@ -325,8 +325,8 @@ def is_graded_modular_form(self): def is_modular_form(self): r""" - Return ``True`` if the given quasiform is a modular form and ``False`` - otherwise. + Return ``True`` if the given quasimodular form is a modular form and + ``False`` otherwise. EXAMPLES:: @@ -415,8 +415,9 @@ def is_homogeneous(self): def weight(self): r""" - Return the weight of the given quasiform. Note that the given form must - be homogeneous. + Return the weight of the given quasimodular form. + + Note that the given form must be homogeneous. EXAMPLES:: @@ -461,9 +462,10 @@ def homogeneous_components(self): def serre_derivative(self): r""" - Return the Serre derivative of the given quasimodular form. If the form - is not homogeneous, then this method sums the serre derivative of each - homogeneous components. + Return the Serre derivative of the given quasimodular form. + + If the form is not homogeneous, then this method sums the serre + derivative of each homogeneous component. EXAMPLES:: @@ -517,9 +519,10 @@ def serre_derivative(self): def derivative(self): r""" - Return the derivative `q \frac{d}{dq}` of the given quasiform. If the - form is not homogeneous, then this method sums the derivative of each - homogeneous components. + Return the derivative `q \frac{d}{dq}` of the given quasimodular form. + + If the form is not homogeneous, then this method sums the derivative of + each homogeneous component. EXAMPLES:: From a61c244c3780d0ae1a88f8aafd557ba65407ad2d Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 15:58:48 +0200 Subject: [PATCH 184/378] increase tolerance for doctests in modular/modform/numerical.py --- src/sage/modular/modform/numerical.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sage/modular/modform/numerical.py b/src/sage/modular/modform/numerical.py index f09aca90239..056f5ad88f1 100644 --- a/src/sage/modular/modform/numerical.py +++ b/src/sage/modular/modform/numerical.py @@ -71,21 +71,21 @@ class NumericalEigenforms(SageObject): sage: n = numerical_eigenforms(23) sage: n == loads(dumps(n)) True - sage: n.ap(2) # rel tol 2e-14 + sage: n.ap(2) # abs tol 1e-12 [3.0, -1.6180339887498947, 0.6180339887498968] - sage: n.systems_of_eigenvalues(7) # rel tol 2e-14 + sage: n.systems_of_eigenvalues(7) # abs tol 2e-12 [ [-1.6180339887498947, 2.2360679774997894, -3.2360679774997894], [0.6180339887498968, -2.236067977499788, 1.2360679774997936], [3.0, 4.0, 6.0] ] - sage: n.systems_of_abs(7) + sage: n.systems_of_abs(7) # abs tol 2e-12 [ - [0.6180339887..., 2.236067977..., 1.236067977...], - [1.6180339887..., 2.236067977..., 3.236067977...], + [0.6180339887498943, 2.2360679774997894, 1.2360679774997887], + [1.6180339887498947, 2.23606797749979, 3.2360679774997894], [3.0, 4.0, 6.0] ] - sage: n.eigenvalues([2,3,5]) # rel tol 2e-14 + sage: n.eigenvalues([2,3,5]) # rel tol 2e-12 [[3.0, -1.6180339887498947, 0.6180339887498968], [4.0, 2.2360679774997894, -2.236067977499788], [6.0, -3.2360679774997894, 1.2360679774997936]] From fea27fabb5736225941e569f00c5f53d1a74baa7 Mon Sep 17 00:00:00 2001 From: Sebastian Oehms Date: Mon, 25 Oct 2021 17:10:20 +0200 Subject: [PATCH 185/378] 32760: add braid_notation_old --- src/sage/databases/knotinfo_db.py | 14 ++++++++++++++ src/sage/knots/knotinfo.py | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/sage/databases/knotinfo_db.py b/src/sage/databases/knotinfo_db.py index cc0e2d034db..7ec59d4e501 100644 --- a/src/sage/databases/knotinfo_db.py +++ b/src/sage/databases/knotinfo_db.py @@ -822,6 +822,7 @@ def _test_database(self, **options): 'braid_index': ['Braid Index', KnotInfoColumnTypes.OnlyKnots], 'braid_length': ['Braid Length', KnotInfoColumnTypes.OnlyKnots], 'braid_notation': ['Braid Notation', KnotInfoColumnTypes.KnotsAndLinks], + 'braid_notation_old': ['Braid Notation', KnotInfoColumnTypes.OnlyLinks], 'alternating': ['Alternating', KnotInfoColumnTypes.KnotsAndLinks], 'alexander_polynomial': ['Alexander', KnotInfoColumnTypes.OnlyKnots], 'jones_polynomial': ['Jones', KnotInfoColumnTypes.KnotsAndLinks], @@ -897,6 +898,19 @@ def _test_database(self, **options): '{3, {1, -2, 1, 2, 2, 1, 1}}', '{2, {-1, -1, -1, -1, -1, -1}}' ], + dc.braid_notation_old: [ + '{2, {-1, -1}}', + '{2, {1, 1}}', + '{4, {1, -2, 3, -2, -1, -2, -3, -2}}', + '{2, {1, 1, 1, 1}}', + '{3, {-1, 2, -1, 2, -1}}', + '{3, {-1, 2, -1, 2, -1}}', + '{4, {1, -2, 3, -2, 1, -2, -3, -2}}', + '{4, {1, 2, 3, 2, 2, -1, 2, 2, -3, 2}}', + '{4, {1, -2, -2, -2, 3, -2, -1, -2, -3, -2}}', + '{4, {1, 2, -3, 2, -1, 2, 3, 2, 2, 2}}', + '{2, {-1, -1, -1, -1, -1, -1}}' + ], dc.braid_index: ['1', '2', '3', '2', '3', '4', '3', '3', '2', '4'], dc.braid_length: ['', '3', '4', '5', '6', '7', '6', '6', '7', '9'], dc.determinant: ['0', '3', '5', '5', '7', '9', '11', '13', '7', '11', '2', '2', '4', '4', '8', '8', '12', '12', '10', '10', '6'], diff --git a/src/sage/knots/knotinfo.py b/src/sage/knots/knotinfo.py index d26da2cd8bb..7775f988967 100644 --- a/src/sage/knots/knotinfo.py +++ b/src/sage/knots/knotinfo.py @@ -599,7 +599,7 @@ def braid_notation(self, original=False): There has been a major change to braid representatives for proper links since version 2021.10.1. The former braid reresentatives can be obtained by the column - ``braid_notation_old``. + ``braid_notation_old`` (see the final example below). EXAMPLES:: @@ -609,6 +609,8 @@ def braid_notation(self, original=False): (-2, -2, -1, 2, -1) sage: L.braid_notation(original=True) '{3, {-2, -2, -1, 2, -1}}' + sage: L[L.items.braid_notation_old] + '{4, {1, -2, 3, -2, -1, -2, -3, -2}}' """ braid_notation = self[self.items.braid_notation] if original: From ea822d0266572d89e111f89d920773279add5425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 25 Oct 2021 18:04:52 +0200 Subject: [PATCH 186/378] fix E713 and E714 in matrix, groups, modules --- src/sage/groups/abelian_gps/abelian_aut.py | 2 +- .../groups/abelian_gps/abelian_group_gap.py | 4 ++-- src/sage/groups/fqf_orthogonal.py | 2 +- src/sage/groups/group_exp.py | 4 +--- src/sage/groups/libgap_morphism.py | 2 +- src/sage/groups/matrix_gps/isometries.py | 4 ++-- src/sage/groups/perm_gps/cubegroup.py | 2 +- src/sage/groups/perm_gps/permgroup.py | 10 +++++----- src/sage/groups/perm_gps/permgroup_named.py | 4 +--- .../matrix/matrix_integer_dense_saturation.py | 2 +- src/sage/modules/free_module.py | 6 +++--- src/sage/modules/matrix_morphism.py | 8 +++----- src/sage/modules/vector_space_morphism.py | 2 +- src/sage/modules/with_basis/morphism.py | 20 +++++++++---------- src/sage/modules/with_basis/subquotient.py | 10 +++++----- 15 files changed, 38 insertions(+), 44 deletions(-) diff --git a/src/sage/groups/abelian_gps/abelian_aut.py b/src/sage/groups/abelian_gps/abelian_aut.py index 18afe029eda..33defb5b271 100644 --- a/src/sage/groups/abelian_gps/abelian_aut.py +++ b/src/sage/groups/abelian_gps/abelian_aut.py @@ -115,7 +115,7 @@ def __init__(self, parent, x, check=True): sage: TestSuite(f).run() """ if check: - if not x in parent.gap(): + if x not in parent.gap(): raise ValueError("%s is not in the group %s" % (x, parent)) ElementLibGAP.__init__(self, parent, x) diff --git a/src/sage/groups/abelian_gps/abelian_group_gap.py b/src/sage/groups/abelian_gps/abelian_group_gap.py index 1a6583dac03..48d7eb39cb1 100644 --- a/src/sage/groups/abelian_gps/abelian_group_gap.py +++ b/src/sage/groups/abelian_gps/abelian_group_gap.py @@ -161,10 +161,10 @@ def exponents(self): orders = P.gens_orders() i = 0 for k in range(len(P.gens())): - if not k+1 in Lgens: + if k + 1 not in Lgens: exp.append(0) else: - i = Lgens.index(k+1) + i = Lgens.index(k + 1) exp.append(Lexpo[i] % orders[k]) return tuple(exp) diff --git a/src/sage/groups/fqf_orthogonal.py b/src/sage/groups/fqf_orthogonal.py index 184efa9be0b..05f76e582d1 100644 --- a/src/sage/groups/fqf_orthogonal.py +++ b/src/sage/groups/fqf_orthogonal.py @@ -558,7 +558,7 @@ def orbits(G, L): if not automorphisms: return f g = ambient(matrix(f)) - if not g in G: + if g not in G: G = B.orthogonal_group(tuple(ambient(s.matrix()) for s in G.gens())+(g,)) waiting = orbits(G, waiting) continue diff --git a/src/sage/groups/group_exp.py b/src/sage/groups/group_exp.py index bf0db4aa837..3fa83c6ff86 100644 --- a/src/sage/groups/group_exp.py +++ b/src/sage/groups/group_exp.py @@ -257,7 +257,6 @@ class GroupExp_Class(UniqueRepresentation, Parent): sage: GroupExp()(QQ) Multiplicative form of Rational Field - """ def __init__(self, G): r""" @@ -268,8 +267,7 @@ def __init__(self, G): sage: TestSuite(EG).run(skip = "_test_elements") """ - - if not G in CommutativeAdditiveGroups(): + if G not in CommutativeAdditiveGroups(): raise TypeError("%s must be a commutative additive group" % G) self._G = G Parent.__init__(self, category=Groups()) diff --git a/src/sage/groups/libgap_morphism.py b/src/sage/groups/libgap_morphism.py index 75785e2e382..77ba764a4f7 100644 --- a/src/sage/groups/libgap_morphism.py +++ b/src/sage/groups/libgap_morphism.py @@ -507,7 +507,7 @@ def lift(self, h): ValueError: f2 is not an element of the image of Group endomorphism of Abelian group with gap, generator orders (2, 4) """ - if not h in self.codomain(): + if h not in self.codomain(): raise TypeError("h (={}) must be an element of the codomain".format(h)) h = self.codomain()(h) phi = self.gap() diff --git a/src/sage/groups/matrix_gps/isometries.py b/src/sage/groups/matrix_gps/isometries.py index 55d6c52b632..ab611b4ce7f 100644 --- a/src/sage/groups/matrix_gps/isometries.py +++ b/src/sage/groups/matrix_gps/isometries.py @@ -116,9 +116,9 @@ def __init__(self, degree, base_ring, Q = invariant_quotient_module for f in gens: self._check_matrix(f) - if (not I is None) and I*f != I: + if (I is not None) and I * f != I: raise ValueError("the submodule is not preserved") - if not Q is None and (Q.W() != Q.W()*f or Q.V()*f != Q.V()): + if Q is not None and (Q.W() != Q.W()*f or Q.V()*f != Q.V()): raise ValueError("the quotient module is not preserved") if len(gens) == 0: # handle the trivial group gens = [G.parent().identity_matrix()] diff --git a/src/sage/groups/perm_gps/cubegroup.py b/src/sage/groups/perm_gps/cubegroup.py index dfdd6d52e74..807cd92ad02 100644 --- a/src/sage/groups/perm_gps/cubegroup.py +++ b/src/sage/groups/perm_gps/cubegroup.py @@ -735,7 +735,7 @@ def parse(self, mv, check=True): return mv if mv.parent() is self else PermutationGroup_generic.__call__(self, mv, check) elif isinstance(mv, str): # It is a string: may be in cycle notation or Rubik's notation - if '(' in mv and not '^' in mv: + if '(' in mv and '^' not in mv: return PermutationGroup_generic.__call__(self, mv, check) else: gens = self.gens() diff --git a/src/sage/groups/perm_gps/permgroup.py b/src/sage/groups/perm_gps/permgroup.py index f91dcd8fcca..3b8ab1fcd4a 100644 --- a/src/sage/groups/perm_gps/permgroup.py +++ b/src/sage/groups/perm_gps/permgroup.py @@ -1910,7 +1910,7 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"): True """ if implementation == "gap": - if not base_of_group is None: + if base_of_group is not None: raise ValueError("the optional argument 'base_of_group'" " (='%s') must be None if 'implementation'='gap'" % base_of_group) @@ -3823,9 +3823,9 @@ def cosets(self, S, side='right'): from copy import copy from sage.categories.finite_permutation_groups import FinitePermutationGroups - if not side in ['right','left']: + if side not in ['right', 'left']: raise ValueError("side should be 'right' or 'left', not %s" % side) - if not S in FinitePermutationGroups(): + if S not in FinitePermutationGroups(): raise TypeError("%s is not a permutation group" % S) if not S.is_subgroup(self): raise ValueError("%s is not a subgroup of %s" % (S, self)) @@ -3836,9 +3836,9 @@ def cosets(self, S, side='right'): while group: rep = group[0] if side == 'right': - coset = [e*rep for e in subgroup] + coset = [e * rep for e in subgroup] if side == 'left': - coset = [rep*e for e in subgroup] + coset = [rep * e for e in subgroup] for e in coset: group.remove(e) decomposition.append(coset) diff --git a/src/sage/groups/perm_gps/permgroup_named.py b/src/sage/groups/perm_gps/permgroup_named.py index 5010e958a3c..a7445145282 100644 --- a/src/sage/groups/perm_gps/permgroup_named.py +++ b/src/sage/groups/perm_gps/permgroup_named.py @@ -1552,13 +1552,11 @@ def __init__(self, p, m): AUTHOR: - Kevin Halasz (2012-8-7) - """ - if not isinstance(p, Integer) or not isinstance(m, Integer): raise TypeError('both p and m must be integers') - if not p in Primes(): + if p not in Primes(): raise ValueError('p must be prime, %s is not prime' % p) if p == 2 and m <= 3: diff --git a/src/sage/matrix/matrix_integer_dense_saturation.py b/src/sage/matrix/matrix_integer_dense_saturation.py index 87b55b6d7e6..b88e7b23472 100644 --- a/src/sage/matrix/matrix_integer_dense_saturation.py +++ b/src/sage/matrix/matrix_integer_dense_saturation.py @@ -111,7 +111,7 @@ def random_sublist_of_size(k, n): w = set([]) while len(w) < n: z = randrange(k) - if not z in w: + if z not in w: w.add(z) return sorted(w) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 1e3c73da128..4b0e3299804 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -512,8 +512,8 @@ def VectorSpace(K, dimension_or_basis_keys=None, sparse=False, inner_product_mat """ if not K.is_field(): raise TypeError("Argument K (= %s) must be a field." % K) - if not sparse in (True,False): - raise TypeError("Argument sparse (= %s) must be a boolean."%sparse) + if sparse not in (True, False): + raise TypeError("Argument sparse (= %s) must be a boolean." % sparse) return FreeModule(K, dimension_or_basis_keys, sparse, inner_product_matrix, with_basis=with_basis, rank=dimension, basis_keys=basis_keys, **args) @@ -4449,7 +4449,7 @@ def linear_dependence(self, vectors, zeros='left', check=True): """ if check: for v in vectors: - if not v in self: + if v not in self: raise ValueError('vector %s is not an element of %s' % (v, self)) if zeros == 'left': basis = 'echelon' diff --git a/src/sage/modules/matrix_morphism.py b/src/sage/modules/matrix_morphism.py index 58e670812ff..a01999eb3c8 100644 --- a/src/sage/modules/matrix_morphism.py +++ b/src/sage/modules/matrix_morphism.py @@ -93,7 +93,7 @@ def __init__(self, parent, side='left'): """ if not sage.categories.homset.is_Homset(parent): raise TypeError("parent must be a Hom space") - if not side in ["left", "right"]: + if side not in ["left", "right"]: raise ValueError("the argument side must be either 'left' or 'right'") self._side = side sage.categories.morphism.Morphism.__init__(self, parent) @@ -1695,13 +1695,11 @@ def matrix(self, side=None): ... ValueError: side must be 'left' or 'right', not junk """ - - if not side in ['left', 'right', None]: + if side not in ['left', 'right', None]: raise ValueError("side must be 'left' or 'right', not {0}".format(side)) if side == self.side() or side is None: return self._matrix - else: - return self._matrix.transpose() + return self._matrix.transpose() def is_injective(self): """ diff --git a/src/sage/modules/vector_space_morphism.py b/src/sage/modules/vector_space_morphism.py index 1a1fde6eb5a..c3725fbdabd 100644 --- a/src/sage/modules/vector_space_morphism.py +++ b/src/sage/modules/vector_space_morphism.py @@ -693,7 +693,7 @@ def linear_transformation(arg0, arg1=None, arg2=None, side='left'): except ImportError: Vector_callable_symbolic_dense = () - if not side in ['left', 'right']: + if side not in ['left', 'right']: raise ValueError("side must be 'left' or 'right', not {0}".format(side)) if not (is_Matrix(arg0) or is_VectorSpace(arg0)): raise TypeError('first argument must be a matrix or a vector space, not {0}'.format(arg0)) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 184b09a94e3..832a06adc35 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -175,11 +175,11 @@ def __init__(self, domain, codomain=None, category=None, affine=False): sage: TestSuite(phi).run() """ if category is None: - if not domain in ModulesWithBasis: - raise ValueError("domain(=%s) should be a module with basis"%(codomain)) + if domain not in ModulesWithBasis: + raise ValueError("domain(=%s) should be a module with basis" % (codomain)) base_ring = domain.base_ring() - if not hasattr( codomain, 'base_ring' ): + if not hasattr(codomain, 'base_ring'): raise ValueError("codomain(=%s) needs to have a base_ring attribute"%(codomain)) # codomain should be a module over base_ring # The natural test would be ``codomains in Modules(base_ring)`` @@ -954,7 +954,7 @@ def preimage(self, f): F = self.domain() G = self.codomain() on_basis = self.on_basis() - if not f in G: + if f not in G: raise ValueError("f(={}) must be in the codomain of the morphism to have a preimage under the latter".format(f)) remainder = f @@ -1333,17 +1333,17 @@ def __init__(self, domain, matrix, codomain=None, category=None, side="left"): [2 5] """ C = ModulesWithBasis(domain.base_ring()).FiniteDimensional() - if not domain in C: - raise ValueError("The domain %s should be finite dimensional"%domain) + if domain not in C: + raise ValueError("The domain %s should be finite dimensional" % domain) if codomain is None: raise ValueError("The codomain %s should be specified") - if not codomain in C: - raise ValueError("The codomain %s should be finite dimensional"%codomain) + if codomain not in C: + raise ValueError("The codomain %s should be finite dimensional" % codomain) if not is_Matrix(matrix): - raise ValueError("matrix (=%s) should be a matrix"%matrix) + raise ValueError("matrix (=%s) should be a matrix" % matrix) import sage.combinat.ranker indices = tuple(domain.basis().keys()) - rank_domain = sage.combinat.ranker.rank_from_list(indices) + rank_domain = sage.combinat.ranker.rank_from_list(indices) if side == "left": matrix = matrix.transpose() if matrix.nrows() != len(indices): diff --git a/src/sage/modules/with_basis/subquotient.py b/src/sage/modules/with_basis/subquotient.py index 5b5c52b2752..02651233a9c 100644 --- a/src/sage/modules/with_basis/subquotient.py +++ b/src/sage/modules/with_basis/subquotient.py @@ -1,12 +1,12 @@ r""" Quotients of Modules With Basis """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2010-2015 Florent Hivert # # Distributed under the terms of the GNU General Public License (GPL) -# http://www.gnu.org/licenses/ -#****************************************************************************** +# https://www.gnu.org/licenses/ +# ***************************************************************************** from sage.misc.cachefunc import cached_method from sage.sets.family import Family @@ -14,6 +14,7 @@ from sage.misc.lazy_attribute import lazy_attribute from sage.categories.all import ModulesWithBasis + class QuotientModuleWithBasis(CombinatorialFreeModule): r""" A class for quotients of a module with basis by a submodule. @@ -376,7 +377,7 @@ def is_submodule(self, other): return True if not isinstance(self, SubmoduleWithBasis) and self.ambient() is other.ambient(): raise ValueError("other (=%s) should be a submodule of the same ambient space" % other) - if not self in ModulesWithBasis.FiniteDimensional: + if self not in ModulesWithBasis.FiniteDimensional: raise NotImplementedError("is_submodule for infinite dimensional modules") for b in self.basis(): try: @@ -384,4 +385,3 @@ def is_submodule(self, other): except ValueError: return False return True - From 9a48bd91c5be689844600d7f9f0c3baabbfb0e84 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 18:22:59 +0200 Subject: [PATCH 187/378] outsource initialization of polyhedron into base0.py --- src/sage/geometry/polyhedron/base.py | 1315 ++----------------------- src/sage/geometry/polyhedron/base0.py | 1282 ++++++++++++++++++++++++ 2 files changed, 1344 insertions(+), 1253 deletions(-) create mode 100644 src/sage/geometry/polyhedron/base0.py diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index e2e6772defb..78abf572793 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -32,7 +32,7 @@ import itertools -from sage.structure.element import Element, coerce_binop, is_Vector, is_Matrix +from sage.structure.element import coerce_binop, is_Vector, is_Matrix from sage.structure.richcmp import rich_to_bool, op_NE from sage.cpython.string import bytes_to_str @@ -54,6 +54,7 @@ from sage.geometry.convex_set import ConvexSet_closed, AffineHullProjectionData from .constructor import Polyhedron +from .base0 import Polyhedron_base0 from sage.geometry.relative_interior import RelativeInterior from sage.categories.sets_cat import EmptySetError @@ -100,7 +101,7 @@ def is_Polyhedron(X): ######################################################################### -class Polyhedron_base(Element, ConvexSet_closed): +class Polyhedron_base(Polyhedron_base0, ConvexSet_closed): """ Base class for Polyhedron objects @@ -173,115 +174,26 @@ class Polyhedron_base(Element, ConvexSet_closed): sage: TestSuite(P).run() """ - def __init__(self, parent, Vrep, Hrep, Vrep_minimal=None, Hrep_minimal=None, pref_rep=None, mutable=False, **kwds): + def _init_empty_polyhedron(self): """ - Initializes the polyhedron. - - See :class:`Polyhedron_base` for a description of the input - data. + Initializes an empty polyhedron. TESTS:: - sage: p = Polyhedron() # indirect doctests - - sage: from sage.geometry.polyhedron.backend_field import Polyhedron_field - sage: from sage.geometry.polyhedron.parent import Polyhedra_field - sage: parent = Polyhedra_field(AA, 1, 'field') - sage: Vrep = [[[0], [1/2], [1]], [], []] - sage: Hrep = [[[0, 1], [1, -1]], []] - sage: p = Polyhedron_field(parent, Vrep, Hrep, - ....: Vrep_minimal=False, Hrep_minimal=True) - Traceback (most recent call last): - ... - ValueError: if both Vrep and Hrep are provided, they must be minimal... - - Illustration of ``pref_rep``. - Note that ``ppl`` doesn't support precomputed data:: - - sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_QQ_ppl - sage: from sage.geometry.polyhedron.parent import Polyhedra_QQ_ppl - sage: parent = Polyhedra_QQ_ppl(QQ, 1, 'ppl') - sage: p = Polyhedron_QQ_ppl(parent, Vrep, 'nonsense', - ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrep') - sage: p = Polyhedron_QQ_ppl(parent, 'nonsense', Hrep, - ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Hrep') - sage: p = Polyhedron_QQ_ppl(parent, 'nonsense', Hrep, - ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrepresentation') - Traceback (most recent call last): - ... - ValueError: ``pref_rep`` must be one of ``(None, 'Vrep', 'Hrep')`` + sage: Polyhedron().vertex_adjacency_matrix() # indirect doctest + [] + sage: Polyhedron().facet_adjacency_matrix() + [0] + """ + Polyhedron_base0._init_empty_polyhedron(self) - If the backend supports precomputed data, ``pref_rep`` is ignored:: + V_matrix = matrix(ZZ, 0, 0, 0) + V_matrix.set_immutable() + self.vertex_adjacency_matrix.set_cache(V_matrix) - sage: p = Polyhedron_field(parent, Vrep, 'nonsense', - ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrep') - Traceback (most recent call last): - ... - TypeError: ..._init_Hrepresentation() takes 3 positional arguments but 9 were given - - The empty polyhedron is detected when the Vrepresentation is given with generator; - see :trac:`29899`:: - - sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd - sage: from sage.geometry.polyhedron.parent import Polyhedra_QQ_cdd - sage: parent = Polyhedra_QQ_cdd(QQ, 0, 'cdd') - sage: p = Polyhedron_QQ_cdd(parent, [iter([]), iter([]), iter([])], None) - """ - Element.__init__(self, parent=parent) - if Vrep is not None and Hrep is not None: - if not (Vrep_minimal is True and Hrep_minimal is True): - raise ValueError("if both Vrep and Hrep are provided, they must be minimal" - " and Vrep_minimal and Hrep_minimal must both be True") - if hasattr(self, "_init_from_Vrepresentation_and_Hrepresentation"): - self._init_from_Vrepresentation_and_Hrepresentation(Vrep, Hrep) - return - else: - if pref_rep is None: - # Initialize from Hrepresentation if this seems simpler. - Vrep = [tuple(Vrep[0]), tuple(Vrep[1]), Vrep[2]] - Hrep = [tuple(Hrep[0]), Hrep[1]] - if len(Hrep[0]) < len(Vrep[0]) + len(Vrep[1]): - pref_rep = 'Hrep' - else: - pref_rep = 'Vrep' - if pref_rep == 'Vrep': - Hrep = None - elif pref_rep == 'Hrep': - Vrep = None - else: - raise ValueError("``pref_rep`` must be one of ``(None, 'Vrep', 'Hrep')``") - if Vrep is not None: - vertices, rays, lines = Vrep - - # We build tuples out of generators now to detect the empty polyhedron. - - # The damage is limited: - # The backend will have to obtain all elements from the generator anyway. - # The generators are mainly for saving time with initializing from - # Vrepresentation and Hrepresentation. - # If we dispose of one of them (see above), it is wasteful to have generated it. - - # E.g. the dilate will be set up with new Vrepresentation and Hrepresentation - # regardless of the backend along with the argument ``pref_rep``. - # As we only use generators, there is no penalty to this approach - # (and the method ``dilation`` does not have to distinguish by backend). - - if not isinstance(vertices, (tuple, list)): - vertices = tuple(vertices) - if not isinstance(rays, (tuple, list)): - rays = tuple(rays) - if not isinstance(lines, (tuple, list)): - lines = tuple(lines) - - if vertices or rays or lines: - self._init_from_Vrepresentation(vertices, rays, lines, **kwds) - else: - self._init_empty_polyhedron() - elif Hrep is not None: - ieqs, eqns = Hrep - self._init_from_Hrepresentation(ieqs, eqns, **kwds) - else: - self._init_empty_polyhedron() + H_matrix = matrix(ZZ, 1, 1, 0) + H_matrix.set_immutable() + self.facet_adjacency_matrix.set_cache(H_matrix) def __hash__(self): r""" @@ -342,93 +254,6 @@ def _sage_input_(self, sib, coerced): kwds['lines'] = [sib(tuple(l)) for l in self.lines()] return sib.name('Polyhedron')(**kwds) - def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds): - """ - Construct polyhedron from V-representation data. - - INPUT: - - - ``vertices`` -- list of point. Each point can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - - ``rays`` -- list of rays. Each ray can be specified as any - iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - - ``lines`` -- list of lines. Each line can be specified as - any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - EXAMPLES:: - - sage: p = Polyhedron() - sage: from sage.geometry.polyhedron.base import Polyhedron_base - sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], []) - Traceback (most recent call last): - ... - NotImplementedError: a derived class must implement this method - """ - raise NotImplementedError('a derived class must implement this method') - - def _init_from_Hrepresentation(self, ieqs, eqns, **kwds): - """ - Construct polyhedron from H-representation data. - - INPUT: - - - ``ieqs`` -- list of inequalities. Each line can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - - ``eqns`` -- list of equalities. Each line can be specified - as any iterable container of - :meth:`~sage.geometry.polyhedron.base.base_ring` elements. - - EXAMPLES:: - - sage: p = Polyhedron() - sage: from sage.geometry.polyhedron.base import Polyhedron_base - sage: Polyhedron_base._init_from_Hrepresentation(p, [], []) - Traceback (most recent call last): - ... - NotImplementedError: a derived class must implement this method - """ - raise NotImplementedError('a derived class must implement this method') - - def _init_empty_polyhedron(self): - """ - Initializes an empty polyhedron. - - TESTS:: - - sage: empty = Polyhedron(); empty - The empty polyhedron in ZZ^0 - sage: empty.Vrepresentation() - () - sage: empty.Hrepresentation() - (An equation -1 == 0,) - sage: Polyhedron(vertices = []) - The empty polyhedron in ZZ^0 - sage: Polyhedron(vertices = [])._init_empty_polyhedron() - sage: from sage.geometry.polyhedron.parent import Polyhedra - sage: Polyhedra(QQ,7)() - A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex - """ - self._Vrepresentation = [] - self._Hrepresentation = [] - self.parent()._make_Equation(self, [-1] + [0] * self.ambient_dim()) - self._Vrepresentation = tuple(self._Vrepresentation) - self._Hrepresentation = tuple(self._Hrepresentation) - - V_matrix = matrix(ZZ, 0, 0, 0) - V_matrix.set_immutable() - self.vertex_adjacency_matrix.set_cache(V_matrix) - - H_matrix = matrix(ZZ, 1, 1, 0) - H_matrix.set_immutable() - self.facet_adjacency_matrix.set_cache(H_matrix) - def _facet_adjacency_matrix(self): """ Compute the facet adjacency matrix in case it has not been @@ -532,126 +357,6 @@ def _test_basic_properties(self, tester=None, **options): if self.n_inequalities() < 40: tester.assertEqual(self, Polyhedron(ieqs=self.inequalities(), eqns=self.equations(), ambient_dim=self.ambient_dim())) - def base_extend(self, base_ring, backend=None): - """ - Return a new polyhedron over a larger base ring. - - This method can also be used to change the backend. - - INPUT: - - - ``base_ring`` -- the new base ring - - - ``backend`` -- the new backend, see - :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. - If ``None`` (the default), attempt to keep the same backend. - Otherwise, use the same defaulting behavior - as described there. - - OUTPUT: - - The same polyhedron, but over a larger base ring and possibly with a changed backend. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ); P - A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray - sage: P.base_extend(QQ) - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray - sage: P.base_extend(QQ) == P - True - - TESTS: - - Test that :trac:`22575` is fixed:: - - sage: Q = P.base_extend(ZZ, backend='field') - sage: Q.backend() - 'field' - - """ - new_parent = self.parent().base_extend(base_ring, backend) - return new_parent(self, copy=True) - - def change_ring(self, base_ring, backend=None): - """ - Return the polyhedron obtained by coercing the entries of the - vertices/lines/rays of this polyhedron into the given ring. - - This method can also be used to change the backend. - - INPUT: - - - ``base_ring`` -- the new base ring - - - ``backend`` -- the new backend or ``None`` (default), see - :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. - If ``None`` (the default), attempt to keep the same backend. - Otherwise, use the same defaulting behavior - as described there. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=QQ); P - A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray - sage: P.change_ring(ZZ) - A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray - sage: P.change_ring(ZZ) == P - True - - sage: P = Polyhedron(vertices=[(-1.3,0), (0,2.3)], base_ring=RDF); P.vertices() - (A vertex at (-1.3, 0.0), A vertex at (0.0, 2.3)) - sage: P.change_ring(QQ).vertices() - (A vertex at (-13/10, 0), A vertex at (0, 23/10)) - sage: P == P.change_ring(QQ) - True - sage: P.change_ring(ZZ) - Traceback (most recent call last): - ... - TypeError: cannot change the base ring to the Integer Ring - - sage: P = polytopes.regular_polygon(3); P # optional - sage.rings.number_field - A 2-dimensional polyhedron in AA^2 defined as the convex hull of 3 vertices - sage: P.vertices() # optional - sage.rings.number_field - (A vertex at (0.?e-16, 1.000000000000000?), - A vertex at (0.866025403784439?, -0.500000000000000?), - A vertex at (-0.866025403784439?, -0.500000000000000?)) - sage: P.change_ring(QQ) # optional - sage.rings.number_field - Traceback (most recent call last): - ... - TypeError: cannot change the base ring to the Rational Field - - .. WARNING:: - - The base ring ``RDF`` should be used with care. As it is - not an exact ring, certain computations may break or - silently produce wrong results, for example changing the - base ring from an exact ring into ``RDF`` may cause a - loss of data:: - - sage: P = Polyhedron([[2/3,0],[6666666666666667/10^16,0]], base_ring=AA); P # optional - sage.rings.number_field - A 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices - sage: Q = P.change_ring(RDF); Q # optional - sage.rings.number_field - A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex - sage: P.n_vertices() == Q.n_vertices() # optional - sage.rings.number_field - False - """ - from sage.categories.rings import Rings - - if base_ring not in Rings(): - raise ValueError("invalid base ring") - - try: - vertices = [[base_ring(x) for x in vertex] for vertex in self.vertices_list()] - rays = [[base_ring(x) for x in ray] for ray in self.rays_list()] - lines = [[base_ring(x) for x in line] for line in self.lines_list()] - - except (TypeError, ValueError): - raise TypeError("cannot change the base ring to the {0}".format(base_ring)) - - new_parent = self.parent().change_ring(base_ring, backend) - return new_parent([vertices, rays, lines], None) - def _richcmp_(self, other, op): """ Compare ``self`` and ``other``. @@ -741,30 +446,6 @@ def _is_subpolyhedron(self, other): for other_H in other.Hrepresentation() for self_V in self.Vrepresentation()) - def is_mutable(self): - r""" - Return True if the polyhedron is mutable, i.e. it can be modified in place. - - EXAMPLES:: - - sage: p = polytopes.cube(backend='field') - sage: p.is_mutable() - False - """ - return False - - def is_immutable(self): - r""" - Return True if the polyhedron is immutable, i.e. it cannot be modified in place. - - EXAMPLES:: - - sage: p = polytopes.cube(backend='field') - sage: p.is_immutable() - True - """ - return True - @cached_method def vertex_facet_graph(self, labels=True): r""" @@ -1226,59 +907,6 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, edge_color, facet_color, opacity, vertex_color, axis) - def _repr_(self): - """ - Return a description of the polyhedron. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) - sage: poly_test._repr_() - 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' - sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) - sage: grammar_test._repr_() - 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' - """ - desc = '' - if self.n_vertices() == 0: - desc += 'The empty polyhedron' - else: - desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' - desc += ' in ' - desc += self.parent()._repr_ambient_module() - - if self.n_vertices() > 0: - desc += ' defined as the convex hull of ' - desc += repr(self.n_vertices()) - if self.n_vertices() == 1: - desc += ' vertex' - else: - desc += ' vertices' - - if self.n_rays() > 0: - if self.n_lines() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_rays()) - if self.n_rays() == 1: - desc += ' ray' - else: - desc += ' rays' - - if self.n_lines() > 0: - if self.n_rays() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_lines()) - if self.n_lines() == 1: - desc += ' line' - else: - desc += ' lines' - - return desc - def _rich_repr_(self, display_manager, **kwds): r""" Rich Output Magic Method @@ -1456,105 +1084,6 @@ def write_cdd_Vrepresentation(self, filename): with open(filename, 'w') as f: f.write(self.cdd_Vrepresentation()) - @cached_method - def n_equations(self): - """ - Return the number of equations. The representation will - always be minimal, so the number of equations is the - codimension of the polyhedron in the ambient space. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]]) - sage: p.n_equations() - 1 - """ - return len(self.equations()) - - @cached_method - def n_inequalities(self): - """ - Return the number of inequalities. The representation will - always be minimal, so the number of inequalities is the - number of facets of the polyhedron in the ambient space. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]]) - sage: p.n_inequalities() - 3 - - sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)]) - sage: p.n_facets() - 8 - """ - return len(self.inequalities()) - - n_facets = n_inequalities - - @cached_method - def n_vertices(self): - """ - Return the number of vertices. The representation will - always be minimal. - - .. WARNING:: - - If the polyhedron has lines, return the number of vertices in - the ``Vrepresentation``. As the represented polyhedron has - no 0-dimensional faces (i.e. vertices), ``n_vertices`` corresponds - to the number of `k`-faces, where `k` is the number of lines:: - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) - sage: P.n_vertices() - 1 - sage: P.faces(0) - () - sage: P.f_vector() - (1, 0, 1, 1) - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0],[0,1,1]]) - sage: P.n_vertices() - 1 - sage: P.f_vector() - (1, 0, 0, 1, 1) - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[1,0],[0,1],[1,1]], rays=[[1,1]]) - sage: p.n_vertices() - 2 - """ - return len(self.vertices()) - - @cached_method - def n_rays(self): - """ - Return the number of rays. The representation will - always be minimal. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[1,0],[0,1]], rays=[[1,1]]) - sage: p.n_rays() - 1 - """ - return len(self.rays()) - - @cached_method - def n_lines(self): - """ - Return the number of lines. The representation will - always be minimal. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[0,0]], rays=[[0,1],[0,-1]]) - sage: p.n_lines() - 1 - """ - return len(self.lines()) - def to_linear_program(self, solver=None, return_variable=False, base_ring=None): r""" Return a linear optimization problem over the polyhedron in the form of @@ -1674,573 +1203,66 @@ def to_linear_program(self, solver=None, return_variable=False, base_ring=None): else: return p - def Hrepresentation(self, index=None): + @cached_method + def vertices_matrix(self, base_ring=None): """ - Return the objects of the H-representation. Each entry is - either an inequality or a equation. + Return the coordinates of the vertices as the columns of a matrix. INPUT: - - ``index`` -- either an integer or ``None`` + - ``base_ring`` -- A ring or ``None`` (default). The base ring + of the returned matrix. If not specified, the base ring of + the polyhedron is used. OUTPUT: - The optional argument is an index running from ``0`` to - ``self.n_Hrepresentation()-1``. If present, the - H-representation object at the given index will be - returned. Without an argument, returns the list of all - H-representation objects. - - EXAMPLES:: - - sage: p = polytopes.hypercube(3, backend='field') - sage: p.Hrepresentation(0) - An inequality (-1, 0, 0) x + 1 >= 0 - sage: p.Hrepresentation(0) == p.Hrepresentation()[0] - True - """ - if index is None: - return self._Hrepresentation - else: - return self._Hrepresentation[index] + A matrix over ``base_ring`` whose columns are the coordinates + of the vertices. A ``TypeError`` is raised if the coordinates + cannot be converted to ``base_ring``. - def Hrepresentation_str(self, separator='\n', latex=False, style='>=', align=None, **kwds): - r""" - Return a human-readable string representation of the Hrepresentation of this - polyhedron. + .. WARNING:: - INPUT: + If the polyhedron has lines, return the coordinates of the vertices + of the ``Vrepresentation``. However, the represented polyhedron + has no 0-dimensional faces (i.e. vertices):: - - ``separator`` -- a string. Default is ``"\n"``. + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) + sage: P.vertices_matrix() + [0] + [0] + [0] + sage: P.faces(0) + () - - ``latex`` -- a boolean. Default is ``False``. + EXAMPLES:: - - ``style`` -- either ``"positive"`` (making all coefficients positive) - or ``"<="``, or ``">="``. Default is ``">="``. + sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) + sage: triangle.vertices_matrix() + [0 1 1] + [1 0 1] + sage: (triangle/2).vertices_matrix() + [ 0 1/2 1/2] + [1/2 0 1/2] + sage: (triangle/2).vertices_matrix(ZZ) + Traceback (most recent call last): + ... + TypeError: no conversion of this rational to integer - - ``align`` -- a boolean or ``None''. Default is ``None`` in which case - ``align`` is ``True`` if ``separator`` is the newline character. - If set, then the lines of the output string are aligned - by the comparison symbol by padding blanks. + TESTS: - Keyword parameters of - :meth:`~sage.geometry.polyhedron.representation.Hrepresentation.repr_pretty` - are passed on: + Check that :trac:`28828` is fixed:: - - ``prefix`` -- a string - - - ``indices`` -- a tuple or other iterable - - OUTPUT: - - A string. - - EXAMPLES:: - - sage: P = polytopes.permutahedron(3) - sage: print(P.Hrepresentation_str()) - x0 + x1 + x2 == 6 - x0 + x1 >= 3 - -x0 - x1 >= -5 - x1 >= 1 - -x0 >= -3 - x0 >= 1 - -x1 >= -3 - - sage: print(P.Hrepresentation_str(style='<=')) - -x0 - x1 - x2 == -6 - -x0 - x1 <= -3 - x0 + x1 <= 5 - -x1 <= -1 - x0 <= 3 - -x0 <= -1 - x1 <= 3 - - sage: print(P.Hrepresentation_str(style='positive')) - x0 + x1 + x2 == 6 - x0 + x1 >= 3 - 5 >= x0 + x1 - x1 >= 1 - 3 >= x0 - x0 >= 1 - 3 >= x1 - - sage: print(P.Hrepresentation_str(latex=True)) - \begin{array}{rcl} - x_{0} + x_{1} + x_{2} & = & 6 \\ - x_{0} + x_{1} & \geq & 3 \\ - -x_{0} - x_{1} & \geq & -5 \\ - x_{1} & \geq & 1 \\ - -x_{0} & \geq & -3 \\ - x_{0} & \geq & 1 \\ - -x_{1} & \geq & -3 - \end{array} - - sage: print(P.Hrepresentation_str(align=False)) - x0 + x1 + x2 == 6 - x0 + x1 >= 3 - -x0 - x1 >= -5 - x1 >= 1 - -x0 >= -3 - x0 >= 1 - -x1 >= -3 - - sage: c = polytopes.cube() - sage: c.Hrepresentation_str(separator=', ', style='positive') - '1 >= x0, 1 >= x1, 1 >= x2, 1 + x0 >= 0, 1 + x2 >= 0, 1 + x1 >= 0' - """ - pretty_hs = [h.repr_pretty(split=True, latex=latex, style=style, **kwds) for h in self.Hrepresentation()] - shift = any(pretty_h[2].startswith('-') for pretty_h in pretty_hs) - - if align is None: - align = separator == "\n" - if align: - lengths = [(len(s[0]), len(s[1]), len(s[2])) for s in pretty_hs] - from operator import itemgetter - length_left = max(lengths, key=itemgetter(0))[0] - length_middle = max(lengths, key=itemgetter(1))[1] - length_right = max(lengths, key=itemgetter(2))[2] - if shift: - length_right += 1 - if latex: - h_line = "{:>" + "{}".format(length_left) + "} & {:" + \ - "{}".format(length_middle) + "} & {:" + \ - "{}".format(length_right) + "}\\\\" - else: - h_line = "{:>" + "{}".format(length_left) \ - + "} {:" + "{}".format(length_middle) \ - + "} {:" + "{}".format(length_right) + "}" - elif latex: - h_line = "{} & {} & {}\\\\" - else: - h_line = "{} {} {}" - - def pad_non_minus(s): - if align and shift and not s.startswith('-'): - return ' ' + s - else: - return s - h_list = [h_line.format(pretty_h[0], pretty_h[1], pad_non_minus(pretty_h[2])) - for pretty_h in pretty_hs] - pretty_print = separator.join(h_list) - - if not latex: - return pretty_print - else: - # below we remove the 2 unnecessary backslashes at the end of pretty_print - return "\\begin{array}{rcl}\n" + pretty_print[:-2] + "\n\\end{array}" - - def Hrep_generator(self): - """ - Return an iterator over the objects of the H-representation - (inequalities or equations). - - EXAMPLES:: - - sage: p = polytopes.hypercube(3) - sage: next(p.Hrep_generator()) - An inequality (-1, 0, 0) x + 1 >= 0 - """ - for H in self.Hrepresentation(): - yield H - - @cached_method - def n_Hrepresentation(self): - """ - Return the number of objects that make up the - H-representation of the polyhedron. - - OUTPUT: - - Integer. - - EXAMPLES:: - - sage: p = polytopes.cross_polytope(4) - sage: p.n_Hrepresentation() - 16 - sage: p.n_Hrepresentation() == p.n_inequalities() + p.n_equations() - True - """ - return len(self.Hrepresentation()) - - def Vrepresentation(self, index=None): - """ - Return the objects of the V-representation. Each entry is - either a vertex, a ray, or a line. - - See :mod:`sage.geometry.polyhedron.constructor` for a - definition of vertex/ray/line. - - INPUT: - - - ``index`` -- either an integer or ``None`` - - OUTPUT: - - The optional argument is an index running from ``0`` to - ``self.n_Vrepresentation()-1``. If present, the - V-representation object at the given index will be - returned. Without an argument, returns the list of all - V-representation objects. - - EXAMPLES:: - - sage: p = polytopes.simplex(4, project=True) - sage: p.Vrepresentation(0) - A vertex at (0.7071067812, 0.4082482905, 0.2886751346, 0.2236067977) - sage: p.Vrepresentation(0) == p.Vrepresentation() [0] - True - """ - if index is None: - return self._Vrepresentation - else: - return self._Vrepresentation[index] - - @cached_method - def n_Vrepresentation(self): - """ - Return the number of objects that make up the - V-representation of the polyhedron. - - OUTPUT: - - Integer. - - EXAMPLES:: - - sage: p = polytopes.simplex(4) - sage: p.n_Vrepresentation() - 5 - sage: p.n_Vrepresentation() == p.n_vertices() + p.n_rays() + p.n_lines() - True - """ - return len(self.Vrepresentation()) - - def Vrep_generator(self): - """ - Return an iterator over the objects of the V-representation - (vertices, rays, and lines). - - EXAMPLES:: - - sage: p = polytopes.cyclic_polytope(3,4) - sage: vg = p.Vrep_generator() - sage: next(vg) - A vertex at (0, 0, 0) - sage: next(vg) - A vertex at (1, 1, 1) - """ - for V in self.Vrepresentation(): - yield V - - def inequality_generator(self): - """ - Return a generator for the defining inequalities of the - polyhedron. - - OUTPUT: - - A generator of the inequality Hrepresentation objects. - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) - sage: for v in triangle.inequality_generator(): print(v) - An inequality (1, 1) x - 1 >= 0 - An inequality (0, -1) x + 1 >= 0 - An inequality (-1, 0) x + 1 >= 0 - sage: [ v for v in triangle.inequality_generator() ] - [An inequality (1, 1) x - 1 >= 0, - An inequality (0, -1) x + 1 >= 0, - An inequality (-1, 0) x + 1 >= 0] - sage: [ [v.A(), v.b()] for v in triangle.inequality_generator() ] - [[(1, 1), -1], [(0, -1), 1], [(-1, 0), 1]] - """ - for H in self.Hrepresentation(): - if H.is_inequality(): - yield H - - @cached_method - def inequalities(self): - """ - Return all inequalities. - - OUTPUT: - - A tuple of inequalities. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]]) - sage: p.inequalities()[0:3] - (An inequality (1, 0, 0) x + 0 >= 0, - An inequality (0, 1, 0) x + 0 >= 0, - An inequality (0, 0, 1) x + 0 >= 0) - sage: p3 = Polyhedron(vertices = Permutations([1,2,3,4])) - sage: ieqs = p3.inequalities() - sage: ieqs[0] - An inequality (0, 1, 1, 1) x - 6 >= 0 - sage: list(_) - [-6, 0, 1, 1, 1] - """ - return tuple(self.inequality_generator()) - - def inequalities_list(self): - """ - Return a list of inequalities as coefficient lists. - - .. NOTE:: - - It is recommended to use :meth:`inequalities` or - :meth:`inequality_generator` instead to iterate over the - list of :class:`Inequality` objects. - - EXAMPLES:: - - sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]]) - sage: p.inequalities_list()[0:3] - [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] - sage: p3 = Polyhedron(vertices = Permutations([1,2,3,4])) - sage: ieqs = p3.inequalities_list() - sage: ieqs[0] - [-6, 0, 1, 1, 1] - sage: ieqs[-1] - [-3, 0, 1, 0, 1] - sage: ieqs == [list(x) for x in p3.inequality_generator()] - True - """ - return [list(x) for x in self.inequality_generator()] - - def equation_generator(self): - """ - Return a generator for the linear equations satisfied by the - polyhedron. - - EXAMPLES:: - - sage: p = polytopes.regular_polygon(8,base_ring=RDF) - sage: p3 = Polyhedron(vertices = [x+[0] for x in p.vertices()], base_ring=RDF) - sage: next(p3.equation_generator()) - An equation (0.0, 0.0, 1.0) x + 0.0 == 0 - """ - for H in self.Hrepresentation(): - if H.is_equation(): - yield H - - @cached_method - def equations(self): - """ - Return all linear constraints of the polyhedron. - - OUTPUT: - - A tuple of equations. - - EXAMPLES:: - - sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]]) - sage: test_p.equations() - (An equation (1, 1, 1, 1) x - 10 == 0,) - """ - return tuple(self.equation_generator()) - - def equations_list(self): - """ - Return the linear constraints of the polyhedron. As with - inequalities, each constraint is given as [b -a1 -a2 ... an] - where for variables x1, x2,..., xn, the polyhedron satisfies - the equation b = a1*x1 + a2*x2 + ... + an*xn. - - .. NOTE:: - - It is recommended to use :meth:`equations` or - :meth:`equation_generator()` instead to iterate over the - list of - :class:`~sage.geometry.polyhedron.representation.Equation` - objects. - - EXAMPLES:: - - sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]]) - sage: test_p.equations_list() - [[-10, 1, 1, 1, 1]] - """ - return [list(eq) for eq in self.equation_generator()] - - def vertices_list(self): - """ - Return a list of vertices of the polyhedron. - - .. NOTE:: - - It is recommended to use :meth:`vertex_generator` instead to - iterate over the list of :class:`Vertex` objects. - - .. WARNING:: - - If the polyhedron has lines, return the vertices - of the ``Vrepresentation``. However, the represented polyhedron - has no 0-dimensional faces (i.e. vertices):: - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) - sage: P.vertices_list() - [[0, 0, 0]] - sage: P.faces(0) - () - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) - sage: triangle.vertices_list() - [[0, 1], [1, 0], [1, 1]] - sage: a_simplex = Polyhedron(ieqs = [ - ....: [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1] - ....: ], eqns = [[1,-1,-1,-1,-1]]) - sage: a_simplex.vertices_list() - [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] - sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()] - True - """ - return [list(x) for x in self.vertex_generator()] - - def vertex_generator(self): - """ - Return a generator for the vertices of the polyhedron. - - .. WARNING:: - - If the polyhedron has lines, return a generator for the vertices - of the ``Vrepresentation``. However, the represented polyhedron - has no 0-dimensional faces (i.e. vertices):: - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) - sage: list(P.vertex_generator()) - [A vertex at (0, 0, 0)] - sage: P.faces(0) - () - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) - sage: for v in triangle.vertex_generator(): print(v) - A vertex at (0, 1) - A vertex at (1, 0) - A vertex at (1, 1) - sage: v_gen = triangle.vertex_generator() - sage: next(v_gen) # the first vertex - A vertex at (0, 1) - sage: next(v_gen) # the second vertex - A vertex at (1, 0) - sage: next(v_gen) # the third vertex - A vertex at (1, 1) - sage: try: next(v_gen) # there are only three vertices - ....: except StopIteration: print("STOP") - STOP - sage: type(v_gen) - <... 'generator'> - sage: [ v for v in triangle.vertex_generator() ] - [A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1)] - """ - for V in self.Vrepresentation(): - if V.is_vertex(): - yield V - - @cached_method - def vertices(self): - """ - Return all vertices of the polyhedron. - - OUTPUT: - - A tuple of vertices. - - .. WARNING:: - - If the polyhedron has lines, return the vertices - of the ``Vrepresentation``. However, the represented polyhedron - has no 0-dimensional faces (i.e. vertices):: - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) - sage: P.vertices() - (A vertex at (0, 0, 0),) - sage: P.faces(0) - () - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) - sage: triangle.vertices() - (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1)) - sage: a_simplex = Polyhedron(ieqs = [ - ....: [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1] - ....: ], eqns = [[1,-1,-1,-1,-1]]) - sage: a_simplex.vertices() - (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0), - A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1)) - """ - return tuple(self.vertex_generator()) - - @cached_method - def vertices_matrix(self, base_ring=None): - """ - Return the coordinates of the vertices as the columns of a matrix. - - INPUT: - - - ``base_ring`` -- A ring or ``None`` (default). The base ring - of the returned matrix. If not specified, the base ring of - the polyhedron is used. - - OUTPUT: - - A matrix over ``base_ring`` whose columns are the coordinates - of the vertices. A ``TypeError`` is raised if the coordinates - cannot be converted to ``base_ring``. - - .. WARNING:: - - If the polyhedron has lines, return the coordinates of the vertices - of the ``Vrepresentation``. However, the represented polyhedron - has no 0-dimensional faces (i.e. vertices):: - - sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) - sage: P.vertices_matrix() - [0] - [0] - [0] - sage: P.faces(0) - () - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) - sage: triangle.vertices_matrix() - [0 1 1] - [1 0 1] - sage: (triangle/2).vertices_matrix() - [ 0 1/2 1/2] - [1/2 0 1/2] - sage: (triangle/2).vertices_matrix(ZZ) - Traceback (most recent call last): - ... - TypeError: no conversion of this rational to integer - - TESTS: - - Check that :trac:`28828` is fixed:: - - sage: P.vertices_matrix().is_immutable() - True - """ - if base_ring is None: - base_ring = self.base_ring() - m = matrix(base_ring, self.ambient_dim(), self.n_vertices()) - for i, v in enumerate(self.vertices()): - for j in range(self.ambient_dim()): - m[j, i] = v[j] - m.set_immutable() - return m + sage: P.vertices_matrix().is_immutable() + True + """ + if base_ring is None: + base_ring = self.base_ring() + m = matrix(base_ring, self.ambient_dim(), self.n_vertices()) + for i, v in enumerate(self.vertices()): + for j in range(self.ambient_dim()): + m[j, i] = v[j] + m.set_immutable() + return m def an_affine_basis(self): """ @@ -2327,115 +1349,6 @@ def _test_an_affine_basis(self, tester=None, **options): for v in b: tester.assertIn(v, self.vertices()) - def ray_generator(self): - """ - Return a generator for the rays of the polyhedron. - - EXAMPLES:: - - sage: pi = Polyhedron(ieqs = [[1,1,0],[1,0,1]]) - sage: pir = pi.ray_generator() - sage: [x.vector() for x in pir] - [(1, 0), (0, 1)] - """ - for V in self.Vrepresentation(): - if V.is_ray(): - yield V - - @cached_method - def rays(self): - """ - Return a list of rays of the polyhedron. - - OUTPUT: - - A tuple of rays. - - EXAMPLES:: - - sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]]) - sage: p.rays() - (A ray in the direction (1, 0, 0), - A ray in the direction (0, 1, 0), - A ray in the direction (0, 0, 1)) - """ - return tuple(self.ray_generator()) - - def rays_list(self): - """ - Return a list of rays as coefficient lists. - - .. NOTE:: - - It is recommended to use :meth:`rays` or - :meth:`ray_generator` instead to iterate over the list of - :class:`Ray` objects. - - OUTPUT: - - A list of rays as lists of coordinates. - - EXAMPLES:: - - sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]]) - sage: p.rays_list() - [[1, 0, 0], [0, 1, 0], [0, 0, 1]] - sage: p.rays_list() == [list(r) for r in p.ray_generator()] - True - """ - return [list(x) for x in self.ray_generator()] - - def line_generator(self): - """ - Return a generator for the lines of the polyhedron. - - EXAMPLES:: - - sage: pr = Polyhedron(rays = [[1,0],[-1,0],[0,1]], vertices = [[-1,-1]]) - sage: next(pr.line_generator()).vector() - (1, 0) - """ - for V in self.Vrepresentation(): - if V.is_line(): - yield V - - @cached_method - def lines(self): - """ - Return all lines of the polyhedron. - - OUTPUT: - - A tuple of lines. - - EXAMPLES:: - - sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]]) - sage: p.lines() - (A line in the direction (1, 0),) - """ - return tuple(self.line_generator()) - - def lines_list(self): - """ - Return a list of lines of the polyhedron. The line data is given - as a list of coordinates rather than as a Hrepresentation object. - - .. NOTE:: - - It is recommended to use :meth:`line_generator` instead to - iterate over the list of :class:`Line` objects. - - EXAMPLES:: - - sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]]) - sage: p.lines_list() - [[1, 0]] - sage: p.lines_list() == [list(x) for x in p.line_generator()] - True - """ - return [list(x) for x in self.line_generator()] - def bounded_edges(self): """ Return the bounded edges (excluding rays and lines). @@ -2529,51 +1442,6 @@ def Hrepresentation_space(self): """ return self.parent().Hrepresentation_space() - def ambient_dim(self): - r""" - Return the dimension of the ambient space. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.ambient_dim() - 4 - """ - return self.parent().ambient_dim() - - def dim(self): - """ - Return the dimension of the polyhedron. - - OUTPUT: - - -1 if the polyhedron is empty, otherwise a non-negative integer. - - EXAMPLES:: - - sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) - sage: simplex.dim() - 3 - sage: simplex.ambient_dim() - 4 - - The empty set is a special case (:trac:`12193`):: - - sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) - sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) - sage: P12 = P1.intersection(P2) - sage: P12 - The empty polyhedron in ZZ^3 - sage: P12.dim() - -1 - """ - if self.n_Vrepresentation() == 0: - return -1 # the empty set - else: - return self.ambient_dim() - self.n_equations() - - dimension = dim - def is_empty(self): """ Test whether the polyhedron is the empty polyhedron @@ -3086,65 +1954,6 @@ def slack_matrix(self): slack_matrix.set_immutable() return slack_matrix - def base_ring(self): - """ - Return the base ring. - - OUTPUT: - - The ring over which the polyhedron is defined. Must be a - sub-ring of the reals to define a polyhedron, in particular - comparison must be defined. Popular choices are - - * ``ZZ`` (the ring of integers, lattice polytope), - - * ``QQ`` (exact arithmetic using gmp), - - * ``RDF`` (double precision floating-point arithmetic), or - - * ``AA`` (real algebraic field). - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]]) - sage: triangle.base_ring() == ZZ - True - """ - return self.parent().base_ring() - - def backend(self): - """ - Return the backend used. - - OUTPUT: - - The name of the backend used for computations. It will be one of - the following backends: - - * ``ppl`` the Parma Polyhedra Library - - * ``cdd`` CDD - - * ``normaliz`` normaliz - - * ``polymake`` polymake - - * ``field`` a generic Sage implementation - - EXAMPLES:: - - sage: triangle = Polyhedron(vertices = [[1, 0], [0, 1], [1, 1]]) - sage: triangle.backend() - 'ppl' - sage: D = polytopes.dodecahedron() - sage: D.backend() - 'field' - sage: P = Polyhedron([[1.23]]) - sage: P.backend() - 'cdd' - """ - return self.parent().backend() - @cached_method def center(self): """ diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py new file mode 100644 index 00000000000..fe66d0dcd74 --- /dev/null +++ b/src/sage/geometry/polyhedron/base0.py @@ -0,0 +1,1282 @@ +r""" +Base class for polyhedra, part 0 + +Initialization and access to Vrepresentation and Hrepresentation. +""" + +# **************************************************************************** +# Copyright (C) 2008-2012 Marshall Hampton +# Copyright (C) 2011-2015 Volker Braun +# Copyright (C) 2012-2018 Frederic Chapoton +# Copyright (C) 2013 Andrey Novoseltsev +# Copyright (C) 2014-2017 Moritz Firsching +# Copyright (C) 2014-2019 Thierry Monteil +# Copyright (C) 2015 Nathann Cohen +# Copyright (C) 2015-2017 Jeroen Demeyer +# Copyright (C) 2015-2017 Vincent Delecroix +# Copyright (C) 2015-2018 Dima Pasechnik +# Copyright (C) 2015-2020 Jean-Philippe Labbe +# Copyright (C) 2015-2021 Matthias Koeppe +# Copyright (C) 2016-2019 Daniel Krenn +# Copyright (C) 2017 Marcelo Forets +# Copyright (C) 2017-2018 Mark Bell +# Copyright (C) 2019 Julian Ritter +# Copyright (C) 2019-2020 Laith Rastanawi +# Copyright (C) 2019-2020 Sophia Elia +# Copyright (C) 2019-2021 Jonathan Kliem +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.cachefunc import cached_method +from sage.structure.element import Element + +class Polyhedron_base0(Element): + """ + Initialization and basic access for polyhedra. + + See :class:`sage.geometry.polyhedron.base.Polyhedron_base`. + + TESTS:: + + sage: from sage.geometry.polyhedron.base0 import Polyhedron_base0 + sage: P = Polyhedron(rays=[[1, 0, 0]], lines=[[0, 1, 0]]) + sage: Polyhedron_base0.__repr__(P) + 'A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line' + sage: Polyhedron_base0.Vrepresentation(P) + (A line in the direction (0, 1, 0), + A vertex at (0, 0, 0), + A ray in the direction (1, 0, 0)) + sage: Polyhedron_base0.vertices.f(P) + (A vertex at (0, 0, 0),) + sage: Polyhedron_base0.rays.f(P) + (A ray in the direction (1, 0, 0),) + sage: Polyhedron_base0.lines.f(P) + (A line in the direction (0, 1, 0),) + sage: Polyhedron_base0.Hrepresentation(P) + (An equation (0, 0, 1) x + 0 == 0, An inequality (1, 0, 0) x + 0 >= 0) + sage: Polyhedron_base0.inequalities.f(P) + (An inequality (1, 0, 0) x + 0 >= 0,) + sage: Polyhedron_base0.equations.f(P) + (An equation (0, 0, 1) x + 0 == 0,) + sage: Polyhedron_base0.base_ring(P) + Integer Ring + sage: Polyhedron_base0.backend(P) + 'ppl' + sage: Polyhedron_base0.dim(P) + 2 + sage: Polyhedron_base0.ambient_dim(P) + 3 + sage: Polyhedron_base0.change_ring(P, ZZ, backend='field').backend() + 'field' + sage: Polyhedron_base0.base_extend(P, QQ) + A 2-dimensional polyhedron in QQ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line + """ + def __init__(self, parent, Vrep, Hrep, Vrep_minimal=None, Hrep_minimal=None, pref_rep=None, mutable=False, **kwds): + """ + Initializes the polyhedron. + + See :class:`sage.geometry.polyhedron.base.Polyhedron_base` for a description of the input + data. + + TESTS:: + + sage: p = Polyhedron() # indirect doctests + + sage: from sage.geometry.polyhedron.backend_field import Polyhedron_field + sage: from sage.geometry.polyhedron.parent import Polyhedra_field + sage: parent = Polyhedra_field(AA, 1, 'field') + sage: Vrep = [[[0], [1/2], [1]], [], []] + sage: Hrep = [[[0, 1], [1, -1]], []] + sage: p = Polyhedron_field(parent, Vrep, Hrep, + ....: Vrep_minimal=False, Hrep_minimal=True) + Traceback (most recent call last): + ... + ValueError: if both Vrep and Hrep are provided, they must be minimal... + + Illustration of ``pref_rep``. + Note that ``ppl`` doesn't support precomputed data:: + + sage: from sage.geometry.polyhedron.backend_ppl import Polyhedron_QQ_ppl + sage: from sage.geometry.polyhedron.parent import Polyhedra_QQ_ppl + sage: parent = Polyhedra_QQ_ppl(QQ, 1, 'ppl') + sage: p = Polyhedron_QQ_ppl(parent, Vrep, 'nonsense', + ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrep') + sage: p = Polyhedron_QQ_ppl(parent, 'nonsense', Hrep, + ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Hrep') + sage: p = Polyhedron_QQ_ppl(parent, 'nonsense', Hrep, + ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrepresentation') + Traceback (most recent call last): + ... + ValueError: ``pref_rep`` must be one of ``(None, 'Vrep', 'Hrep')`` + + If the backend supports precomputed data, ``pref_rep`` is ignored:: + + sage: p = Polyhedron_field(parent, Vrep, 'nonsense', + ....: Vrep_minimal=True, Hrep_minimal=True, pref_rep='Vrep') + Traceback (most recent call last): + ... + TypeError: ..._init_Hrepresentation() takes 3 positional arguments but 9 were given + + The empty polyhedron is detected when the Vrepresentation is given with generator; + see :trac:`29899`:: + + sage: from sage.geometry.polyhedron.backend_cdd import Polyhedron_QQ_cdd + sage: from sage.geometry.polyhedron.parent import Polyhedra_QQ_cdd + sage: parent = Polyhedra_QQ_cdd(QQ, 0, 'cdd') + sage: p = Polyhedron_QQ_cdd(parent, [iter([]), iter([]), iter([])], None) + """ + Element.__init__(self, parent=parent) + if Vrep is not None and Hrep is not None: + if not (Vrep_minimal is True and Hrep_minimal is True): + raise ValueError("if both Vrep and Hrep are provided, they must be minimal" + " and Vrep_minimal and Hrep_minimal must both be True") + if hasattr(self, "_init_from_Vrepresentation_and_Hrepresentation"): + self._init_from_Vrepresentation_and_Hrepresentation(Vrep, Hrep) + return + else: + if pref_rep is None: + # Initialize from Hrepresentation if this seems simpler. + Vrep = [tuple(Vrep[0]), tuple(Vrep[1]), Vrep[2]] + Hrep = [tuple(Hrep[0]), Hrep[1]] + if len(Hrep[0]) < len(Vrep[0]) + len(Vrep[1]): + pref_rep = 'Hrep' + else: + pref_rep = 'Vrep' + if pref_rep == 'Vrep': + Hrep = None + elif pref_rep == 'Hrep': + Vrep = None + else: + raise ValueError("``pref_rep`` must be one of ``(None, 'Vrep', 'Hrep')``") + if Vrep is not None: + vertices, rays, lines = Vrep + + # We build tuples out of generators now to detect the empty polyhedron. + + # The damage is limited: + # The backend will have to obtain all elements from the generator anyway. + # The generators are mainly for saving time with initializing from + # Vrepresentation and Hrepresentation. + # If we dispose of one of them (see above), it is wasteful to have generated it. + + # E.g. the dilate will be set up with new Vrepresentation and Hrepresentation + # regardless of the backend along with the argument ``pref_rep``. + # As we only use generators, there is no penalty to this approach + # (and the method ``dilation`` does not have to distinguish by backend). + + if not isinstance(vertices, (tuple, list)): + vertices = tuple(vertices) + if not isinstance(rays, (tuple, list)): + rays = tuple(rays) + if not isinstance(lines, (tuple, list)): + lines = tuple(lines) + + if vertices or rays or lines: + self._init_from_Vrepresentation(vertices, rays, lines, **kwds) + else: + self._init_empty_polyhedron() + elif Hrep is not None: + ieqs, eqns = Hrep + self._init_from_Hrepresentation(ieqs, eqns, **kwds) + else: + self._init_empty_polyhedron() + + def _init_from_Vrepresentation(self, vertices, rays, lines, **kwds): + """ + Construct polyhedron from V-representation data. + + INPUT: + + - ``vertices`` -- list of point. Each point can be specified + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + + - ``rays`` -- list of rays. Each ray can be specified as any + iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + + - ``lines`` -- list of lines. Each line can be specified as + any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + + EXAMPLES:: + + sage: p = Polyhedron() + sage: from sage.geometry.polyhedron.base import Polyhedron_base + sage: Polyhedron_base._init_from_Vrepresentation(p, [], [], []) + Traceback (most recent call last): + ... + NotImplementedError: a derived class must implement this method + """ + raise NotImplementedError('a derived class must implement this method') + + def _init_from_Hrepresentation(self, ieqs, eqns, **kwds): + """ + Construct polyhedron from H-representation data. + + INPUT: + + - ``ieqs`` -- list of inequalities. Each line can be specified + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + + - ``eqns`` -- list of equalities. Each line can be specified + as any iterable container of + :meth:`~sage.geometry.polyhedron.base.base_ring` elements. + + EXAMPLES:: + + sage: p = Polyhedron() + sage: from sage.geometry.polyhedron.base import Polyhedron_base + sage: Polyhedron_base._init_from_Hrepresentation(p, [], []) + Traceback (most recent call last): + ... + NotImplementedError: a derived class must implement this method + """ + raise NotImplementedError('a derived class must implement this method') + + def _init_empty_polyhedron(self): + """ + Initializes an empty polyhedron. + + TESTS:: + + sage: empty = Polyhedron(); empty + The empty polyhedron in ZZ^0 + sage: empty.Vrepresentation() + () + sage: empty.Hrepresentation() + (An equation -1 == 0,) + sage: Polyhedron(vertices = []) + The empty polyhedron in ZZ^0 + sage: Polyhedron(vertices = [])._init_empty_polyhedron() + sage: from sage.geometry.polyhedron.parent import Polyhedra + sage: Polyhedra(QQ,7)() + A 0-dimensional polyhedron in QQ^7 defined as the convex hull of 1 vertex + """ + self._Vrepresentation = [] + self._Hrepresentation = [] + self.parent()._make_Equation(self, [-1] + [0] * self.ambient_dim()) + self._Vrepresentation = tuple(self._Vrepresentation) + self._Hrepresentation = tuple(self._Hrepresentation) + + def base_extend(self, base_ring, backend=None): + """ + Return a new polyhedron over a larger base ring. + + This method can also be used to change the backend. + + INPUT: + + - ``base_ring`` -- the new base ring + + - ``backend`` -- the new backend, see + :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. + If ``None`` (the default), attempt to keep the same backend. + Otherwise, use the same defaulting behavior + as described there. + + OUTPUT: + + The same polyhedron, but over a larger base ring and possibly with a changed backend. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=ZZ); P + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray + sage: P.base_extend(QQ) + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray + sage: P.base_extend(QQ) == P + True + + TESTS: + + Test that :trac:`22575` is fixed:: + + sage: Q = P.base_extend(ZZ, backend='field') + sage: Q.backend() + 'field' + + """ + new_parent = self.parent().base_extend(base_ring, backend) + return new_parent(self, copy=True) + + def change_ring(self, base_ring, backend=None): + """ + Return the polyhedron obtained by coercing the entries of the + vertices/lines/rays of this polyhedron into the given ring. + + This method can also be used to change the backend. + + INPUT: + + - ``base_ring`` -- the new base ring + + - ``backend`` -- the new backend or ``None`` (default), see + :func:`~sage.geometry.polyhedron.constructor.Polyhedron`. + If ``None`` (the default), attempt to keep the same backend. + Otherwise, use the same defaulting behavior + as described there. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[(1,0), (0,1)], rays=[(1,1)], base_ring=QQ); P + A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 2 vertices and 1 ray + sage: P.change_ring(ZZ) + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices and 1 ray + sage: P.change_ring(ZZ) == P + True + + sage: P = Polyhedron(vertices=[(-1.3,0), (0,2.3)], base_ring=RDF); P.vertices() + (A vertex at (-1.3, 0.0), A vertex at (0.0, 2.3)) + sage: P.change_ring(QQ).vertices() + (A vertex at (-13/10, 0), A vertex at (0, 23/10)) + sage: P == P.change_ring(QQ) + True + sage: P.change_ring(ZZ) + Traceback (most recent call last): + ... + TypeError: cannot change the base ring to the Integer Ring + + sage: P = polytopes.regular_polygon(3); P # optional - sage.rings.number_field + A 2-dimensional polyhedron in AA^2 defined as the convex hull of 3 vertices + sage: P.vertices() # optional - sage.rings.number_field + (A vertex at (0.?e-16, 1.000000000000000?), + A vertex at (0.866025403784439?, -0.500000000000000?), + A vertex at (-0.866025403784439?, -0.500000000000000?)) + sage: P.change_ring(QQ) # optional - sage.rings.number_field + Traceback (most recent call last): + ... + TypeError: cannot change the base ring to the Rational Field + + .. WARNING:: + + The base ring ``RDF`` should be used with care. As it is + not an exact ring, certain computations may break or + silently produce wrong results, for example changing the + base ring from an exact ring into ``RDF`` may cause a + loss of data:: + + sage: P = Polyhedron([[2/3,0],[6666666666666667/10^16,0]], base_ring=AA); P # optional - sage.rings.number_field + A 1-dimensional polyhedron in AA^2 defined as the convex hull of 2 vertices + sage: Q = P.change_ring(RDF); Q # optional - sage.rings.number_field + A 0-dimensional polyhedron in RDF^2 defined as the convex hull of 1 vertex + sage: P.n_vertices() == Q.n_vertices() # optional - sage.rings.number_field + False + """ + from sage.categories.rings import Rings + + if base_ring not in Rings(): + raise ValueError("invalid base ring") + + try: + vertices = [[base_ring(x) for x in vertex] for vertex in self.vertices_list()] + rays = [[base_ring(x) for x in ray] for ray in self.rays_list()] + lines = [[base_ring(x) for x in line] for line in self.lines_list()] + + except (TypeError, ValueError): + raise TypeError("cannot change the base ring to the {0}".format(base_ring)) + + new_parent = self.parent().change_ring(base_ring, backend) + return new_parent([vertices, rays, lines], None) + + def is_mutable(self): + r""" + Return True if the polyhedron is mutable, i.e. it can be modified in place. + + EXAMPLES:: + + sage: p = polytopes.cube(backend='field') + sage: p.is_mutable() + False + """ + return False + + def is_immutable(self): + r""" + Return True if the polyhedron is immutable, i.e. it cannot be modified in place. + + EXAMPLES:: + + sage: p = polytopes.cube(backend='field') + sage: p.is_immutable() + True + """ + return True + + def _repr_(self): + """ + Return a description of the polyhedron. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) + sage: poly_test._repr_() + 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' + sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) + sage: grammar_test._repr_() + 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' + """ + desc = '' + if self.n_vertices() == 0: + desc += 'The empty polyhedron' + else: + desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' + desc += ' in ' + desc += self.parent()._repr_ambient_module() + + if self.n_vertices() > 0: + desc += ' defined as the convex hull of ' + desc += repr(self.n_vertices()) + if self.n_vertices() == 1: + desc += ' vertex' + else: + desc += ' vertices' + + if self.n_rays() > 0: + if self.n_lines() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_rays()) + if self.n_rays() == 1: + desc += ' ray' + else: + desc += ' rays' + + if self.n_lines() > 0: + if self.n_rays() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_lines()) + if self.n_lines() == 1: + desc += ' line' + else: + desc += ' lines' + + return desc + + @cached_method + def n_equations(self): + """ + Return the number of equations. The representation will + always be minimal, so the number of equations is the + codimension of the polyhedron in the ambient space. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]]) + sage: p.n_equations() + 1 + """ + return len(self.equations()) + + @cached_method + def n_inequalities(self): + """ + Return the number of inequalities. The representation will + always be minimal, so the number of inequalities is the + number of facets of the polyhedron in the ambient space. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[1,0,0],[0,1,0],[0,0,1]]) + sage: p.n_inequalities() + 3 + + sage: p = Polyhedron(vertices = [[t,t^2,t^3] for t in range(6)]) + sage: p.n_facets() + 8 + """ + return len(self.inequalities()) + + n_facets = n_inequalities + + @cached_method + def n_vertices(self): + """ + Return the number of vertices. The representation will + always be minimal. + + .. WARNING:: + + If the polyhedron has lines, return the number of vertices in + the ``Vrepresentation``. As the represented polyhedron has + no 0-dimensional faces (i.e. vertices), ``n_vertices`` corresponds + to the number of `k`-faces, where `k` is the number of lines:: + + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) + sage: P.n_vertices() + 1 + sage: P.faces(0) + () + sage: P.f_vector() + (1, 0, 1, 1) + + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0],[0,1,1]]) + sage: P.n_vertices() + 1 + sage: P.f_vector() + (1, 0, 0, 1, 1) + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[1,0],[0,1],[1,1]], rays=[[1,1]]) + sage: p.n_vertices() + 2 + """ + return len(self.vertices()) + + @cached_method + def n_rays(self): + """ + Return the number of rays. The representation will + always be minimal. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[1,0],[0,1]], rays=[[1,1]]) + sage: p.n_rays() + 1 + """ + return len(self.rays()) + + @cached_method + def n_lines(self): + """ + Return the number of lines. The representation will + always be minimal. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[0,0]], rays=[[0,1],[0,-1]]) + sage: p.n_lines() + 1 + """ + return len(self.lines()) + + def Hrepresentation(self, index=None): + """ + Return the objects of the H-representation. Each entry is + either an inequality or a equation. + + INPUT: + + - ``index`` -- either an integer or ``None`` + + OUTPUT: + + The optional argument is an index running from ``0`` to + ``self.n_Hrepresentation()-1``. If present, the + H-representation object at the given index will be + returned. Without an argument, returns the list of all + H-representation objects. + + EXAMPLES:: + + sage: p = polytopes.hypercube(3, backend='field') + sage: p.Hrepresentation(0) + An inequality (-1, 0, 0) x + 1 >= 0 + sage: p.Hrepresentation(0) == p.Hrepresentation()[0] + True + """ + if index is None: + return self._Hrepresentation + else: + return self._Hrepresentation[index] + + def Hrepresentation_str(self, separator='\n', latex=False, style='>=', align=None, **kwds): + r""" + Return a human-readable string representation of the Hrepresentation of this + polyhedron. + + INPUT: + + - ``separator`` -- a string. Default is ``"\n"``. + + - ``latex`` -- a boolean. Default is ``False``. + + - ``style`` -- either ``"positive"`` (making all coefficients positive) + or ``"<="``, or ``">="``. Default is ``">="``. + + - ``align`` -- a boolean or ``None''. Default is ``None`` in which case + ``align`` is ``True`` if ``separator`` is the newline character. + If set, then the lines of the output string are aligned + by the comparison symbol by padding blanks. + + Keyword parameters of + :meth:`~sage.geometry.polyhedron.representation.Hrepresentation.repr_pretty` + are passed on: + + - ``prefix`` -- a string + + - ``indices`` -- a tuple or other iterable + + OUTPUT: + + A string. + + EXAMPLES:: + + sage: P = polytopes.permutahedron(3) + sage: print(P.Hrepresentation_str()) + x0 + x1 + x2 == 6 + x0 + x1 >= 3 + -x0 - x1 >= -5 + x1 >= 1 + -x0 >= -3 + x0 >= 1 + -x1 >= -3 + + sage: print(P.Hrepresentation_str(style='<=')) + -x0 - x1 - x2 == -6 + -x0 - x1 <= -3 + x0 + x1 <= 5 + -x1 <= -1 + x0 <= 3 + -x0 <= -1 + x1 <= 3 + + sage: print(P.Hrepresentation_str(style='positive')) + x0 + x1 + x2 == 6 + x0 + x1 >= 3 + 5 >= x0 + x1 + x1 >= 1 + 3 >= x0 + x0 >= 1 + 3 >= x1 + + sage: print(P.Hrepresentation_str(latex=True)) + \begin{array}{rcl} + x_{0} + x_{1} + x_{2} & = & 6 \\ + x_{0} + x_{1} & \geq & 3 \\ + -x_{0} - x_{1} & \geq & -5 \\ + x_{1} & \geq & 1 \\ + -x_{0} & \geq & -3 \\ + x_{0} & \geq & 1 \\ + -x_{1} & \geq & -3 + \end{array} + + sage: print(P.Hrepresentation_str(align=False)) + x0 + x1 + x2 == 6 + x0 + x1 >= 3 + -x0 - x1 >= -5 + x1 >= 1 + -x0 >= -3 + x0 >= 1 + -x1 >= -3 + + sage: c = polytopes.cube() + sage: c.Hrepresentation_str(separator=', ', style='positive') + '1 >= x0, 1 >= x1, 1 >= x2, 1 + x0 >= 0, 1 + x2 >= 0, 1 + x1 >= 0' + """ + pretty_hs = [h.repr_pretty(split=True, latex=latex, style=style, **kwds) for h in self.Hrepresentation()] + shift = any(pretty_h[2].startswith('-') for pretty_h in pretty_hs) + + if align is None: + align = separator == "\n" + if align: + lengths = [(len(s[0]), len(s[1]), len(s[2])) for s in pretty_hs] + from operator import itemgetter + length_left = max(lengths, key=itemgetter(0))[0] + length_middle = max(lengths, key=itemgetter(1))[1] + length_right = max(lengths, key=itemgetter(2))[2] + if shift: + length_right += 1 + if latex: + h_line = "{:>" + "{}".format(length_left) + "} & {:" + \ + "{}".format(length_middle) + "} & {:" + \ + "{}".format(length_right) + "}\\\\" + else: + h_line = "{:>" + "{}".format(length_left) \ + + "} {:" + "{}".format(length_middle) \ + + "} {:" + "{}".format(length_right) + "}" + elif latex: + h_line = "{} & {} & {}\\\\" + else: + h_line = "{} {} {}" + + def pad_non_minus(s): + if align and shift and not s.startswith('-'): + return ' ' + s + else: + return s + h_list = [h_line.format(pretty_h[0], pretty_h[1], pad_non_minus(pretty_h[2])) + for pretty_h in pretty_hs] + pretty_print = separator.join(h_list) + + if not latex: + return pretty_print + else: + # below we remove the 2 unnecessary backslashes at the end of pretty_print + return "\\begin{array}{rcl}\n" + pretty_print[:-2] + "\n\\end{array}" + + def Hrep_generator(self): + """ + Return an iterator over the objects of the H-representation + (inequalities or equations). + + EXAMPLES:: + + sage: p = polytopes.hypercube(3) + sage: next(p.Hrep_generator()) + An inequality (-1, 0, 0) x + 1 >= 0 + """ + for H in self.Hrepresentation(): + yield H + + @cached_method + def n_Hrepresentation(self): + """ + Return the number of objects that make up the + H-representation of the polyhedron. + + OUTPUT: + + Integer. + + EXAMPLES:: + + sage: p = polytopes.cross_polytope(4) + sage: p.n_Hrepresentation() + 16 + sage: p.n_Hrepresentation() == p.n_inequalities() + p.n_equations() + True + """ + return len(self.Hrepresentation()) + + def Vrepresentation(self, index=None): + """ + Return the objects of the V-representation. Each entry is + either a vertex, a ray, or a line. + + See :mod:`sage.geometry.polyhedron.constructor` for a + definition of vertex/ray/line. + + INPUT: + + - ``index`` -- either an integer or ``None`` + + OUTPUT: + + The optional argument is an index running from ``0`` to + ``self.n_Vrepresentation()-1``. If present, the + V-representation object at the given index will be + returned. Without an argument, returns the list of all + V-representation objects. + + EXAMPLES:: + + sage: p = polytopes.simplex(4, project=True) + sage: p.Vrepresentation(0) + A vertex at (0.7071067812, 0.4082482905, 0.2886751346, 0.2236067977) + sage: p.Vrepresentation(0) == p.Vrepresentation() [0] + True + """ + if index is None: + return self._Vrepresentation + else: + return self._Vrepresentation[index] + + @cached_method + def n_Vrepresentation(self): + """ + Return the number of objects that make up the + V-representation of the polyhedron. + + OUTPUT: + + Integer. + + EXAMPLES:: + + sage: p = polytopes.simplex(4) + sage: p.n_Vrepresentation() + 5 + sage: p.n_Vrepresentation() == p.n_vertices() + p.n_rays() + p.n_lines() + True + """ + return len(self.Vrepresentation()) + + def Vrep_generator(self): + """ + Return an iterator over the objects of the V-representation + (vertices, rays, and lines). + + EXAMPLES:: + + sage: p = polytopes.cyclic_polytope(3,4) + sage: vg = p.Vrep_generator() + sage: next(vg) + A vertex at (0, 0, 0) + sage: next(vg) + A vertex at (1, 1, 1) + """ + for V in self.Vrepresentation(): + yield V + + def inequality_generator(self): + """ + Return a generator for the defining inequalities of the + polyhedron. + + OUTPUT: + + A generator of the inequality Hrepresentation objects. + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) + sage: for v in triangle.inequality_generator(): print(v) + An inequality (1, 1) x - 1 >= 0 + An inequality (0, -1) x + 1 >= 0 + An inequality (-1, 0) x + 1 >= 0 + sage: [ v for v in triangle.inequality_generator() ] + [An inequality (1, 1) x - 1 >= 0, + An inequality (0, -1) x + 1 >= 0, + An inequality (-1, 0) x + 1 >= 0] + sage: [ [v.A(), v.b()] for v in triangle.inequality_generator() ] + [[(1, 1), -1], [(0, -1), 1], [(-1, 0), 1]] + """ + for H in self.Hrepresentation(): + if H.is_inequality(): + yield H + + @cached_method + def inequalities(self): + """ + Return all inequalities. + + OUTPUT: + + A tuple of inequalities. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]]) + sage: p.inequalities()[0:3] + (An inequality (1, 0, 0) x + 0 >= 0, + An inequality (0, 1, 0) x + 0 >= 0, + An inequality (0, 0, 1) x + 0 >= 0) + sage: p3 = Polyhedron(vertices = Permutations([1,2,3,4])) + sage: ieqs = p3.inequalities() + sage: ieqs[0] + An inequality (0, 1, 1, 1) x - 6 >= 0 + sage: list(_) + [-6, 0, 1, 1, 1] + """ + return tuple(self.inequality_generator()) + + def inequalities_list(self): + """ + Return a list of inequalities as coefficient lists. + + .. NOTE:: + + It is recommended to use :meth:`inequalities` or + :meth:`inequality_generator` instead to iterate over the + list of :class:`Inequality` objects. + + EXAMPLES:: + + sage: p = Polyhedron(vertices = [[0,0,0],[0,0,1],[0,1,0],[1,0,0],[2,2,2]]) + sage: p.inequalities_list()[0:3] + [[0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] + sage: p3 = Polyhedron(vertices = Permutations([1,2,3,4])) + sage: ieqs = p3.inequalities_list() + sage: ieqs[0] + [-6, 0, 1, 1, 1] + sage: ieqs[-1] + [-3, 0, 1, 0, 1] + sage: ieqs == [list(x) for x in p3.inequality_generator()] + True + """ + return [list(x) for x in self.inequality_generator()] + + def equation_generator(self): + """ + Return a generator for the linear equations satisfied by the + polyhedron. + + EXAMPLES:: + + sage: p = polytopes.regular_polygon(8,base_ring=RDF) + sage: p3 = Polyhedron(vertices = [x+[0] for x in p.vertices()], base_ring=RDF) + sage: next(p3.equation_generator()) + An equation (0.0, 0.0, 1.0) x + 0.0 == 0 + """ + for H in self.Hrepresentation(): + if H.is_equation(): + yield H + + @cached_method + def equations(self): + """ + Return all linear constraints of the polyhedron. + + OUTPUT: + + A tuple of equations. + + EXAMPLES:: + + sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]]) + sage: test_p.equations() + (An equation (1, 1, 1, 1) x - 10 == 0,) + """ + return tuple(self.equation_generator()) + + def equations_list(self): + """ + Return the linear constraints of the polyhedron. As with + inequalities, each constraint is given as [b -a1 -a2 ... an] + where for variables x1, x2,..., xn, the polyhedron satisfies + the equation b = a1*x1 + a2*x2 + ... + an*xn. + + .. NOTE:: + + It is recommended to use :meth:`equations` or + :meth:`equation_generator()` instead to iterate over the + list of + :class:`~sage.geometry.polyhedron.representation.Equation` + objects. + + EXAMPLES:: + + sage: test_p = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1],[3,4,1,2]]) + sage: test_p.equations_list() + [[-10, 1, 1, 1, 1]] + """ + return [list(eq) for eq in self.equation_generator()] + + def vertices_list(self): + """ + Return a list of vertices of the polyhedron. + + .. NOTE:: + + It is recommended to use :meth:`vertex_generator` instead to + iterate over the list of :class:`Vertex` objects. + + .. WARNING:: + + If the polyhedron has lines, return the vertices + of the ``Vrepresentation``. However, the represented polyhedron + has no 0-dimensional faces (i.e. vertices):: + + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) + sage: P.vertices_list() + [[0, 0, 0]] + sage: P.faces(0) + () + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) + sage: triangle.vertices_list() + [[0, 1], [1, 0], [1, 1]] + sage: a_simplex = Polyhedron(ieqs = [ + ....: [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1] + ....: ], eqns = [[1,-1,-1,-1,-1]]) + sage: a_simplex.vertices_list() + [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] + sage: a_simplex.vertices_list() == [list(v) for v in a_simplex.vertex_generator()] + True + """ + return [list(x) for x in self.vertex_generator()] + + def vertex_generator(self): + """ + Return a generator for the vertices of the polyhedron. + + .. WARNING:: + + If the polyhedron has lines, return a generator for the vertices + of the ``Vrepresentation``. However, the represented polyhedron + has no 0-dimensional faces (i.e. vertices):: + + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) + sage: list(P.vertex_generator()) + [A vertex at (0, 0, 0)] + sage: P.faces(0) + () + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) + sage: for v in triangle.vertex_generator(): print(v) + A vertex at (0, 1) + A vertex at (1, 0) + A vertex at (1, 1) + sage: v_gen = triangle.vertex_generator() + sage: next(v_gen) # the first vertex + A vertex at (0, 1) + sage: next(v_gen) # the second vertex + A vertex at (1, 0) + sage: next(v_gen) # the third vertex + A vertex at (1, 1) + sage: try: next(v_gen) # there are only three vertices + ....: except StopIteration: print("STOP") + STOP + sage: type(v_gen) + <... 'generator'> + sage: [ v for v in triangle.vertex_generator() ] + [A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1)] + """ + for V in self.Vrepresentation(): + if V.is_vertex(): + yield V + + @cached_method + def vertices(self): + """ + Return all vertices of the polyhedron. + + OUTPUT: + + A tuple of vertices. + + .. WARNING:: + + If the polyhedron has lines, return the vertices + of the ``Vrepresentation``. However, the represented polyhedron + has no 0-dimensional faces (i.e. vertices):: + + sage: P = Polyhedron(rays=[[1,0,0]],lines=[[0,1,0]]) + sage: P.vertices() + (A vertex at (0, 0, 0),) + sage: P.faces(0) + () + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices=[[1,0],[0,1],[1,1]]) + sage: triangle.vertices() + (A vertex at (0, 1), A vertex at (1, 0), A vertex at (1, 1)) + sage: a_simplex = Polyhedron(ieqs = [ + ....: [0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1] + ....: ], eqns = [[1,-1,-1,-1,-1]]) + sage: a_simplex.vertices() + (A vertex at (1, 0, 0, 0), A vertex at (0, 1, 0, 0), + A vertex at (0, 0, 1, 0), A vertex at (0, 0, 0, 1)) + """ + return tuple(self.vertex_generator()) + + def ray_generator(self): + """ + Return a generator for the rays of the polyhedron. + + EXAMPLES:: + + sage: pi = Polyhedron(ieqs = [[1,1,0],[1,0,1]]) + sage: pir = pi.ray_generator() + sage: [x.vector() for x in pir] + [(1, 0), (0, 1)] + """ + for V in self.Vrepresentation(): + if V.is_ray(): + yield V + + @cached_method + def rays(self): + """ + Return a list of rays of the polyhedron. + + OUTPUT: + + A tuple of rays. + + EXAMPLES:: + + sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]]) + sage: p.rays() + (A ray in the direction (1, 0, 0), + A ray in the direction (0, 1, 0), + A ray in the direction (0, 0, 1)) + """ + return tuple(self.ray_generator()) + + def rays_list(self): + """ + Return a list of rays as coefficient lists. + + .. NOTE:: + + It is recommended to use :meth:`rays` or + :meth:`ray_generator` instead to iterate over the list of + :class:`Ray` objects. + + OUTPUT: + + A list of rays as lists of coordinates. + + EXAMPLES:: + + sage: p = Polyhedron(ieqs = [[0,0,0,1],[0,0,1,0],[1,1,0,0]]) + sage: p.rays_list() + [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + sage: p.rays_list() == [list(r) for r in p.ray_generator()] + True + """ + return [list(x) for x in self.ray_generator()] + + def line_generator(self): + """ + Return a generator for the lines of the polyhedron. + + EXAMPLES:: + + sage: pr = Polyhedron(rays = [[1,0],[-1,0],[0,1]], vertices = [[-1,-1]]) + sage: next(pr.line_generator()).vector() + (1, 0) + """ + for V in self.Vrepresentation(): + if V.is_line(): + yield V + + @cached_method + def lines(self): + """ + Return all lines of the polyhedron. + + OUTPUT: + + A tuple of lines. + + EXAMPLES:: + + sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]]) + sage: p.lines() + (A line in the direction (1, 0),) + """ + return tuple(self.line_generator()) + + def lines_list(self): + """ + Return a list of lines of the polyhedron. The line data is given + as a list of coordinates rather than as a Hrepresentation object. + + .. NOTE:: + + It is recommended to use :meth:`line_generator` instead to + iterate over the list of :class:`Line` objects. + + EXAMPLES:: + + sage: p = Polyhedron(rays = [[1,0],[-1,0],[0,1],[1,1]], vertices = [[-2,-2],[2,3]]) + sage: p.lines_list() + [[1, 0]] + sage: p.lines_list() == [list(x) for x in p.line_generator()] + True + """ + return [list(x) for x in self.line_generator()] + + def ambient_dim(self): + r""" + Return the dimension of the ambient space. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.ambient_dim() + 4 + """ + return self.parent().ambient_dim() + + def dim(self): + """ + Return the dimension of the polyhedron. + + OUTPUT: + + -1 if the polyhedron is empty, otherwise a non-negative integer. + + EXAMPLES:: + + sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) + sage: simplex.dim() + 3 + sage: simplex.ambient_dim() + 4 + + The empty set is a special case (:trac:`12193`):: + + sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) + sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) + sage: P12 = P1.intersection(P2) + sage: P12 + The empty polyhedron in ZZ^3 + sage: P12.dim() + -1 + """ + if self.n_Vrepresentation() == 0: + return -1 # the empty set + else: + return self.ambient_dim() - self.n_equations() + + dimension = dim + + def base_ring(self): + """ + Return the base ring. + + OUTPUT: + + The ring over which the polyhedron is defined. Must be a + sub-ring of the reals to define a polyhedron, in particular + comparison must be defined. Popular choices are + + * ``ZZ`` (the ring of integers, lattice polytope), + + * ``QQ`` (exact arithmetic using gmp), + + * ``RDF`` (double precision floating-point arithmetic), or + + * ``AA`` (real algebraic field). + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices = [[1,0],[0,1],[1,1]]) + sage: triangle.base_ring() == ZZ + True + """ + return self.parent().base_ring() + + def backend(self): + """ + Return the backend used. + + OUTPUT: + + The name of the backend used for computations. It will be one of + the following backends: + + * ``ppl`` the Parma Polyhedra Library + + * ``cdd`` CDD + + * ``normaliz`` normaliz + + * ``polymake`` polymake + + * ``field`` a generic Sage implementation + + EXAMPLES:: + + sage: triangle = Polyhedron(vertices = [[1, 0], [0, 1], [1, 1]]) + sage: triangle.backend() + 'ppl' + sage: D = polytopes.dodecahedron() + sage: D.backend() + 'field' + sage: P = Polyhedron([[1.23]]) + sage: P.backend() + 'cdd' + """ + return self.parent().backend() From 0505175110576f1f333675f996c874f4d905de4f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 09:24:55 -0700 Subject: [PATCH 188/378] tox.ini: Reduce envlist to a few platforms for 'tox -p auto' --- tox.ini | 106 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/tox.ini b/tox.ini index 8c5301eb28e..69c79015727 100644 --- a/tox.ini +++ b/tox.ini @@ -1,3 +1,6 @@ +# SAGE_ROOT/tox.ini: Environments for testing the Sage distribution +# + # Run a specific environment: # tox -e docker-fedora-31 # Run all in parallel: @@ -5,35 +8,53 @@ # with local squid: # EXTRA_DOCKER_BUILD_ARGS="--build-arg http_proxy=http://host.docker.internal:3128 --build-arg https_proxy=http://host.docker.internal:3128" tox -p auto [tox] -### Test that the system packages listed in debian.txt/fedora.txt files of standard spkg exist -### and satisfy the requirements tested by spkg-configure.m4, then compile a few packages. -### + envlist = - ##### Delegation to src/tox.ini ##### - doctest, coverage, startuptime, pycodestyle-minimal, relint, codespell, - ##### Sage-the-distribution tests ##### + + ##### + ##### Delegation to src/tox.ini + ##### + + # Included on tox -p auto + doctest, + coverage, + startuptime, + pycodestyle-minimal, + relint, + codespell, + + # Also available: + #pycodestyle + + ##### + ##### Sage-the-distribution tests + ##### + check_configure, - ##### Sage-the-distribution portability tests ##### - { - { - ### "docker" toxenvs copy sources from the source tree subject to the exclusions in + + ##### + ##### Sage-the-distribution portability tests + ##### + + # See https://doc.sagemath.org/html/en/developer/portability_testing.html + + ### "docker" environments copy sources from the source tree subject to the exclusions in ### the file ".dockerignore". This should work out of non-clean source trees, and all ### "docker" toxenvs can be run in parallel. - docker-{ubuntu-{trusty,xenial,bionic,latest,rolling,focal,devel}, - debian-{jessie,stretch,buster,bullseye,sid}, - linuxmint-{17,18,19,19.1,19.2,19.3}, - fedora-{26,27,28,29,30,31,32}, - centos-{7,8}, - arch-latest, - conda-forge,conda-anaconda3 - } - -{# https://github.com/docker-library/official-images#architectures-other-than-amd64 - # architectures officially supported by Docker, Inc. for running Docker - amd64,arm32v6,arm32v7,arm64v8, - # windows-amd64 # https://hub.docker.com/u/winamd64/ - # Other architectures built by official images: - # (but not officially supported by Docker, Inc.) - arm32v5,ppc64le,s390x,i386}, + + ### Package factors: + ### + ### - minimal # Install a minimal set of system packages that supports bootstrapping and compiling Sage. + ### - standard # Install all known system packages equivalent to standard packages that have spkg-configure.m4 + ### - maximal # Install all known system packages equivalent to standard/optional packages that have spkg-configure.m4 + + docker-ubuntu-trusty-minimal, + docker-debian-bullseye-standard, + docker-fedora-34-standard, + docker-archlinux-latest-maximal, + docker-manylinux-2_24-i686-standard, + docker-conda-forge-standard, + ### "local" targets should be run from a source tree that is freshly checked out ### (for example, by 'git worktree add ...') or has been cleaned by 'make bdist-clean' -- ### because they build within the source tree (because we have no VPATH support). @@ -74,26 +95,13 @@ envlist = # instead. It may install packages or update packages. It will not remove packages. # Use at your own risk. # - local-homebrew-macos - } - -{### - ### Package factors: - ### - minimal, # Install a minimal set of system packages that supports bootstrapping and compiling Sage. - standard, # Install all known system packages equivalent to standard packages that have spkg-configure.m4 - maximal # Install all known system packages equivalent to standard/optional packages that have spkg-configure.m4 - }, - ### - ### The "local-direct" toxenv passes the whole environment on to the sage build. - ### Whatever is in PATH etc. will be used. - ### - local-direct - } - -{### - ### Configuration factors: - ### - python3_spkg - } + + ### + ### The "local-direct" toxenv passes the whole environment on to the sage build. + ### Whatever is in PATH etc. will be used. + ### + # + # $ tox -e local-direct -- openblas skipsdist = true @@ -308,6 +316,14 @@ setenv = # Many docker images for another architecture are named the same, in the arch prefix. # All work for Docker on Mac; but only i386 works for Linux Docker. # + # According to https://github.com/docker-library/official-images#architectures-other-than-amd64 + # architectures officially supported by Docker, Inc. for running Docker: + # - amd64,arm32v6,arm32v7,arm64v8, + # - windows-amd64 # https://hub.docker.com/u/winamd64/ + # Other architectures built by official images: + # (but not officially supported by Docker, Inc.) + # - arm32v5,ppc64le,s390x,i386 + # arm32v5: ARCH_IMAGE_PREFIX=arm32v5/ arm32v6: ARCH_IMAGE_PREFIX=arm32v6/ arm32v7: ARCH_IMAGE_PREFIX=arm32v7/ From 609815dd15005f428d32cf0f636a5ccfc0e2b298 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 09:25:20 -0700 Subject: [PATCH 189/378] tox.ini (check_configure): Set HOME --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 69c79015727..0fd00cd6850 100644 --- a/tox.ini +++ b/tox.ini @@ -600,6 +600,8 @@ commands = ## Test that configure behaves properly whitelist_externals = bash +setenv = + HOME = {envdir} commands = ./bootstrap bash -c 'test -z "$(./configure --quiet 2>&1)" || (echo >&2 Error: "configure --quiet" is not quiet; exit 1)' From 5392cd7925de2eb58b349b8fcc26b5cf71d46eb3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 09:35:08 -0700 Subject: [PATCH 190/378] tox.ini: Do not include the environments delegated to src/tox.ini in 'tox -p auto' --- tox.ini | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/tox.ini b/tox.ini index 0fd00cd6850..b70188b99bc 100644 --- a/tox.ini +++ b/tox.ini @@ -11,21 +11,6 @@ envlist = - ##### - ##### Delegation to src/tox.ini - ##### - - # Included on tox -p auto - doctest, - coverage, - startuptime, - pycodestyle-minimal, - relint, - codespell, - - # Also available: - #pycodestyle - ##### ##### Sage-the-distribution tests ##### @@ -103,6 +88,25 @@ envlist = # # $ tox -e local-direct -- openblas + + ##### + ##### Delegation to src/tox.ini + ##### + + # included with (cd src && tox -p auto): + # + # doctest, + # coverage, + # startuptime, + # pycodestyle-minimal, + # relint, + # codespell, + # + # Also available: + # + # pycodestyle + + skipsdist = true [testenv] From 47a2b421fb70095a0971d37c39689460c0b16d4c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 10:31:53 -0700 Subject: [PATCH 191/378] tox.ini: Add more examples --- tox.ini | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/tox.ini b/tox.ini index b70188b99bc..eea7ce74624 100644 --- a/tox.ini +++ b/tox.ini @@ -1,12 +1,28 @@ # SAGE_ROOT/tox.ini: Environments for testing the Sage distribution # -# Run a specific environment: -# tox -e docker-fedora-31 -# Run all in parallel: -# tox -p auto +# To run a specific environment: +# +# $ tox -e docker-fedora-31-standard +# +# This will do a complete build of the Sage distribution in a Docker container, which will take a while. +# +# Specific 'make' targets can be given as additional arguments after "--". +# For example, to only run the configuration phase: +# +# $ tox -e docker-debian-bullseye-standard -- config.status +# +# To build a single package (and its dependencies): +# +# $ tox -e docker-manylinux-2_24-i686-standard -- ppl +# +# It can be useful to run several of the environments in parallel. For example: +# +# $ tox -p auto -- config.status +# # with local squid: -# EXTRA_DOCKER_BUILD_ARGS="--build-arg http_proxy=http://host.docker.internal:3128 --build-arg https_proxy=http://host.docker.internal:3128" tox -p auto +# +# $ EXTRA_DOCKER_BUILD_ARGS="--build-arg http_proxy=http://host.docker.internal:3128 --build-arg https_proxy=http://host.docker.internal:3128" tox -p auto -- config.status [tox] envlist = From 0a1b9ac4ac1df59da7d6132bea6824283d71e35c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 08:32:08 -0700 Subject: [PATCH 192/378] src/sage/rings/padics/generic_nodes.py: Remove unused imports --- src/sage/rings/padics/generic_nodes.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/rings/padics/generic_nodes.py b/src/sage/rings/padics/generic_nodes.py index 6262e0b4065..53496a522ec 100644 --- a/src/sage/rings/padics/generic_nodes.py +++ b/src/sage/rings/padics/generic_nodes.py @@ -23,7 +23,6 @@ from sage.rings.padics.local_generic import LocalGeneric from sage.rings.padics.padic_generic import pAdicGeneric -from sage.rings.ring import EuclideanDomain, Field import sage.rings.abc from sage.rings.padics.padic_base_generic import pAdicBaseGeneric from sage.rings.integer_ring import ZZ From 6dfadb810949aa2b2beea63b8fffd29396da0807 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Mon, 25 Oct 2021 21:37:54 +0200 Subject: [PATCH 193/378] leave dim and ambient_dim for convex set --- src/sage/geometry/polyhedron/base.py | 98 ++++++++++++++++++++++++ src/sage/geometry/polyhedron/base0.py | 104 -------------------------- 2 files changed, 98 insertions(+), 104 deletions(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 78abf572793..4e618af342b 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -907,6 +907,59 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, edge_color, facet_color, opacity, vertex_color, axis) + def _repr_(self): + """ + Return a description of the polyhedron. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) + sage: poly_test._repr_() + 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' + sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) + sage: grammar_test._repr_() + 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' + """ + desc = '' + if self.n_vertices() == 0: + desc += 'The empty polyhedron' + else: + desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' + desc += ' in ' + desc += self.parent()._repr_ambient_module() + + if self.n_vertices() > 0: + desc += ' defined as the convex hull of ' + desc += repr(self.n_vertices()) + if self.n_vertices() == 1: + desc += ' vertex' + else: + desc += ' vertices' + + if self.n_rays() > 0: + if self.n_lines() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_rays()) + if self.n_rays() == 1: + desc += ' ray' + else: + desc += ' rays' + + if self.n_lines() > 0: + if self.n_rays() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_lines()) + if self.n_lines() == 1: + desc += ' line' + else: + desc += ' lines' + + return desc + def _rich_repr_(self, display_manager, **kwds): r""" Rich Output Magic Method @@ -1376,6 +1429,51 @@ def bounded_edges(self): continue yield (obj[i], obj[j]) + def ambient_dim(self): + r""" + Return the dimension of the ambient space. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.ambient_dim() + 4 + """ + return self.parent().ambient_dim() + + def dim(self): + """ + Return the dimension of the polyhedron. + + OUTPUT: + + -1 if the polyhedron is empty, otherwise a non-negative integer. + + EXAMPLES:: + + sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) + sage: simplex.dim() + 3 + sage: simplex.ambient_dim() + 4 + + The empty set is a special case (:trac:`12193`):: + + sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) + sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) + sage: P12 = P1.intersection(P2) + sage: P12 + The empty polyhedron in ZZ^3 + sage: P12.dim() + -1 + """ + if self.n_Vrepresentation() == 0: + return -1 # the empty set + else: + return self.ambient_dim() - self.n_equations() + + dimension = dim + def Vrepresentation_space(self): r""" Return the ambient free module. diff --git a/src/sage/geometry/polyhedron/base0.py b/src/sage/geometry/polyhedron/base0.py index fe66d0dcd74..21c22c4f4aa 100644 --- a/src/sage/geometry/polyhedron/base0.py +++ b/src/sage/geometry/polyhedron/base0.py @@ -45,8 +45,6 @@ class Polyhedron_base0(Element): sage: from sage.geometry.polyhedron.base0 import Polyhedron_base0 sage: P = Polyhedron(rays=[[1, 0, 0]], lines=[[0, 1, 0]]) - sage: Polyhedron_base0.__repr__(P) - 'A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 1 vertex, 1 ray, 1 line' sage: Polyhedron_base0.Vrepresentation(P) (A line in the direction (0, 1, 0), A vertex at (0, 0, 0), @@ -67,10 +65,6 @@ class Polyhedron_base0(Element): Integer Ring sage: Polyhedron_base0.backend(P) 'ppl' - sage: Polyhedron_base0.dim(P) - 2 - sage: Polyhedron_base0.ambient_dim(P) - 3 sage: Polyhedron_base0.change_ring(P, ZZ, backend='field').backend() 'field' sage: Polyhedron_base0.base_extend(P, QQ) @@ -409,59 +403,6 @@ def is_immutable(self): """ return True - def _repr_(self): - """ - Return a description of the polyhedron. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) - sage: poly_test._repr_() - 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' - sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) - sage: grammar_test._repr_() - 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' - """ - desc = '' - if self.n_vertices() == 0: - desc += 'The empty polyhedron' - else: - desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' - desc += ' in ' - desc += self.parent()._repr_ambient_module() - - if self.n_vertices() > 0: - desc += ' defined as the convex hull of ' - desc += repr(self.n_vertices()) - if self.n_vertices() == 1: - desc += ' vertex' - else: - desc += ' vertices' - - if self.n_rays() > 0: - if self.n_lines() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_rays()) - if self.n_rays() == 1: - desc += ' ray' - else: - desc += ' rays' - - if self.n_lines() > 0: - if self.n_rays() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_lines()) - if self.n_lines() == 1: - desc += ' line' - else: - desc += ' lines' - - return desc - @cached_method def n_equations(self): """ @@ -1177,51 +1118,6 @@ def lines_list(self): """ return [list(x) for x in self.line_generator()] - def ambient_dim(self): - r""" - Return the dimension of the ambient space. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.ambient_dim() - 4 - """ - return self.parent().ambient_dim() - - def dim(self): - """ - Return the dimension of the polyhedron. - - OUTPUT: - - -1 if the polyhedron is empty, otherwise a non-negative integer. - - EXAMPLES:: - - sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) - sage: simplex.dim() - 3 - sage: simplex.ambient_dim() - 4 - - The empty set is a special case (:trac:`12193`):: - - sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) - sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) - sage: P12 = P1.intersection(P2) - sage: P12 - The empty polyhedron in ZZ^3 - sage: P12.dim() - -1 - """ - if self.n_Vrepresentation() == 0: - return -1 # the empty set - else: - return self.ambient_dim() - self.n_equations() - - dimension = dim - def base_ring(self): """ Return the base ring. From bed7308f0d57dc8e4d1c052121217a07156fc888 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 14:21:08 -0700 Subject: [PATCH 194/378] src/sage/geometry/polyhedron/base.py: Remove stray character --- src/sage/geometry/polyhedron/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 81f8e630e2a..7de1c996072 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -40,7 +40,7 @@ from sage.misc.misc_c import prod from sage.misc.randstate import current_randstate from sage.misc.superseded import deprecated_function_alias -y + from sage.rings.integer_ring import ZZ from sage.rings.qqbar import AA from sage.rings.rational_field import QQ From 4d53db6ae0e675865c6b4649a1b6fecaacda7db3 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 14:42:52 -0700 Subject: [PATCH 195/378] src/sage/categories/coxeter_groups.py: Remove module-level import from sage.graphs --- src/sage/categories/coxeter_groups.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index 70a20541ed7..f480095041a 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -22,7 +22,6 @@ from sage.categories.generalized_coxeter_groups import GeneralizedCoxeterGroups from sage.structure.element import have_same_parent, parent from sage.misc.flatten import flatten -from sage.graphs.digraph import DiGraph from sage.rings.integer_ring import ZZ from copy import copy from collections import deque @@ -2943,6 +2942,6 @@ def kazhdan_lusztig_cell(self, side='left'): vertices.add(y) queue.appendleft(y) + from sage.graphs.digraph import DiGraph g = DiGraph([list(vertices), list(edges)]) return set(g.strongly_connected_component_containing_vertex(w)) - From 86aec7339484f10ee040fb4650209dd65a79f97d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 14:50:03 -0700 Subject: [PATCH 196/378] src/sage/categories/coxeter_groups.py: Move import of ZZ into method --- src/sage/categories/coxeter_groups.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/categories/coxeter_groups.py b/src/sage/categories/coxeter_groups.py index f480095041a..6660829d005 100644 --- a/src/sage/categories/coxeter_groups.py +++ b/src/sage/categories/coxeter_groups.py @@ -22,7 +22,6 @@ from sage.categories.generalized_coxeter_groups import GeneralizedCoxeterGroups from sage.structure.element import have_same_parent, parent from sage.misc.flatten import flatten -from sage.rings.integer_ring import ZZ from copy import copy from collections import deque @@ -2912,6 +2911,7 @@ def kazhdan_lusztig_cell(self, side='left'): """ from sage.algebras.iwahori_hecke_algebra import IwahoriHeckeAlgebra from sage.rings.polynomial.laurent_polynomial_ring import LaurentPolynomialRing + from sage.rings.integer_ring import ZZ R = LaurentPolynomialRing(ZZ, 'v') v = R.gen(0) From 16d28509023cd429a4fd82a9ba3aec6037868244 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 15:25:38 -0700 Subject: [PATCH 197/378] src/sage/libs/pari/convert_sage_complex_double.pxd (pari_to_cdf): cdef inline -> cpdef --- src/sage/libs/pari/convert_sage_complex_double.pxd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/libs/pari/convert_sage_complex_double.pxd b/src/sage/libs/pari/convert_sage_complex_double.pxd index ded6cce2221..ebb3640c68b 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pxd +++ b/src/sage/libs/pari/convert_sage_complex_double.pxd @@ -1,6 +1,6 @@ from cypari2.gen cimport Gen from sage.rings.complex_double cimport ComplexDoubleElement -cdef inline ComplexDoubleElement pari_to_cdf(Gen g) +cpdef ComplexDoubleElement pari_to_cdf(Gen g) cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self) From 078cc56af53928090a86d4dbd00633565a3b4676 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 16:17:55 -0700 Subject: [PATCH 198/378] src/sage/geometry/polyhedron/base.py: Remove unused import --- src/sage/geometry/polyhedron/base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 4e618af342b..e3d4346bc7a 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -39,7 +39,6 @@ from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod from sage.misc.randstate import current_randstate -from sage.misc.superseded import deprecated_function_alias from sage.rings.integer_ring import ZZ from sage.rings.qqbar import AA From 33a2e7bc53d3eb3f23e80e6a8208b4e1608b82c0 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 25 Oct 2021 18:45:20 -0700 Subject: [PATCH 199/378] src/sage/geometry/polyhedron/base.py: Fix up imports --- src/sage/geometry/polyhedron/base.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 7de1c996072..085c117a087 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -50,6 +50,7 @@ from sage.matrix.constructor import matrix from sage.arith.misc import integer_floor as floor from sage.arith.misc import integer_ceil as ceil +from sage.misc.lazy_import import lazy_import lazy_import('sage.groups.matrix_gps.finitely_generated', 'MatrixGroup') from sage.geometry.convex_set import ConvexSet_closed, AffineHullProjectionData @@ -10537,6 +10538,7 @@ def edge_label(i, j, c_ij): Qplus = sum(v.column() * v.row() for v in V).pseudoinverse() # Construct the graph. + from sage.graphs.graph import Graph G = Graph() for i in range(len(V)): for j in range(i+1, len(V)): From 03b24bdbb76455c91cbda1815649eb44e8755c0b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 00:42:19 -0700 Subject: [PATCH 200/378] src/sage/schemes/berkovich/berkovich_space.py: Whitespace fix --- src/sage/schemes/berkovich/berkovich_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/berkovich/berkovich_space.py b/src/sage/schemes/berkovich/berkovich_space.py index 82ba2c17fd6..35c6dd05688 100644 --- a/src/sage/schemes/berkovich/berkovich_space.py +++ b/src/sage/schemes/berkovich/berkovich_space.py @@ -440,7 +440,7 @@ def __init__(self, base, ideal=None): if not ideal.is_prime(): raise ValueError('passed non prime ideal') self._base_type = 'number field' - elif isinstance(base, sage.rings.abc.pAdicField): # change base to Qpbar + elif isinstance(base, sage.rings.abc.pAdicField): # change base to Qpbar prime = base.prime() ideal = None self._base_type = 'padic field' From 0e87ca6f55ff486e28953dd80fb1dca747000037 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 11:17:08 +0200 Subject: [PATCH 201/378] fix incorrect doctest from #29978 --- src/sage/modules/free_module_integer.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/modules/free_module_integer.py b/src/sage/modules/free_module_integer.py index a1e8a05fb50..66d4db2f9df 100644 --- a/src/sage/modules/free_module_integer.py +++ b/src/sage/modules/free_module_integer.py @@ -364,10 +364,10 @@ def LLL(self, *args, **kwds): ... sage: L.reduced_basis == A True - sage: old_min = min(v.norm().n() for v in L.reduced_basis) + sage: old = L.reduced_basis[0].norm().n() sage: _ = L.LLL() - sage: new_min = L.reduced_basis[0].norm().n() - sage: new_min <= old_min + sage: new = L.reduced_basis[0].norm().n() + sage: new <= old True """ basis = self.reduced_basis From 50e4c8dba0363f84c3fcd44231b889b6dffed28c Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 11:41:14 +0200 Subject: [PATCH 202/378] fix two test failures for graphs --- src/sage/graphs/base/sparse_graph.pyx | 6 ++++-- src/sage/graphs/generators/families.py | 10 +++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sage/graphs/base/sparse_graph.pyx b/src/sage/graphs/base/sparse_graph.pyx index 19006ceb808..b606a9aa0d1 100644 --- a/src/sage/graphs/base/sparse_graph.pyx +++ b/src/sage/graphs/base/sparse_graph.pyx @@ -1167,8 +1167,10 @@ def _test_adjacency_sequence_out(): from sage.misc.prandom import randint, random low = 0 high = 1000 - randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random())) - n = randg.order() + n = 0 + while not n: + randg = DiGraph(GraphGenerators().RandomGNP(randint(low, high), random())) + n = randg.order() # set all labels to 0 E = [(u, v, 0) for u, v in randg.edges(labels=False)] cdef SparseGraph g = SparseGraph(n, diff --git a/src/sage/graphs/generators/families.py b/src/sage/graphs/generators/families.py index 91003aae159..12975b1d9f0 100644 --- a/src/sage/graphs/generators/families.py +++ b/src/sage/graphs/generators/families.py @@ -1171,7 +1171,7 @@ def CubeGraph(n, embedding=1): vertices in each column represents rows in Pascal's triangle. See for instance the :wikipedia:`10-cube` for more details. - - ``None`` or ``O``: no embedding is provided + - ``None`` or ``O``: no embedding is provided EXAMPLES: @@ -1268,7 +1268,7 @@ def CubeGraph(n, embedding=1): for u, d in G.breadth_first_search(s, report_distance=True): L[d].append(u) - p = G._circle_embedding(list(range(2*n)), radius=(n + 1)//2, angle=pi, return_dict=True) + p = G._circle_embedding(list(range(2*n)), radius=(n + 1)//2, angle=pi, return_dict=True) for i in range(n + 1): y = p[i][1] / 1.5 G._line_embedding(L[i], first=(i, y), last=(i, -y), return_dict=False) @@ -1462,11 +1462,11 @@ def FriendshipGraph(n): sage: G.is_isomorphic(graphs.ButterflyGraph()) True - If `n \geq 1`, then the friendship graph `F_n` has `2n + 1` vertices + If `n \geq 2`, then the friendship graph `F_n` has `2n + 1` vertices and `3n` edges. It has radius 1, diameter 2, girth 3, and chromatic number 3. Furthermore, `F_n` is planar and Eulerian. :: - sage: n = randint(1, 10^3) + sage: n = randint(2, 10^3) sage: G = graphs.FriendshipGraph(n) sage: G.order() == 2*n + 1 True @@ -4016,7 +4016,7 @@ def CubeConnectedCycle(d): For each vertex, `(x,y)`, add an edge between it and `(x, (y-1) \mod d))`, `(x,(y+1) \mod d)`, and `(x \oplus 2^y, y)`, where `\oplus` is the bitwise xor operator. - + For `d=1` and `2`, the cube-connected cycle graph contains self-loops or multiple edges between a pair of vertices, but for all other `d`, it is simple. From fcf0f142e3e43f113ee359ef0d7821176f09cb98 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 12:20:24 +0200 Subject: [PATCH 203/378] fix doctest of rat_interval_cf_list --- src/sage/rings/continued_fraction.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index cf5f8b1f9eb..ce55ac87867 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -268,6 +268,8 @@ def rat_interval_cf_list(r1, r2): ....: x = R.random_element() * R.random_element() + R.random_element() / 100 ....: l = x.lower().exact_rational() ....: u = x.upper().exact_rational() + ....: if l.floor() != u.floor(): + ....: continue ....: cf = rat_interval_cf_list(l,u) ....: a = continued_fraction(cf).value() ....: b = continued_fraction(cf+[1]).value() From 388b05f54be5419a1c0f68c765a6e6064301e1ac Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 13:53:11 +0200 Subject: [PATCH 204/378] speed up conversion for complex double --- .../libs/pari/convert_sage_complex_double.pxd | 7 ++ .../libs/pari/convert_sage_complex_double.pyx | 69 +++++++++++++++++++ src/sage/rings/complex_double.pyx | 46 +++++++++++-- 3 files changed, 115 insertions(+), 7 deletions(-) diff --git a/src/sage/libs/pari/convert_sage_complex_double.pxd b/src/sage/libs/pari/convert_sage_complex_double.pxd index ebb3640c68b..51299d77759 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pxd +++ b/src/sage/libs/pari/convert_sage_complex_double.pxd @@ -4,3 +4,10 @@ from sage.rings.complex_double cimport ComplexDoubleElement cpdef ComplexDoubleElement pari_to_cdf(Gen g) cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self) + +cpdef ComplexDoubleElement complex_double_element_eta(ComplexDoubleElement self, int flag) +cpdef ComplexDoubleElement complex_double_element_agm(ComplexDoubleElement self, right) +cpdef ComplexDoubleElement complex_double_element_dilog(ComplexDoubleElement self) +cpdef ComplexDoubleElement complex_double_element_gamma(ComplexDoubleElement self) +cpdef ComplexDoubleElement complex_double_element_gamma_inc(ComplexDoubleElement self, t) +cpdef ComplexDoubleElement complex_double_element_zeta(ComplexDoubleElement self) diff --git a/src/sage/libs/pari/convert_sage_complex_double.pyx b/src/sage/libs/pari/convert_sage_complex_double.pyx index 5a04aff7f6e..d9b1f4a6a28 100644 --- a/src/sage/libs/pari/convert_sage_complex_double.pyx +++ b/src/sage/libs/pari/convert_sage_complex_double.pyx @@ -58,3 +58,72 @@ cpdef Gen new_gen_from_complex_double_element(ComplexDoubleElement self): return new_gen_from_double(self._complex.real) else: return new_t_COMPLEX_from_double(self._complex.real, self._complex.imag) + + +cpdef ComplexDoubleElement complex_double_element_eta(ComplexDoubleElement self, int flag): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_eta + sage: a = CDF(1,1) + sage: complex_double_element_eta(a, 0) + 0.9981290699259585 + sage: complex_double_element_eta(a, 1) + 0.7420487758365647 + 0.1988313702299107*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).eta(flag)) + + +cpdef ComplexDoubleElement complex_double_element_agm(ComplexDoubleElement self, right): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_agm + sage: complex_double_element_agm(CDF(1, 1), CDF(2, 2)) + 1.4567910310469068 + 1.4567910310469068*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).agm(right)) + + +cpdef ComplexDoubleElement complex_double_element_dilog(ComplexDoubleElement self): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_dilog + sage: complex_double_element_dilog(CDF(1, 1)) + 0.6168502750680849 + 1.4603621167531196*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).dilog()) + + +cpdef ComplexDoubleElement complex_double_element_gamma(ComplexDoubleElement self): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_gamma + sage: complex_double_element_gamma(CDF(1, 1)) + 0.49801566811835607 - 0.15494982830181067*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).gamma()) + + +cpdef ComplexDoubleElement complex_double_element_gamma_inc(ComplexDoubleElement self, t): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_gamma_inc + sage: complex_double_element_gamma_inc(CDF(1, 1), CDF(2, 2)) + 0.054695987717541285 - 0.04676800059213122*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).incgam(t)) + + +cpdef ComplexDoubleElement complex_double_element_zeta(ComplexDoubleElement self): + """ + TESTS:: + + sage: from sage.libs.pari.convert_sage_complex_double import complex_double_element_zeta + sage: complex_double_element_zeta(CDF(1, 2)) + 0.5981655697623818 - 0.35185474521784527*I + """ + return pari_to_cdf(new_gen_from_complex_double_element(self).zeta()) diff --git a/src/sage/rings/complex_double.pyx b/src/sage/rings/complex_double.pyx index ecc326b4396..5f4e1ec0585 100644 --- a/src/sage/rings/complex_double.pyx +++ b/src/sage/rings/complex_double.pyx @@ -96,6 +96,16 @@ try: except ImportError: pari_gen = () + +new_gen_from_complex_double_element = None +complex_double_element_eta = None +complex_double_element_agm = None +complex_double_element_dilog = None +complex_double_element_gamma = None +complex_double_element_gamma_inc = None +complex_double_element_zeta = None + + from . import complex_mpfr from .complex_mpfr import ComplexField @@ -1140,7 +1150,9 @@ cdef class ComplexDoubleElement(FieldElement): sage: pari(CDF(I)) 1.00000000000000*I """ - from sage.libs.pari.convert_sage_complex_double import new_gen_from_complex_double_element + global new_gen_from_complex_double_element + if new_gen_from_complex_double_element is None: + from sage.libs.pari.convert_sage_complex_double import new_gen_from_complex_double_element return new_gen_from_complex_double_element(self) def __mpc__(self): @@ -2241,8 +2253,12 @@ cdef class ComplexDoubleElement(FieldElement): # this, PARI can easily underflow. return ComplexDoubleElement(0,0) + global complex_double_element_eta + if complex_double_element_eta is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_eta + cdef int flag = 0 if omit_frac else 1 - return pari_to_cdf(self.__pari__().eta(flag)) + return complex_double_element_eta(self, flag) def agm(self, right, algorithm="optimal"): r""" @@ -2307,7 +2323,10 @@ cdef class ComplexDoubleElement(FieldElement): cdef double d, e, eps = 2.0**-51 if algorithm == "pari": - return pari_to_cdf(self.__pari__().agm(right)) + global complex_double_element_agm + if complex_double_element_agm is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_agm + return complex_double_element_agm(self, right) if not isinstance(right, ComplexDoubleElement): right = CDF(right) @@ -2357,7 +2376,10 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(10000000,10000000).dilog() -134.411774490731 + 38.79396299904504*I """ - return pari_to_cdf(self.__pari__().dilog()) + global complex_double_element_dilog + if complex_double_element_dilog is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_dilog + return complex_double_element_dilog(self) def gamma(self): r""" @@ -2385,7 +2407,10 @@ cdef class ComplexDoubleElement(FieldElement): return CC(self).gamma() except TypeError: pass - return pari_to_cdf(self.__pari__().gamma()) + global complex_double_element_gamma + if complex_double_element_gamma is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_gamma + return complex_double_element_gamma(self) def gamma_inc(self, t): r""" @@ -2400,7 +2425,10 @@ cdef class ComplexDoubleElement(FieldElement): sage: CDF(2,0).gamma_inc(CDF(1,1)) 0.7070920963459381 - 0.4203536409598115*I """ - return pari_to_cdf(self.__pari__().incgam(t)) + global complex_double_element_gamma_inc + if complex_double_element_gamma_inc is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_gamma_inc + return complex_double_element_gamma_inc(self, t) def zeta(self): """ @@ -2419,7 +2447,11 @@ cdef class ComplexDoubleElement(FieldElement): if self._complex.real == 1 and self._complex.imag == 0: from .infinity import unsigned_infinity return unsigned_infinity - return pari_to_cdf(self.__pari__().zeta()) + + global complex_double_element_zeta + if complex_double_element_zeta is None: + from sage.libs.pari.convert_sage_complex_double import complex_double_element_zeta + return complex_double_element_zeta(self) def algdep(self, long n): """ From a64d72b83610b2de1efaed05deaf18d879a78001 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 13:56:29 +0200 Subject: [PATCH 205/378] speed up conversion from real double --- src/sage/rings/real_double.pyx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/real_double.pyx b/src/sage/rings/real_double.pyx index 2125d431c98..ca8b888104f 100644 --- a/src/sage/rings/real_double.pyx +++ b/src/sage/rings/real_double.pyx @@ -71,6 +71,9 @@ from sage.arith.constants cimport * cimport gmpy2 +new_gen_from_real_double_element = None + + def is_RealDoubleField(x): """ Returns ``True`` if ``x`` is the field of real double precision numbers. @@ -1677,7 +1680,9 @@ cdef class RealDoubleElement(FieldElement): sage: RDF(1.5).__pari__() 1.50000000000000 """ - from sage.libs.pari.convert_sage_real_double import new_gen_from_real_double_element + global new_gen_from_real_double_element + if new_gen_from_real_double_element is None: + from sage.libs.pari.convert_sage_real_double import new_gen_from_real_double_element return new_gen_from_real_double_element(self) From 33e6c65fa0b359693e29fce746961c38615ec037 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 14:21:41 +0200 Subject: [PATCH 206/378] improve conversion rational <-> pari --- src/sage/rings/rational.pyx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/rational.pyx b/src/sage/rings/rational.pyx index 6e02cf4387d..0fea3b02145 100644 --- a/src/sage/rings/rational.pyx +++ b/src/sage/rings/rational.pyx @@ -110,6 +110,10 @@ except ImportError: pari_gen = () +set_rational_from_gen = None +new_gen_from_rational = None + + cdef sage.rings.fast_arith.arith_int ai ai = sage.rings.fast_arith.arith_int() @@ -650,7 +654,9 @@ cdef class Rational(sage.structure.element.FieldElement): mpq_canonicalize(self.value) elif isinstance(x, pari_gen): - from sage.libs.pari.convert_sage import set_rational_from_gen + global set_rational_from_gen + if set_rational_from_gen is None: + from sage.libs.pari.convert_sage import set_rational_from_gen set_rational_from_gen(self, x) elif isinstance(x, list) and len(x) == 1: @@ -3777,7 +3783,9 @@ cdef class Rational(sage.structure.element.FieldElement): sage: m.type() 't_FRAC' """ - from sage.libs.pari.convert_sage import new_gen_from_rational + global new_gen_from_rational + if new_gen_from_rational is None: + from sage.libs.pari.convert_sage import new_gen_from_rational return new_gen_from_rational(self) def _interface_init_(self, I=None): From 1589f9457592c666431ccc7cda340bb078a4b8cc Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 14:45:54 +0200 Subject: [PATCH 207/378] improve conversion integer <-> pari --- src/sage/rings/integer.pyx | 71 +++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 24 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index 56de0fc858a..fefe92b7d02 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -198,6 +198,15 @@ except ImportError: pari_gen = () +set_integer_from_pari_gen = None +pari_divisors_small = None +n_factor_to_list = None +pari_is_prime_power = None +pari_is_prime = None +objtogen = None +new_gen_from_integer = None + + cdef extern from *: int unlikely(int) nogil # Defined by Cython @@ -637,7 +646,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise TypeError("Cannot convert non-integral float to integer") elif isinstance(x, pari_gen): - from sage.libs.pari.convert_sage import set_integer_from_gen + global set_integer_from_pari_gen + if set_integer_from_pari_gen is None: + from sage.libs.pari.convert_sage import set_integer_from_gen set_integer_from_gen(self, x) else: @@ -3046,12 +3057,14 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise ValueError("n must be nonzero") if (method is None or method == 'pari') and mpz_fits_slong_p(self.value): - try: - from sage.libs.pari.convert_sage import pari_divisors_small - except ImportError: - if method == 'pari': - raise ImportError("method `pari` requested, but cypari2 not present") - else: + global pari_divisors_small + if pari_divisors_small is None: + try: + from sage.libs.pari.convert_sage import pari_divisors_small + except ImportError: + if method == 'pari': + raise ImportError("method `pari` requested, but cypari2 not present") + if pari_divisors_small is not None: if mpz_sgn(self.value) > 0: return pari_divisors_small(self) else: @@ -3909,11 +3922,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return factor_trial_division(self, limit) if mpz_fits_slong_p(n.value): - try: - from sage.libs.flint.ulong_extras import n_factor_to_list - except ImportError: - pass - else: + global n_factor_to_list + if n_factor_to_list is None: + try: + from sage.libs.flint.ulong_extras import n_factor_to_list + except ImportError: + pass + if n_factor_to_list is not None: if proof is None: from sage.structure.proof.proof import get_flag proof = get_flag(proof, "arithmetic") @@ -5108,11 +5123,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return (self, zero) if get_data else False if mpz_fits_slong_p(self.value): - try: - from sage.libs.pari.convert_sage import pari_is_prime_power - except ImportError: - pass - else: + global pari_is_prime_power + if pari_is_prime_power is None: + try: + from sage.libs.pari.convert_sage import pari_is_prime_power + except ImportError: + pass + if pari_is_prime_power is not None: return pari_is_prime_power(self, get_data) cdef long n @@ -5194,11 +5211,13 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): return False if mpz_fits_ulong_p(self.value): - try: - from sage.libs.pari.convert_sage import pari_is_prime - except ImportError: - pass - else: + global pari_is_prime + if pari_is_prime is None: + try: + from sage.libs.pari.convert_sage import pari_is_prime + except ImportError: + pass + if pari_is_prime is not None: return pari_is_prime(self) if proof is None: @@ -5550,7 +5569,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): """ - from cypari2.gen import objtogen + global objtogen + if objtogen is None: + from cypari2.gen import objtogen if self.is_square(): raise ValueError("class_number not defined for square integers") if not self%4 in [0,1]: @@ -5958,7 +5979,9 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): 1041334 """ - from sage.libs.pari.convert_sage import new_gen_from_integer + global new_gen_from_integer + if new_gen_from_integer is None: + from sage.libs.pari.convert_sage import new_gen_from_integer return new_gen_from_integer(self) def _interface_init_(self, I=None): From 7bd6ce4f39bb8e3a94ba59eaf064044a1e02b9ee Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Tue, 26 Oct 2021 16:16:11 +0200 Subject: [PATCH 208/378] Partly revert "Enable editable mode also for other sage packages" This partly reverts commit b9b1dba57d85ea7d6f68471024406a939579b5bb. --- build/pkgs/sagelib/spkg-install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sagelib/spkg-install b/build/pkgs/sagelib/spkg-install index 050af61a140..76a306e5762 100755 --- a/build/pkgs/sagelib/spkg-install +++ b/build/pkgs/sagelib/spkg-install @@ -49,7 +49,7 @@ if [ "$SAGE_EDITABLE" = yes ]; then # and renamed the distribution to "sagemath-standard"). There is no clean way to uninstall # them, so we just use rm. (cd "$SITEPACKAGESDIR" && rm -rf sage sage_setup sage-[1-9]*.egg-info sage-[1-9]*.dist-info) - time sdh_pip_editable_install . || exit 1 + time python3 -m pip install --verbose --no-deps --no-index --no-build-isolation --isolated --editable . || exit 1 else # Likewise, we should remove the egg-link that may have been installed previously. (cd "$SITEPACKAGESDIR" && rm -f sagemath-standard.egg-link) From f0121c596134a37152a3c9b42d05e2d8cc25e6c3 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Tue, 26 Oct 2021 16:28:02 +0200 Subject: [PATCH 209/378] outsource convex set methods to base1.py --- src/sage/geometry/polyhedron/base.py | 723 +---------------------- src/sage/geometry/polyhedron/base1.py | 802 ++++++++++++++++++++++++++ 2 files changed, 806 insertions(+), 719 deletions(-) create mode 100644 src/sage/geometry/polyhedron/base1.py diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index e3d4346bc7a..c3d760ab1cc 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -50,11 +50,10 @@ from sage.functions.other import sqrt, floor, ceil from sage.groups.matrix_gps.finitely_generated import MatrixGroup from sage.graphs.graph import Graph -from sage.geometry.convex_set import ConvexSet_closed, AffineHullProjectionData +from sage.geometry.convex_set import AffineHullProjectionData from .constructor import Polyhedron -from .base0 import Polyhedron_base0 -from sage.geometry.relative_interior import RelativeInterior +from .base1 import Polyhedron_base1 from sage.categories.sets_cat import EmptySetError ######################################################################### @@ -100,7 +99,7 @@ def is_Polyhedron(X): ######################################################################### -class Polyhedron_base(Polyhedron_base0, ConvexSet_closed): +class Polyhedron_base(Polyhedron_base1): """ Base class for Polyhedron objects @@ -184,7 +183,7 @@ def _init_empty_polyhedron(self): sage: Polyhedron().facet_adjacency_matrix() [0] """ - Polyhedron_base0._init_empty_polyhedron(self) + Polyhedron_base1._init_empty_polyhedron(self) V_matrix = matrix(ZZ, 0, 0, 0) V_matrix.set_immutable() @@ -194,32 +193,6 @@ def _init_empty_polyhedron(self): H_matrix.set_immutable() self.facet_adjacency_matrix.set_cache(H_matrix) - def __hash__(self): - r""" - TESTS:: - - sage: K. = QuadraticField(2) - sage: p = Polyhedron(vertices=[(0,1,a),(3,a,5)], - ....: rays=[(a,2,3), (0,0,1)], - ....: base_ring=K) - sage: q = Polyhedron(vertices=[(3,a,5),(0,1,a)], - ....: rays=[(0,0,1), (a,2,3)], - ....: base_ring=K) - sage: hash(p) == hash(q) - True - """ - # TODO: find something better *but* fast - return hash((self.dim(), - self.ambient_dim(), - self.n_Hrepresentation(), - self.n_Vrepresentation(), - self.n_equations(), - self.n_facets(), - self.n_inequalities(), - self.n_lines(), - self.n_rays(), - self.n_vertices())) - def _sage_input_(self, sib, coerced): """ Return Sage command to reconstruct ``self``. @@ -906,59 +879,6 @@ def tikz(self, view=[0, 0, 1], angle=0, scale=1, edge_color, facet_color, opacity, vertex_color, axis) - def _repr_(self): - """ - Return a description of the polyhedron. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) - sage: poly_test._repr_() - 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' - sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) - sage: grammar_test._repr_() - 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' - """ - desc = '' - if self.n_vertices() == 0: - desc += 'The empty polyhedron' - else: - desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' - desc += ' in ' - desc += self.parent()._repr_ambient_module() - - if self.n_vertices() > 0: - desc += ' defined as the convex hull of ' - desc += repr(self.n_vertices()) - if self.n_vertices() == 1: - desc += ' vertex' - else: - desc += ' vertices' - - if self.n_rays() > 0: - if self.n_lines() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_rays()) - if self.n_rays() == 1: - desc += ' ray' - else: - desc += ' rays' - - if self.n_lines() > 0: - if self.n_rays() > 0: - desc += ", " - else: - desc += " and " - desc += repr(self.n_lines()) - if self.n_lines() == 1: - desc += ' line' - else: - desc += ' lines' - - return desc - def _rich_repr_(self, display_manager, **kwds): r""" Rich Output Magic Method @@ -1316,91 +1236,6 @@ def vertices_matrix(self, base_ring=None): m.set_immutable() return m - def an_affine_basis(self): - """ - Return points in ``self`` that are a basis for the affine span of the polytope. - - This implementation of the method :meth:`ConvexSet_base.an_affine_basis` - for polytopes guarantees the following: - - - All points are vertices. - - - The basis is obtained by considering a maximal chain of faces - in the face lattice and picking for each cover relation - one vertex that is in the difference. Thus this method - is independent of the concrete realization of the polytope. - - EXAMPLES:: - - sage: P = polytopes.cube() - sage: P.an_affine_basis() - [A vertex at (-1, -1, -1), - A vertex at (1, -1, -1), - A vertex at (1, -1, 1), - A vertex at (1, 1, -1)] - - sage: P = polytopes.permutahedron(5) - sage: P.an_affine_basis() - [A vertex at (1, 2, 3, 5, 4), - A vertex at (2, 1, 3, 5, 4), - A vertex at (1, 3, 2, 5, 4), - A vertex at (4, 1, 3, 5, 2), - A vertex at (4, 2, 5, 3, 1)] - - The method is not implemented for unbounded polyhedra:: - - sage: p = Polyhedron(vertices=[(0,0)],rays=[(1,0),(0,1)]) - sage: p.an_affine_basis() - Traceback (most recent call last): - ... - NotImplementedError: this function is not implemented for unbounded polyhedra - """ - if not self.is_compact(): - raise NotImplementedError("this function is not implemented for unbounded polyhedra") - - chain = self.a_maximal_chain()[1:] # we exclude the empty face - chain_indices = [face.ambient_V_indices() for face in chain] - basis_indices = [] - - # We use in the following that elements in ``chain_indices`` are sorted lists - # of V-indices. - # Thus for each two faces we can easily find the first vertex that differs. - for dim, face in enumerate(chain_indices): - if dim == 0: - # Append the vertex. - basis_indices.append(face[0]) - continue - - prev_face = chain_indices[dim-1] - for i in range(len(prev_face)): - if prev_face[i] != face[i]: - # We found a vertex that ``face`` has, but its facet does not. - basis_indices.append(face[i]) - break - else: # no break - # ``prev_face`` contains all the same vertices as ``face`` until now. - # But ``face`` is guaranteed to contain one more vertex (at least). - basis_indices.append(face[len(prev_face)]) - - return [self.Vrepresentation()[i] for i in basis_indices] - - def _test_an_affine_basis(self, tester=None, **options): - """ - Run tests on the method :meth:`.an_affine_basis` - - TESTS:: - - sage: polytopes.cross_polytope(3)._test_an_affine_basis() - """ - if tester is None: - tester = self._tester(**options) - if self.is_compact(): - b = self.an_affine_basis() - m = matrix([1] + list(v) for v in b) - tester.assertEqual(m.rank(), self.dim() + 1) - for v in b: - tester.assertIn(v, self.vertices()) - def bounded_edges(self): """ Return the bounded edges (excluding rays and lines). @@ -1428,171 +1263,6 @@ def bounded_edges(self): continue yield (obj[i], obj[j]) - def ambient_dim(self): - r""" - Return the dimension of the ambient space. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.ambient_dim() - 4 - """ - return self.parent().ambient_dim() - - def dim(self): - """ - Return the dimension of the polyhedron. - - OUTPUT: - - -1 if the polyhedron is empty, otherwise a non-negative integer. - - EXAMPLES:: - - sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) - sage: simplex.dim() - 3 - sage: simplex.ambient_dim() - 4 - - The empty set is a special case (:trac:`12193`):: - - sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) - sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) - sage: P12 = P1.intersection(P2) - sage: P12 - The empty polyhedron in ZZ^3 - sage: P12.dim() - -1 - """ - if self.n_Vrepresentation() == 0: - return -1 # the empty set - else: - return self.ambient_dim() - self.n_equations() - - dimension = dim - - def Vrepresentation_space(self): - r""" - Return the ambient free module. - - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim`. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.Vrepresentation_space() - Ambient free module of rank 4 over the principal ideal domain Integer Ring - sage: poly_test.ambient_space() is poly_test.Vrepresentation_space() - True - """ - return self.parent().Vrepresentation_space() - - ambient_space = Vrepresentation_space - - def ambient_vector_space(self, base_field=None): - r""" - Return the ambient vector space. - - It is the ambient free module (:meth:`Vrepresentation_space`) tensored - with a field. - - INPUT: - - - ``base_field`` -- (default: the fraction field of the base ring) a field. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.ambient_vector_space() - Vector space of dimension 4 over Rational Field - sage: poly_test.ambient_vector_space() is poly_test.ambient() - True - - sage: poly_test.ambient_vector_space(AA) - Vector space of dimension 4 over Algebraic Real Field - sage: poly_test.ambient_vector_space(RR) - Vector space of dimension 4 over Real Field with 53 bits of precision - sage: poly_test.ambient_vector_space(SR) - Vector space of dimension 4 over Symbolic Ring - """ - return self.Vrepresentation_space().vector_space(base_field=base_field) - - ambient = ambient_vector_space - - def Hrepresentation_space(self): - r""" - Return the linear space containing the H-representation vectors. - - OUTPUT: - - A free module over the base ring of dimension :meth:`ambient_dim` + 1. - - EXAMPLES:: - - sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) - sage: poly_test.Hrepresentation_space() - Ambient free module of rank 5 over the principal ideal domain Integer Ring - """ - return self.parent().Hrepresentation_space() - - def is_empty(self): - """ - Test whether the polyhedron is the empty polyhedron - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]); P - A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices - sage: P.is_empty(), P.is_universe() - (False, False) - - sage: Q = Polyhedron(vertices=()); Q - The empty polyhedron in ZZ^0 - sage: Q.is_empty(), Q.is_universe() - (True, False) - - sage: R = Polyhedron(lines=[(1,0),(0,1)]); R - A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 lines - sage: R.is_empty(), R.is_universe() - (False, True) - """ - return self.n_Vrepresentation() == 0 - - def is_universe(self): - """ - Test whether the polyhedron is the whole ambient space - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]); P - A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices - sage: P.is_empty(), P.is_universe() - (False, False) - - sage: Q = Polyhedron(vertices=()); Q - The empty polyhedron in ZZ^0 - sage: Q.is_empty(), Q.is_universe() - (True, False) - - sage: R = Polyhedron(lines=[(1,0),(0,1)]); R - A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 lines - sage: R.is_empty(), R.is_universe() - (False, True) - """ - return self.n_Hrepresentation() == 0 - @cached_method def vertex_adjacency_matrix(self): """ @@ -2174,74 +1844,6 @@ def centroid(self, engine='auto', **kwds): pass return centroid - @cached_method - def representative_point(self): - """ - Return a "generic" point. - - .. SEEALSO:: - - :meth:`center`. - - OUTPUT: - - A point as a coordinate vector. The point is chosen to be - interior as far as possible. If the polyhedron is not - full-dimensional, the point is in the relative interior. If - the polyhedron is zero-dimensional, its single point is - returned. - - EXAMPLES:: - - sage: p = Polyhedron(vertices=[(3,2)], rays=[(1,-1)]) - sage: p.representative_point() - (4, 1) - sage: p.center() - (3, 2) - - sage: Polyhedron(vertices=[(3,2)]).representative_point() - (3, 2) - """ - accumulator = vector(self.base_ring(), [0]*self.ambient_dim()) - for v in self.vertex_generator(): - accumulator += v.vector() - accumulator /= self.n_vertices() - for r in self.ray_generator(): - accumulator += r.vector() - accumulator.set_immutable() - return accumulator - - def _some_elements_(self): - r""" - Generate some points of ``self``. - - If ``self`` is empty, no points are generated; no exception will be raised. - - EXAMPLES:: - - sage: P = polytopes.simplex() - sage: P.an_element() # indirect doctest - (1/4, 1/4, 1/4, 1/4) - sage: P.some_elements() # indirect doctest - [(1/4, 1/4, 1/4, 1/4), - (0, 0, 0, 1), - (0, 0, 1/2, 1/2), - (0, 1/2, 1/4, 1/4), - (1/2, 1/4, 1/8, 1/8)] - """ - if self.is_empty(): - return - yield self.representative_point() - vertex_iter = iter(self.vertex_generator()) - try: - p = next(vertex_iter).vector() - yield vector(p, immutable=True) - for i in range(4): - p = (p + next(vertex_iter).vector()) / 2 - yield vector(p, immutable=True) - except StopIteration: - pass - def a_maximal_chain(self): r""" Return a maximal chain of the face lattice in increasing order. @@ -7956,323 +7558,6 @@ def _integrate_latte_(self, polynomial, **kwds): polynomial, cdd=True, **kwds) - def contains(self, point): - """ - Test whether the polyhedron contains the given ``point``. - - .. SEEALSO:: - - :meth:`interior_contains`, :meth:`relative_interior_contains`. - - INPUT: - - - ``point`` -- coordinates of a point (an iterable) - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[[1,1],[1,-1],[0,0]]) - sage: P.contains( [1,0] ) - True - sage: P.contains( P.center() ) # true for any convex set - True - - As a shorthand, one may use the usual ``in`` operator:: - - sage: P.center() in P - True - sage: [-1,-1] in P - False - - The point need not have coordinates in the same field as the - polyhedron:: - - sage: ray = Polyhedron(vertices=[(0,0)], rays=[(1,0)], base_ring=QQ) - sage: ray.contains([sqrt(2)/3,0]) # irrational coordinates are ok - True - sage: a = var('a') - sage: ray.contains([a,0]) # a might be negative! - False - sage: assume(a>0) - sage: ray.contains([a,0]) - True - sage: ray.contains(['hello', 'kitty']) # no common ring for coordinates - False - - The empty polyhedron needs extra care, see :trac:`10238`:: - - sage: empty = Polyhedron(); empty - The empty polyhedron in ZZ^0 - sage: empty.contains([]) - False - sage: empty.contains([0]) # not a point in QQ^0 - False - sage: full = Polyhedron(vertices=[()]); full - A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex - sage: full.contains([]) - True - sage: full.contains([0]) - False - - TESTS: - - Passing non-iterable objects does not cause an exception, see :trac:`32013`:: - - sage: None in Polyhedron(vertices=[(0,0)], rays=[(1,0)], base_ring=QQ) - False - """ - try: - p = vector(point) - except TypeError: # point not iterable or no common ring for elements - try: - l = len(point) - except TypeError: - return False - if l > 0: - return False - else: - p = vector(self.base_ring(), []) - - if len(p) != self.ambient_dim(): - return False - - for H in self.Hrep_generator(): - if not H.contains(p): - return False - return True - - __contains__ = contains - - @cached_method - def interior(self): - """ - The interior of ``self``. - - OUTPUT: - - - either an empty polyhedron or an instance of - :class:`~sage.geometry.relative_interior.RelativeInterior` - - EXAMPLES: - - If the polyhedron is full-dimensional, the result is the - same as that of :meth:`relative_interior`:: - - sage: P_full = Polyhedron(vertices=[[0,0],[1,1],[1,-1]]) - sage: P_full.interior() - Relative interior of - a 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices - - If the polyhedron is of strictly smaller dimension than the - ambient space, its interior is empty:: - - sage: P_lower = Polyhedron(vertices=[[0,1], [0,-1]]) - sage: P_lower.interior() - The empty polyhedron in ZZ^2 - - TESTS:: - - sage: Empty = Polyhedron(ambient_dim=2); Empty - The empty polyhedron in ZZ^2 - sage: Empty.interior() is Empty - True - """ - if self.is_open(): - return self - if not self.is_full_dimensional(): - return self.parent().element_class(self.parent(), None, None) - return self.relative_interior() - - def interior_contains(self, point): - """ - Test whether the interior of the polyhedron contains the - given ``point``. - - .. SEEALSO:: - - :meth:`contains`, :meth:`relative_interior_contains`. - - INPUT: - - - ``point`` -- coordinates of a point - - OUTPUT: - - ``True`` or ``False``. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[[0,0],[1,1],[1,-1]]) - sage: P.contains( [1,0] ) - True - sage: P.interior_contains( [1,0] ) - False - - If the polyhedron is of strictly smaller dimension than the - ambient space, its interior is empty:: - - sage: P = Polyhedron(vertices=[[0,1],[0,-1]]) - sage: P.contains( [0,0] ) - True - sage: P.interior_contains( [0,0] ) - False - - The empty polyhedron needs extra care, see :trac:`10238`:: - - sage: empty = Polyhedron(); empty - The empty polyhedron in ZZ^0 - sage: empty.interior_contains([]) - False - """ - try: - p = vector(point) - except TypeError: # point not iterable or no common ring for elements - try: - l = len(point) - except TypeError: - return False - if l > 0: - return False - else: - p = vector(self.base_ring(), []) - - if len(p) != self.ambient_dim(): - return False - - for H in self.Hrep_generator(): - if not H.interior_contains(p): - return False - return True - - def is_relatively_open(self): - r""" - Return whether ``self`` is relatively open. - - OUTPUT: - - Boolean. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[(1,0), (-1,0)]); P - A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices - sage: P.is_relatively_open() - False - - sage: P0 = Polyhedron(vertices=[[1, 2]]); P0 - A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex - sage: P0.is_relatively_open() - True - - sage: Empty = Polyhedron(ambient_dim=2); Empty - The empty polyhedron in ZZ^2 - sage: Empty.is_relatively_open() - True - - sage: Line = Polyhedron(vertices=[(1, 1)], lines=[(1, 0)]); Line - A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line - sage: Line.is_relatively_open() - True - - """ - return not self.inequalities() - - @cached_method - def relative_interior(self): - """ - Return the relative interior of ``self``. - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[(1,0), (-1,0)]) - sage: ri_P = P.relative_interior(); ri_P - Relative interior of - a 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices - sage: (0, 0) in ri_P - True - sage: (1, 0) in ri_P - False - - sage: P0 = Polyhedron(vertices=[[1, 2]]) - sage: P0.relative_interior() is P0 - True - - sage: Empty = Polyhedron(ambient_dim=2) - sage: Empty.relative_interior() is Empty - True - - sage: Line = Polyhedron(vertices=[(1, 1)], lines=[(1, 0)]) - sage: Line.relative_interior() is Line - True - """ - if self.is_relatively_open(): - return self - return RelativeInterior(self) - - def relative_interior_contains(self, point): - """ - Test whether the relative interior of the polyhedron - contains the given ``point``. - - .. SEEALSO:: - - :meth:`contains`, :meth:`interior_contains`. - - INPUT: - - - ``point`` -- coordinates of a point - - OUTPUT: - - ``True`` or ``False`` - - EXAMPLES:: - - sage: P = Polyhedron(vertices=[(1,0), (-1,0)]) - sage: P.contains( (0,0) ) - True - sage: P.interior_contains( (0,0) ) - False - sage: P.relative_interior_contains( (0,0) ) - True - sage: P.relative_interior_contains( (1,0) ) - False - - The empty polyhedron needs extra care, see :trac:`10238`:: - - sage: empty = Polyhedron(); empty - The empty polyhedron in ZZ^0 - sage: empty.relative_interior_contains([]) - False - """ - try: - p = vector(point) - except TypeError: # point not iterable or no common ring for elements - try: - l = len(point) - except TypeError: - return False - if l > 0: - return False - else: - p = vector(self.base_ring(), []) - - if len(p) != self.ambient_dim(): - return False - - for eq in self.equation_generator(): - if not eq.contains(p): - return False - - for ine in self.inequality_generator(): - if not ine.interior_contains(p): - return False - - return True - def is_simplex(self): r""" Return whether the polyhedron is a simplex. diff --git a/src/sage/geometry/polyhedron/base1.py b/src/sage/geometry/polyhedron/base1.py new file mode 100644 index 00000000000..84968dbe01d --- /dev/null +++ b/src/sage/geometry/polyhedron/base1.py @@ -0,0 +1,802 @@ +r""" +Base class for polyhedra, part 1 + +Define methods that exist for convex sets, +but not constructions such as dilation or product. +""" + +# **************************************************************************** +# Copyright (C) 2008-2012 Marshall Hampton +# Copyright (C) 2011-2015 Volker Braun +# Copyright (C) 2012-2018 Frederic Chapoton +# Copyright (C) 2013 Andrey Novoseltsev +# Copyright (C) 2014-2017 Moritz Firsching +# Copyright (C) 2014-2019 Thierry Monteil +# Copyright (C) 2015 Nathann Cohen +# Copyright (C) 2015-2017 Jeroen Demeyer +# Copyright (C) 2015-2017 Vincent Delecroix +# Copyright (C) 2015-2018 Dima Pasechnik +# Copyright (C) 2015-2020 Jean-Philippe Labbe +# Copyright (C) 2015-2021 Matthias Koeppe +# Copyright (C) 2016-2019 Daniel Krenn +# Copyright (C) 2017 Marcelo Forets +# Copyright (C) 2017-2018 Mark Bell +# Copyright (C) 2019 Julian Ritter +# Copyright (C) 2019-2020 Laith Rastanawi +# Copyright (C) 2019-2020 Sophia Elia +# Copyright (C) 2019-2021 Jonathan Kliem +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from sage.misc.abstract_method import abstract_method +from sage.misc.cachefunc import cached_method +from sage.modules.free_module_element import vector +from .base0 import Polyhedron_base0 +from sage.geometry.convex_set import ConvexSet_closed, AffineHullProjectionData +from sage.geometry.relative_interior import RelativeInterior + + +class Polyhedron_base1(Polyhedron_base0, ConvexSet_closed): + """ + Convex set methods for polyhedra, + but not constructions such as dilation or product. + + See :class:`sage.geometry.polyhedron.base.Polyhedron_base`. + + TESTS:: + + sage: from sage.geometry.polyhedron.base1 import Polyhedron_base1 + sage: P = polytopes.cube() + sage: Q = polytopes.cube() + sage: Polyhedron_base1.__hash__(P) == Polyhedron_base1.__hash__(Q) + True + sage: Polyhedron_base1.__repr__(P) + 'A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices' + sage: Polyhedron_base1.is_empty(P) + False + sage: Polyhedron_base1.is_universe(P) + False + sage: Polyhedron_base1.dim(P) + 3 + sage: Polyhedron_base1.ambient_vector_space(P) + Vector space of dimension 3 over Rational Field + sage: Polyhedron_base1.ambient_dim(P) + 3 + sage: Polyhedron_base1.an_affine_basis(P) + [A vertex at (-1, -1, -1), + A vertex at (1, -1, -1), + A vertex at (1, -1, 1), + A vertex at (1, 1, -1)] + sage: list(Polyhedron_base1._some_elements_(P)) + [(0, 0, 0), + (1, -1, -1), + (1, 0, -1), + (1, 1/2, 0), + (1, -1/4, 1/2), + (0, -5/8, 3/4)] + sage: Polyhedron_base1.contains(P, vector([1, 1, 1])) + True + sage: Polyhedron_base1.interior_contains(P, vector([1, 1, 1])) + False + sage: Polyhedron_base1.is_relatively_open(P) + False + sage: Polyhedron_base1.relative_interior.f(P) == Polyhedron_base1.interior.f(P) + True + """ + + def __hash__(self): + r""" + TESTS:: + + sage: K. = QuadraticField(2) + sage: p = Polyhedron(vertices=[(0,1,a),(3,a,5)], + ....: rays=[(a,2,3), (0,0,1)], + ....: base_ring=K) + sage: q = Polyhedron(vertices=[(3,a,5),(0,1,a)], + ....: rays=[(0,0,1), (a,2,3)], + ....: base_ring=K) + sage: hash(p) == hash(q) + True + """ + # TODO: find something better *but* fast + return hash((self.dim(), + self.ambient_dim(), + self.n_Hrepresentation(), + self.n_Vrepresentation(), + self.n_equations(), + self.n_facets(), + self.n_inequalities(), + self.n_lines(), + self.n_rays(), + self.n_vertices())) + + def _repr_(self): + """ + Return a description of the polyhedron. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,2,3,4],[2,1,3,4],[4,3,2,1]]) + sage: poly_test._repr_() + 'A 2-dimensional polyhedron in ZZ^4 defined as the convex hull of 3 vertices' + sage: grammar_test = Polyhedron(vertices = [[1,1,1,1,1,1]]) + sage: grammar_test._repr_() + 'A 0-dimensional polyhedron in ZZ^6 defined as the convex hull of 1 vertex' + """ + desc = '' + if self.n_vertices() == 0: + desc += 'The empty polyhedron' + else: + desc += 'A ' + repr(self.dim()) + '-dimensional polyhedron' + desc += ' in ' + desc += self.parent()._repr_ambient_module() + + if self.n_vertices() > 0: + desc += ' defined as the convex hull of ' + desc += repr(self.n_vertices()) + if self.n_vertices() == 1: + desc += ' vertex' + else: + desc += ' vertices' + + if self.n_rays() > 0: + if self.n_lines() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_rays()) + if self.n_rays() == 1: + desc += ' ray' + else: + desc += ' rays' + + if self.n_lines() > 0: + if self.n_rays() > 0: + desc += ", " + else: + desc += " and " + desc += repr(self.n_lines()) + if self.n_lines() == 1: + desc += ' line' + else: + desc += ' lines' + + return desc + + def is_empty(self): + """ + Test whether the polyhedron is the empty polyhedron + + OUTPUT: + + Boolean. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]); P + A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices + sage: P.is_empty(), P.is_universe() + (False, False) + + sage: Q = Polyhedron(vertices=()); Q + The empty polyhedron in ZZ^0 + sage: Q.is_empty(), Q.is_universe() + (True, False) + + sage: R = Polyhedron(lines=[(1,0),(0,1)]); R + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 lines + sage: R.is_empty(), R.is_universe() + (False, True) + """ + return self.n_Vrepresentation() == 0 + + def is_universe(self): + """ + Test whether the polyhedron is the whole ambient space + + OUTPUT: + + Boolean. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]); P + A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices + sage: P.is_empty(), P.is_universe() + (False, False) + + sage: Q = Polyhedron(vertices=()); Q + The empty polyhedron in ZZ^0 + sage: Q.is_empty(), Q.is_universe() + (True, False) + + sage: R = Polyhedron(lines=[(1,0),(0,1)]); R + A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex and 2 lines + sage: R.is_empty(), R.is_universe() + (False, True) + """ + return self.n_Hrepresentation() == 0 + + def dim(self): + """ + Return the dimension of the polyhedron. + + OUTPUT: + + -1 if the polyhedron is empty, otherwise a non-negative integer. + + EXAMPLES:: + + sage: simplex = Polyhedron(vertices = [[1,0,0,0],[0,0,0,1],[0,1,0,0],[0,0,1,0]]) + sage: simplex.dim() + 3 + sage: simplex.ambient_dim() + 4 + + The empty set is a special case (:trac:`12193`):: + + sage: P1=Polyhedron(vertices=[[1,0,0],[0,1,0],[0,0,1]]) + sage: P2=Polyhedron(vertices=[[2,0,0],[0,2,0],[0,0,2]]) + sage: P12 = P1.intersection(P2) + sage: P12 + The empty polyhedron in ZZ^3 + sage: P12.dim() + -1 + """ + if self.n_Vrepresentation() == 0: + return -1 # the empty set + else: + return self.ambient_dim() - self.n_equations() + + dimension = dim + + def Vrepresentation_space(self): + r""" + Return the ambient free module. + + OUTPUT: + + A free module over the base ring of dimension :meth:`ambient_dim`. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.Vrepresentation_space() + Ambient free module of rank 4 over the principal ideal domain Integer Ring + sage: poly_test.ambient_space() is poly_test.Vrepresentation_space() + True + """ + return self.parent().Vrepresentation_space() + + def Hrepresentation_space(self): + r""" + Return the linear space containing the H-representation vectors. + + OUTPUT: + + A free module over the base ring of dimension :meth:`ambient_dim` + 1. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.Hrepresentation_space() + Ambient free module of rank 5 over the principal ideal domain Integer Ring + """ + return self.parent().Hrepresentation_space() + + ambient_space = Vrepresentation_space + + def ambient_vector_space(self, base_field=None): + r""" + Return the ambient vector space. + + It is the ambient free module (:meth:`Vrepresentation_space`) tensored + with a field. + + INPUT: + + - ``base_field`` -- (default: the fraction field of the base ring) a field. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.ambient_vector_space() + Vector space of dimension 4 over Rational Field + sage: poly_test.ambient_vector_space() is poly_test.ambient() + True + + sage: poly_test.ambient_vector_space(AA) + Vector space of dimension 4 over Algebraic Real Field + sage: poly_test.ambient_vector_space(RR) + Vector space of dimension 4 over Real Field with 53 bits of precision + sage: poly_test.ambient_vector_space(SR) + Vector space of dimension 4 over Symbolic Ring + """ + return self.Vrepresentation_space().vector_space(base_field=base_field) + + ambient = ambient_vector_space + + def ambient_dim(self): + r""" + Return the dimension of the ambient space. + + EXAMPLES:: + + sage: poly_test = Polyhedron(vertices = [[1,0,0,0],[0,1,0,0]]) + sage: poly_test.ambient_dim() + 4 + """ + return self.parent().ambient_dim() + + def an_affine_basis(self): + """ + Return points in ``self`` that are a basis for the affine span of the polytope. + + This implementation of the method :meth:`ConvexSet_base.an_affine_basis` + for polytopes guarantees the following: + + - All points are vertices. + + - The basis is obtained by considering a maximal chain of faces + in the face lattice and picking for each cover relation + one vertex that is in the difference. Thus this method + is independent of the concrete realization of the polytope. + + EXAMPLES:: + + sage: P = polytopes.cube() + sage: P.an_affine_basis() + [A vertex at (-1, -1, -1), + A vertex at (1, -1, -1), + A vertex at (1, -1, 1), + A vertex at (1, 1, -1)] + + sage: P = polytopes.permutahedron(5) + sage: P.an_affine_basis() + [A vertex at (1, 2, 3, 5, 4), + A vertex at (2, 1, 3, 5, 4), + A vertex at (1, 3, 2, 5, 4), + A vertex at (4, 1, 3, 5, 2), + A vertex at (4, 2, 5, 3, 1)] + + The method is not implemented for unbounded polyhedra:: + + sage: p = Polyhedron(vertices=[(0,0)],rays=[(1,0),(0,1)]) + sage: p.an_affine_basis() + Traceback (most recent call last): + ... + NotImplementedError: this function is not implemented for unbounded polyhedra + """ + if not self.is_compact(): + raise NotImplementedError("this function is not implemented for unbounded polyhedra") + + chain = self.a_maximal_chain()[1:] # we exclude the empty face + chain_indices = [face.ambient_V_indices() for face in chain] + basis_indices = [] + + # We use in the following that elements in ``chain_indices`` are sorted lists + # of V-indices. + # Thus for each two faces we can easily find the first vertex that differs. + for dim, face in enumerate(chain_indices): + if dim == 0: + # Append the vertex. + basis_indices.append(face[0]) + continue + + prev_face = chain_indices[dim-1] + for i in range(len(prev_face)): + if prev_face[i] != face[i]: + # We found a vertex that ``face`` has, but its facet does not. + basis_indices.append(face[i]) + break + else: # no break + # ``prev_face`` contains all the same vertices as ``face`` until now. + # But ``face`` is guaranteed to contain one more vertex (at least). + basis_indices.append(face[len(prev_face)]) + + return [self.Vrepresentation()[i] for i in basis_indices] + + @abstract_method + def a_maximal_chain(self): + r""" + Return a maximal chain of the face lattice in increasing order. + + Subclasses must provide an implementation of this method. + + EXAMPLES:: + + sage: from sage.geometry.polyhedron.base1 import Polyhedron_base1 + sage: P = polytopes.cube() + sage: Polyhedron_base1.a_maximal_chain + + """ + + @cached_method + def representative_point(self): + """ + Return a "generic" point. + + .. SEEALSO:: + + :meth:`center`. + + OUTPUT: + + A point as a coordinate vector. The point is chosen to be + interior as far as possible. If the polyhedron is not + full-dimensional, the point is in the relative interior. If + the polyhedron is zero-dimensional, its single point is + returned. + + EXAMPLES:: + + sage: p = Polyhedron(vertices=[(3,2)], rays=[(1,-1)]) + sage: p.representative_point() + (4, 1) + sage: p.center() + (3, 2) + + sage: Polyhedron(vertices=[(3,2)]).representative_point() + (3, 2) + """ + accumulator = vector(self.base_ring(), [0]*self.ambient_dim()) + for v in self.vertex_generator(): + accumulator += v.vector() + accumulator /= self.n_vertices() + for r in self.ray_generator(): + accumulator += r.vector() + accumulator.set_immutable() + return accumulator + + def _some_elements_(self): + r""" + Generate some points of ``self``. + + If ``self`` is empty, no points are generated; no exception will be raised. + + EXAMPLES:: + + sage: P = polytopes.simplex() + sage: P.an_element() # indirect doctest + (1/4, 1/4, 1/4, 1/4) + sage: P.some_elements() # indirect doctest + [(1/4, 1/4, 1/4, 1/4), + (0, 0, 0, 1), + (0, 0, 1/2, 1/2), + (0, 1/2, 1/4, 1/4), + (1/2, 1/4, 1/8, 1/8)] + """ + if self.is_empty(): + return + yield self.representative_point() + vertex_iter = iter(self.vertex_generator()) + try: + p = next(vertex_iter).vector() + yield vector(p, immutable=True) + for i in range(4): + p = (p + next(vertex_iter).vector()) / 2 + yield vector(p, immutable=True) + except StopIteration: + pass + + def contains(self, point): + """ + Test whether the polyhedron contains the given ``point``. + + .. SEEALSO:: + + :meth:`interior_contains`, :meth:`relative_interior_contains`. + + INPUT: + + - ``point`` -- coordinates of a point (an iterable) + + OUTPUT: + + Boolean. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[[1,1],[1,-1],[0,0]]) + sage: P.contains( [1,0] ) + True + sage: P.contains( P.center() ) # true for any convex set + True + + As a shorthand, one may use the usual ``in`` operator:: + + sage: P.center() in P + True + sage: [-1,-1] in P + False + + The point need not have coordinates in the same field as the + polyhedron:: + + sage: ray = Polyhedron(vertices=[(0,0)], rays=[(1,0)], base_ring=QQ) + sage: ray.contains([sqrt(2)/3,0]) # irrational coordinates are ok + True + sage: a = var('a') + sage: ray.contains([a,0]) # a might be negative! + False + sage: assume(a>0) + sage: ray.contains([a,0]) + True + sage: ray.contains(['hello', 'kitty']) # no common ring for coordinates + False + + The empty polyhedron needs extra care, see :trac:`10238`:: + + sage: empty = Polyhedron(); empty + The empty polyhedron in ZZ^0 + sage: empty.contains([]) + False + sage: empty.contains([0]) # not a point in QQ^0 + False + sage: full = Polyhedron(vertices=[()]); full + A 0-dimensional polyhedron in ZZ^0 defined as the convex hull of 1 vertex + sage: full.contains([]) + True + sage: full.contains([0]) + False + + TESTS: + + Passing non-iterable objects does not cause an exception, see :trac:`32013`:: + + sage: None in Polyhedron(vertices=[(0,0)], rays=[(1,0)], base_ring=QQ) + False + """ + try: + p = vector(point) + except TypeError: # point not iterable or no common ring for elements + try: + l = len(point) + except TypeError: + return False + if l > 0: + return False + else: + p = vector(self.base_ring(), []) + + if len(p) != self.ambient_dim(): + return False + + for H in self.Hrep_generator(): + if not H.contains(p): + return False + return True + + __contains__ = contains + + @cached_method + def interior(self): + """ + The interior of ``self``. + + OUTPUT: + + - either an empty polyhedron or an instance of + :class:`~sage.geometry.relative_interior.RelativeInterior` + + EXAMPLES: + + If the polyhedron is full-dimensional, the result is the + same as that of :meth:`relative_interior`:: + + sage: P_full = Polyhedron(vertices=[[0,0],[1,1],[1,-1]]) + sage: P_full.interior() + Relative interior of + a 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices + + If the polyhedron is of strictly smaller dimension than the + ambient space, its interior is empty:: + + sage: P_lower = Polyhedron(vertices=[[0,1], [0,-1]]) + sage: P_lower.interior() + The empty polyhedron in ZZ^2 + + TESTS:: + + sage: Empty = Polyhedron(ambient_dim=2); Empty + The empty polyhedron in ZZ^2 + sage: Empty.interior() is Empty + True + """ + if self.is_open(): + return self + if not self.is_full_dimensional(): + return self.parent().element_class(self.parent(), None, None) + return self.relative_interior() + + def interior_contains(self, point): + """ + Test whether the interior of the polyhedron contains the + given ``point``. + + .. SEEALSO:: + + :meth:`contains`, :meth:`relative_interior_contains`. + + INPUT: + + - ``point`` -- coordinates of a point + + OUTPUT: + + ``True`` or ``False``. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[[0,0],[1,1],[1,-1]]) + sage: P.contains( [1,0] ) + True + sage: P.interior_contains( [1,0] ) + False + + If the polyhedron is of strictly smaller dimension than the + ambient space, its interior is empty:: + + sage: P = Polyhedron(vertices=[[0,1],[0,-1]]) + sage: P.contains( [0,0] ) + True + sage: P.interior_contains( [0,0] ) + False + + The empty polyhedron needs extra care, see :trac:`10238`:: + + sage: empty = Polyhedron(); empty + The empty polyhedron in ZZ^0 + sage: empty.interior_contains([]) + False + """ + try: + p = vector(point) + except TypeError: # point not iterable or no common ring for elements + try: + l = len(point) + except TypeError: + return False + if l > 0: + return False + else: + p = vector(self.base_ring(), []) + + if len(p) != self.ambient_dim(): + return False + + for H in self.Hrep_generator(): + if not H.interior_contains(p): + return False + return True + + def is_relatively_open(self): + r""" + Return whether ``self`` is relatively open. + + OUTPUT: + + Boolean. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[(1,0), (-1,0)]); P + A 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices + sage: P.is_relatively_open() + False + + sage: P0 = Polyhedron(vertices=[[1, 2]]); P0 + A 0-dimensional polyhedron in ZZ^2 defined as the convex hull of 1 vertex + sage: P0.is_relatively_open() + True + + sage: Empty = Polyhedron(ambient_dim=2); Empty + The empty polyhedron in ZZ^2 + sage: Empty.is_relatively_open() + True + + sage: Line = Polyhedron(vertices=[(1, 1)], lines=[(1, 0)]); Line + A 1-dimensional polyhedron in QQ^2 defined as the convex hull of 1 vertex and 1 line + sage: Line.is_relatively_open() + True + + """ + return not self.inequalities() + + @cached_method + def relative_interior(self): + """ + Return the relative interior of ``self``. + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[(1,0), (-1,0)]) + sage: ri_P = P.relative_interior(); ri_P + Relative interior of + a 1-dimensional polyhedron in ZZ^2 defined as the convex hull of 2 vertices + sage: (0, 0) in ri_P + True + sage: (1, 0) in ri_P + False + + sage: P0 = Polyhedron(vertices=[[1, 2]]) + sage: P0.relative_interior() is P0 + True + + sage: Empty = Polyhedron(ambient_dim=2) + sage: Empty.relative_interior() is Empty + True + + sage: Line = Polyhedron(vertices=[(1, 1)], lines=[(1, 0)]) + sage: Line.relative_interior() is Line + True + """ + if self.is_relatively_open(): + return self + return RelativeInterior(self) + + def relative_interior_contains(self, point): + """ + Test whether the relative interior of the polyhedron + contains the given ``point``. + + .. SEEALSO:: + + :meth:`contains`, :meth:`interior_contains`. + + INPUT: + + - ``point`` -- coordinates of a point + + OUTPUT: + + ``True`` or ``False`` + + EXAMPLES:: + + sage: P = Polyhedron(vertices=[(1,0), (-1,0)]) + sage: P.contains( (0,0) ) + True + sage: P.interior_contains( (0,0) ) + False + sage: P.relative_interior_contains( (0,0) ) + True + sage: P.relative_interior_contains( (1,0) ) + False + + The empty polyhedron needs extra care, see :trac:`10238`:: + + sage: empty = Polyhedron(); empty + The empty polyhedron in ZZ^0 + sage: empty.relative_interior_contains([]) + False + """ + try: + p = vector(point) + except TypeError: # point not iterable or no common ring for elements + try: + l = len(point) + except TypeError: + return False + if l > 0: + return False + else: + p = vector(self.base_ring(), []) + + if len(p) != self.ambient_dim(): + return False + + for eq in self.equation_generator(): + if not eq.contains(p): + return False + + for ine in self.inequality_generator(): + if not ine.interior_contains(p): + return False + + return True From 315748c8236d22ee4948fb262bde747a22a7b725 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 11:26:44 -0700 Subject: [PATCH 210/378] src/sage/geometry/abc.pyx: Update unique direct subclass test for ABC Polyhedron --- src/sage/geometry/abc.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/abc.pyx b/src/sage/geometry/abc.pyx index 199db3ec6eb..ada0cac6a14 100644 --- a/src/sage/geometry/abc.pyx +++ b/src/sage/geometry/abc.pyx @@ -72,7 +72,7 @@ class Polyhedron: By design, there is a unique direct subclass:: sage: sage.geometry.abc.Polyhedron.__subclasses__() # optional - sage.geometry.polyhedron - [] + [] sage: len(sage.geometry.abc.Polyhedron.__subclasses__()) <= 1 True From 2bb33dca58544d1f8b41ff102907b8e46f3040ed Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 11:38:44 -0700 Subject: [PATCH 211/378] src/sage/geometry/abc.pyx: Update unique direct subclass test for ABC Polyhedron (fixup) --- src/sage/geometry/abc.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/abc.pyx b/src/sage/geometry/abc.pyx index ada0cac6a14..4db85b7ace8 100644 --- a/src/sage/geometry/abc.pyx +++ b/src/sage/geometry/abc.pyx @@ -72,7 +72,7 @@ class Polyhedron: By design, there is a unique direct subclass:: sage: sage.geometry.abc.Polyhedron.__subclasses__() # optional - sage.geometry.polyhedron - [] + [] sage: len(sage.geometry.abc.Polyhedron.__subclasses__()) <= 1 True From 810e3e6d58c5206db09838b5612be17e0a8e12a7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 11:49:55 -0700 Subject: [PATCH 212/378] src/sage/modules/free_module.py: Separate long if/elif chain from the following code by a newline --- src/sage/modules/free_module.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/modules/free_module.py b/src/sage/modules/free_module.py index 9e002cfbea9..1b773a5e18d 100644 --- a/src/sage/modules/free_module.py +++ b/src/sage/modules/free_module.py @@ -7462,6 +7462,7 @@ def element_class(R, is_sparse): elif isinstance(R, sage.rings.abc.SymbolicRing) and not is_sparse: import sage.modules.vector_symbolic_dense return sage.modules.vector_symbolic_dense.Vector_symbolic_dense + if is_sparse: return free_module_element.FreeModuleElement_generic_sparse else: From b85aaa4048b19999727d72e98e9add5f114f9f7a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 11:50:45 -0700 Subject: [PATCH 213/378] src/sage/symbolic/ring.pyx: Returns -> Return in docstring --- src/sage/symbolic/ring.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/ring.pyx b/src/sage/symbolic/ring.pyx index 2d3a8e51f28..7c245e0e6c3 100644 --- a/src/sage/symbolic/ring.pyx +++ b/src/sage/symbolic/ring.pyx @@ -1311,7 +1311,7 @@ def the_SymbolicRing(): def is_SymbolicExpressionRing(R): """ - Returns True if ``R`` is the symbolic expression ring. + Return True if ``R`` is the symbolic expression ring. This function is deprecated. Instead, either use ``R is SR`` (to test whether ``R`` is the unique symbolic ring ``SR``); or From 9c1d6b40b01efdc86017378138cbd6ceb14feaaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 26 Oct 2021 21:27:43 +0200 Subject: [PATCH 214/378] some details --- src/sage/modules/with_basis/morphism.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sage/modules/with_basis/morphism.py b/src/sage/modules/with_basis/morphism.py index 832a06adc35..7972927406d 100644 --- a/src/sage/modules/with_basis/morphism.py +++ b/src/sage/modules/with_basis/morphism.py @@ -176,11 +176,11 @@ def __init__(self, domain, codomain=None, category=None, affine=False): """ if category is None: if domain not in ModulesWithBasis: - raise ValueError("domain(=%s) should be a module with basis" % (codomain)) + raise ValueError("domain(=%s) should be a module with basis" % codomain) base_ring = domain.base_ring() if not hasattr(codomain, 'base_ring'): - raise ValueError("codomain(=%s) needs to have a base_ring attribute"%(codomain)) + raise ValueError("codomain(=%s) needs to have a base_ring attribute" % codomain) # codomain should be a module over base_ring # The natural test would be ``codomains in Modules(base_ring)`` # But this is not properly implemented yet:: @@ -227,6 +227,7 @@ def __init__(self, domain, codomain=None, category=None, affine=False): if not issubclass(self.__class__, H._abstract_element_class): self.__class__ = H.__make_element_class__(self.__class__) + class ModuleMorphismFromFunction(ModuleMorphism, SetMorphism): """ A class for module morphisms implemented by a plain function. @@ -264,6 +265,7 @@ def __init__(self, domain, function, codomain=None, category=None): ModuleMorphism.__init__(self, domain, codomain, category=category) SetMorphism.__init__(self, self.parent(), function) + class ModuleMorphismByLinearity(ModuleMorphism): """ A class for module morphisms obtained by extending a function by linearity. @@ -318,7 +320,7 @@ def __init__(self, domain, on_basis=None, codomain=None, category=None, self._on_basis = on_basis self._is_module_with_basis_over_same_base_ring = \ - codomain in ModulesWithBasis( base_ring ) and zero == codomain.zero() + codomain in ModulesWithBasis(base_ring) and zero == codomain.zero() ModuleMorphism.__init__(self, domain, codomain, category=category, From bf0ed1dfbd38f0836c576bcd4199682a66c83936 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 16:27:56 -0700 Subject: [PATCH 215/378] _is_[real_]numerical: Fall back to using CDF/RDF if ComplexField, RealField cannot be imported --- src/sage/structure/parent.pyx | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sage/structure/parent.pyx b/src/sage/structure/parent.pyx index 506946bf5f4..30590b1ba77 100644 --- a/src/sage/structure/parent.pyx +++ b/src/sage/structure/parent.pyx @@ -2812,9 +2812,16 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: [R._is_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ - from sage.rings.complex_mpfr import ComplexField - from sage.rings.real_mpfr import mpfr_prec_min - return ComplexField(mpfr_prec_min()).has_coerce_map_from(self) + try: + from sage.rings.complex_mpfr import ComplexField + from sage.rings.real_mpfr import mpfr_prec_min + except ImportError: + pass + else: + return ComplexField(mpfr_prec_min()).has_coerce_map_from(self) + + from sage.rings.real_double import CDF + return CDF.has_coerce_map_from(self) @cached_method def _is_real_numerical(self): @@ -2833,8 +2840,15 @@ cdef class Parent(sage.structure.category_object.CategoryObject): sage: [R._is_real_numerical() for R in [RIF, RBF, CIF, CBF]] [False, False, False, False] """ - from sage.rings.real_mpfr import RealField, mpfr_prec_min - return RealField(mpfr_prec_min()).has_coerce_map_from(self) + try: + from sage.rings.real_mpfr import RealField, mpfr_prec_min + except ImportError: + pass + else: + return RealField(mpfr_prec_min()).has_coerce_map_from(self) + + from sage.rings.real_double import RDF + return RDF.has_coerce_map_from(self) ############################################################################ # Set base class -- From afe634c3d05c6b976ee199b7220f3e366f2d25fd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 16:56:11 -0700 Subject: [PATCH 216/378] sage.rings.infinity: Remove hard dependency on real_lazy and real_mpfi --- src/sage/rings/infinity.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index dfa0b9b6423..567d5cc769b 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -710,9 +710,13 @@ def _element_constructor_(self, x): True """ # Lazy elements can wrap infinity or not, unwrap first - from sage.rings.real_lazy import LazyWrapper - if isinstance(x, LazyWrapper): - x = x._value + try: + from sage.rings.real_lazy import LazyWrapper + except ImportError: + pass + else: + if isinstance(x, LazyWrapper): + x = x._value # Handle all ways to represent infinity first if isinstance(x, InfinityElement): @@ -720,7 +724,7 @@ def _element_constructor_(self, x): elif isinstance(x, float): if x in [float('+inf'), float('-inf')]: return self.gen() - elif isinstance(x, sage.rings.real_mpfi.RealIntervalFieldElement): + elif isinstance(x.parent(), sage.rings.abc.RealIntervalField): if x.upper().is_infinity() or x.lower().is_infinity(): return self.gen() else: @@ -1166,9 +1170,13 @@ def _element_constructor_(self, x): ValueError: infinite but not with +/- phase """ # Lazy elements can wrap infinity or not, unwrap first - from sage.rings.real_lazy import LazyWrapper - if isinstance(x, LazyWrapper): - x = x._value + try: + from sage.rings.real_lazy import LazyWrapper + except ImportError: + pass + else: + if isinstance(x, LazyWrapper): + x = x._value # Handle all ways to represent infinity first if isinstance(x, InfinityElement): @@ -1181,7 +1189,7 @@ def _element_constructor_(self, x): return self.gen(0) if x == float('-inf'): return self.gen(1) - elif isinstance(x, sage.rings.real_mpfi.RealIntervalFieldElement): + elif isinstance(x.parent(), sage.rings.abc.RealIntervalField): if x.upper().is_positive_infinity(): return self.gen(0) if x.lower().is_negative_infinity(): From 1305b3a83f9796b230e07d0b12165065554aa35d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 17:26:57 -0700 Subject: [PATCH 217/378] src/sage/geometry/polyhedron/library.py: Make imports from sage.rings lazier --- src/sage/geometry/polyhedron/library.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 31cec880ccf..89ef3effb86 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -82,10 +82,9 @@ import itertools from sage.rings.integer_ring import ZZ -from sage.rings.qqbar import AA, QQbar +from sage.misc.lazy_import import lazy_import +lazy_import('sage.rings.qqbar', ['AA', 'QQbar']) from sage.rings.rational_field import QQ -from sage.rings.real_double import RDF -from sage.rings.real_mpfr import RR from sage.combinat.permutation import Permutations from sage.groups.perm_gps.permgroup_named import AlternatingGroup from .constructor import Polyhedron @@ -94,7 +93,7 @@ from sage.graphs.graph import Graph from sage.combinat.root_system.associahedron import Associahedron -def zero_sum_projection(d, base_ring=RDF): +def zero_sum_projection(d, base_ring=None): r""" Return a matrix corresponding to the projection on the orthogonal of `(1,1,\ldots,1)` in dimension `d`. @@ -126,6 +125,8 @@ def zero_sum_projection(d, base_ring=RDF): """ from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector + if base_ring is None: + from sage.rings.real_double import RDF as base_ring basis = [vector(base_ring, [1]*i + [-i] + [0]*(d-i-1)) for i in range(1, d)] return matrix(base_ring, [v / v.norm() for v in basis]) @@ -190,7 +191,7 @@ def project_points(*points, **kwds): return [] base_ring = kwds.pop('base_ring', None) if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring from sage.modules.free_module_element import vector vecs = [vector(base_ring, p) for p in points] m = zero_sum_projection(len(vecs[0]), base_ring=base_ring) @@ -563,9 +564,9 @@ def regular_polygon(self, n, exact=True, base_ring=None, backend=None): if base_ring is None: if exact: - base_ring = AA + from sage.rings.qqbar import AA as base_ring else: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring try: omega = 2*base_ring.pi() / n @@ -1512,6 +1513,7 @@ def icosidodecahedron(self, exact=True, backend=None): if exact: return Polyhedron(vertices=verts, base_ring=K, backend=backend) else: + from sage.rings.real_mpfr import RR verts = [(RR(x), RR(y), RR(z)) for x, y, z in verts] return Polyhedron(vertices=verts, backend=backend) From ae64d1b0cd6e4f94c6e607b8a95f024946f214dd Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 28 Sep 2021 23:31:13 -0700 Subject: [PATCH 218/378] src/sage/geometry/polyhedron/library.py: Make some imports lazy --- src/sage/geometry/polyhedron/library.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 89ef3effb86..c15a77b1d41 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -85,13 +85,13 @@ from sage.misc.lazy_import import lazy_import lazy_import('sage.rings.qqbar', ['AA', 'QQbar']) from sage.rings.rational_field import QQ -from sage.combinat.permutation import Permutations -from sage.groups.perm_gps.permgroup_named import AlternatingGroup +lazy_import('sage.combinat.permutation', 'Permutations') +lazy_import('sage.groups.perm_gps.permgroup_named', 'AlternatingGroup') from .constructor import Polyhedron from .parent import Polyhedra -from sage.graphs.digraph import DiGraph -from sage.graphs.graph import Graph -from sage.combinat.root_system.associahedron import Associahedron +lazy_import('sage.graphs.digraph', 'DiGraph') +lazy_import('sage.graphs.graph', 'Graph') +lazy_import('sage.combinat.root_system.associahedron', 'Associahedron') def zero_sum_projection(d, base_ring=None): r""" From 459b3d47f74c1c74640e09c156b97bd2049afe3f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 29 Sep 2021 19:00:13 -0700 Subject: [PATCH 219/378] src/sage/geometry/polyhedron/library.py: Ignore failing imports from other modules --- src/sage/geometry/polyhedron/library.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index c15a77b1d41..4539d9af7ae 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -3418,9 +3418,12 @@ def parallelotope(self, generators, backend=None): # -------------------------------------------------------- associahedron = staticmethod(Associahedron) - flow_polytope = staticmethod(DiGraph.flow_polytope) - edge_polytope = staticmethod(Graph.edge_polytope) - symmetric_edge_polytope = staticmethod(Graph.symmetric_edge_polytope) + try: + flow_polytope = staticmethod(DiGraph.flow_polytope) + edge_polytope = staticmethod(Graph.edge_polytope) + symmetric_edge_polytope = staticmethod(Graph.symmetric_edge_polytope) + except ImportError: + pass polytopes = Polytopes() From 24e821d7cc0a421f2b92adf1f58793ad74d4e960 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 17:38:02 -0700 Subject: [PATCH 220/378] src/sage/geometry/polyhedron/library.py: Move import of RDF into methods --- src/sage/geometry/polyhedron/library.py | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 4539d9af7ae..3b031e6c81d 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -776,7 +776,7 @@ def icosahedron(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = (1 + base_ring(5).sqrt()) / 2 r12 = base_ring.one() / 2 @@ -895,7 +895,7 @@ def small_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring sqrt2 = base_ring(2).sqrt() one = base_ring.one() @@ -953,7 +953,7 @@ def great_rhombicuboctahedron(self, exact=True, base_ring=None, backend=None): sqrt2 = base_ring.gen() else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring sqrt2 = base_ring(2).sqrt() one = base_ring.one() @@ -1114,7 +1114,7 @@ def truncated_cube(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = base_ring(2).sqrt() - 1 v = [[a * g, b, c] for a in [-1, 1] for b in [-1, 1] for c in [-1, 1]] @@ -1382,7 +1382,7 @@ def construct_z(field): z = base_ring.gen() else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring z = construct_z(base_ring) verts = [] @@ -1577,7 +1577,7 @@ def icosidodecahedron_V2(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = (1 + base_ring(5).sqrt()) / 2 pts = [[g, 0, 0], [-g, 0, 0]] @@ -1658,7 +1658,7 @@ def truncated_dodecahedron(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = (1 + base_ring(5).sqrt()) / 2 z = base_ring.zero() @@ -1818,7 +1818,7 @@ def rhombicosidodecahedron(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = (1 + base_ring(5).sqrt()) / 2 pts = [[s1 * base_ring.one(), s2 * base_ring.one(), s3 * (g**3)] @@ -1895,7 +1895,7 @@ def truncated_icosidodecahedron(self, exact=True, base_ring=None, backend=None): base_ring = K else: if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring g = (1 + base_ring(5).sqrt()) / 2 pts = [[s1 * 1 / g, s2 * 1 / g, s3 * (3 + g)] @@ -1960,7 +1960,7 @@ def snub_dodecahedron(self, base_ring=None, backend=None, verbose=False): """ if base_ring is None: - base_ring = RDF + from sage.rings.real_double import RDF as base_ring phi = (1 + base_ring(5).sqrt()) / 2 xi = ((phi/2 + (phi - ZZ(5)/27).sqrt()/2)**(~ZZ(3)) + (phi/2 - (phi - ZZ(5)/27).sqrt()/2)**(~ZZ(3))) @@ -2261,8 +2261,8 @@ def six_hundred_cell(self, exact=False, backend=None): g = (1 + sqrt5) / 2 base_ring = K else: - g = (1 + RDF(5).sqrt()) / 2 - base_ring = RDF + from sage.rings.real_double import RDF as base_ring + g = (1 + base_ring(5).sqrt()) / 2 q12 = base_ring(1) / base_ring(2) z = base_ring.zero() @@ -2332,8 +2332,8 @@ def grand_antiprism(self, exact=True, backend=None, verbose=False): g = (1 + sqrt5) / 2 base_ring = K else: - g = (1 + RDF(5).sqrt()) / 2 - base_ring = RDF + from sage.rings.real_double import RDF as base_ring + g = (1 + base_ring(5).sqrt()) / 2 q12 = base_ring(1) / base_ring(2) z = base_ring.zero() From 1b844e2cadd424ac9bd76a425cc50ba43551a04c Mon Sep 17 00:00:00 2001 From: Thierry Monteil Date: Wed, 27 Oct 2021 03:03:07 +0200 Subject: [PATCH 221/378] #32781 : search for the correct pattern in the logs when SAGE_CHECK='warn' --- build/bin/sage-spkg | 1 + build/make/install | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 7f390e3a0f2..7f038c5f194 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -773,6 +773,7 @@ if [ "$SAGE_CHECK" = "yes" -o "$SAGE_CHECK" = "warn" ]; then if [ $? -ne 0 ]; then TEST_SUITE_RESULT="failed" if [ "$SAGE_CHECK" = "warn" ]; then + # The following warning message must be consistent with SAGE_ROOT/build/bin/sage-spkg (see trac:32781) error_msg "Warning: Failures testing package $PKG_NAME (ignored)" "make check" else error_msg "Error testing package $PKG_NAME" "make check" diff --git a/build/make/install b/build/make/install index 1d17884c1ba..eaf6ed7b47a 100755 --- a/build/make/install +++ b/build/make/install @@ -122,7 +122,8 @@ EOF elif [ "$SAGE_CHECK" = "warn" ]; then echo "SAGE_CHECK=warn, so scanning the log files. This may take a few seconds." - warnings=`look_for_errors "$SAGE_LOGS/*.log" 20 "^Warning: Error testing" package` + # The following warning message must be consistent with SAGE_ROOT/build/bin/sage-spkg (see trac:32781) + warnings=`look_for_errors "$SAGE_LOGS/*.log" 20 "^Warning: Failures testing package" package` if [ -n "$warnings" ]; then cat >&2 < Date: Wed, 27 Oct 2021 03:06:48 +0200 Subject: [PATCH 222/378] #32781 : typo --- build/bin/sage-spkg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/bin/sage-spkg b/build/bin/sage-spkg index 7f038c5f194..42dd723c8df 100755 --- a/build/bin/sage-spkg +++ b/build/bin/sage-spkg @@ -773,7 +773,7 @@ if [ "$SAGE_CHECK" = "yes" -o "$SAGE_CHECK" = "warn" ]; then if [ $? -ne 0 ]; then TEST_SUITE_RESULT="failed" if [ "$SAGE_CHECK" = "warn" ]; then - # The following warning message must be consistent with SAGE_ROOT/build/bin/sage-spkg (see trac:32781) + # The following warning message must be consistent with SAGE_ROOT/build/make/install (see trac:32781) error_msg "Warning: Failures testing package $PKG_NAME (ignored)" "make check" else error_msg "Error testing package $PKG_NAME" "make check" From c1b1d9338fc3142f533bf37f2c13defc496d3335 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 22:10:32 -0700 Subject: [PATCH 223/378] src/sage/geometry/polyhedron/plot.py: Add more # optional - sage.plot --- src/sage/geometry/polyhedron/plot.py | 38 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/sage/geometry/polyhedron/plot.py b/src/sage/geometry/polyhedron/plot.py index cde0769cd68..803023bc2db 100644 --- a/src/sage/geometry/polyhedron/plot.py +++ b/src/sage/geometry/polyhedron/plot.py @@ -881,8 +881,8 @@ def render_points_1d(self, **kwds): sage: cube1 = polytopes.hypercube(1) sage: proj = cube1.projection() - sage: points = proj.render_points_1d() - sage: points._objects + sage: points = proj.render_points_1d() # optional - sage.plot + sage: points._objects # optional - sage.plot [Point set defined by 2 point(s)] """ return point2d([c + [0] for c in self.coordinates_of(self.points)], **kwds) @@ -902,8 +902,8 @@ def render_line_1d(self, **kwds): EXAMPLES:: - sage: outline = polytopes.hypercube(1).projection().render_line_1d() - sage: outline._objects[0] + sage: outline = polytopes.hypercube(1).projection().render_line_1d() # optional - sage.plot + sage: outline._objects[0] # optional - sage.plot Line defined by 2 points """ if len(self.lines) == 0: @@ -922,8 +922,8 @@ def render_points_2d(self, **kwds): sage: hex = polytopes.regular_polygon(6) sage: proj = hex.projection() - sage: hex_points = proj.render_points_2d() - sage: hex_points._objects + sage: hex_points = proj.render_points_2d() # optional - sage.plot + sage: hex_points._objects # optional - sage.plot [Point set defined by 6 point(s)] """ return point2d(self.coordinates_of(self.points), **kwds) @@ -935,8 +935,8 @@ def render_outline_2d(self, **kwds): EXAMPLES:: sage: penta = polytopes.regular_polygon(5) - sage: outline = penta.projection().render_outline_2d() - sage: outline._objects[0] + sage: outline = penta.projection().render_outline_2d() # optional - sage.plot + sage: outline._objects[0] # optional - sage.plot Line defined by 2 points """ wireframe = [] @@ -957,8 +957,8 @@ def render_fill_2d(self, **kwds): sage: cps = [i^3 for i in srange(-2,2,1/5)] sage: p = Polyhedron(vertices = [[(t^2-1)/(t^2+1),2*t/(t^2+1)] for t in cps]) sage: proj = p.projection() - sage: filled_poly = proj.render_fill_2d() - sage: filled_poly.axes_width() + sage: filled_poly = proj.render_fill_2d() # optional - sage.plot + sage: filled_poly.axes_width() # optional - sage.plot 0.8 """ poly = [polygon2d(self.coordinates_of(p), **kwds) @@ -973,8 +973,8 @@ def render_vertices_3d(self, **kwds): sage: p = polytopes.cross_polytope(3) sage: proj = p.projection() - sage: verts = proj.render_vertices_3d() - sage: verts.bounding_box() + sage: verts = proj.render_vertices_3d() # optional - sage.plot + sage: verts.bounding_box() # optional - sage.plot ((-1.0, -1.0, -1.0), (1.0, 1.0, 1.0)) """ return point3d(self.coordinates_of(self.points), **kwds) @@ -987,8 +987,8 @@ def render_wireframe_3d(self, **kwds): sage: cube = polytopes.hypercube(3) sage: cube_proj = cube.projection() - sage: wire = cube_proj.render_wireframe_3d() - sage: print(wire.tachyon().split('\n')[77]) # for testing + sage: wire = cube_proj.render_wireframe_3d() # optional - sage.plot + sage: print(wire.tachyon().split('\n')[77]) # for testing # optional - sage.plot FCylinder base 1.0 1.0 -1.0 apex -1.0 1.0 -1.0 rad 0.005 texture... """ wireframe = [] @@ -1007,8 +1007,8 @@ def render_solid_3d(self, **kwds): EXAMPLES:: sage: p = polytopes.hypercube(3).projection() - sage: p_solid = p.render_solid_3d(opacity = .7) - sage: type(p_solid) + sage: p_solid = p.render_solid_3d(opacity=.7) # optional - sage.plot + sage: type(p_solid) # optional - sage.plot """ polys = self.polygons @@ -1031,9 +1031,9 @@ def render_0d(self, point_opts=None, line_opts=None, polygon_opts=None): EXAMPLES:: - sage: print(Polyhedron([]).projection().render_0d().description()) + sage: print(Polyhedron([]).projection().render_0d().description()) # optional - sage.plot - sage: print(Polyhedron(ieqs=[(1,)]).projection().render_0d().description()) + sage: print(Polyhedron(ieqs=[(1,)]).projection().render_0d().description()) # optional - sage.plot Point set defined by 1 point(s): [(0.0, 0.0)] """ if point_opts is None: @@ -1062,7 +1062,7 @@ def render_1d(self, point_opts=None, line_opts=None, polygon_opts=None): EXAMPLES:: - sage: Polyhedron([(0,), (1,)]).projection().render_1d() + sage: Polyhedron([(0,), (1,)]).projection().render_1d() # optional - sage.plot Graphics object consisting of 2 graphics primitives """ plt = Graphics() From eb31b221cdb5ca05e44a94fee6526ddc78eaa2cc Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 22:34:28 -0700 Subject: [PATCH 224/378] src/sage/geometry/voronoi_diagram.py: Add # optional - sage.rings.number_field --- src/sage/geometry/voronoi_diagram.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/geometry/voronoi_diagram.py b/src/sage/geometry/voronoi_diagram.py index a854f5651c9..bc588b4e73d 100644 --- a/src/sage/geometry/voronoi_diagram.py +++ b/src/sage/geometry/voronoi_diagram.py @@ -52,18 +52,18 @@ class VoronoiDiagram(SageObject): Get the Voronoi diagram of a regular pentagon in ``AA^2``. All cells meet at the origin:: - sage: DV = VoronoiDiagram([[AA(c) for c in v] for v in polytopes.regular_polygon(5).vertices_list()]); DV + sage: DV = VoronoiDiagram([[AA(c) for c in v] for v in polytopes.regular_polygon(5).vertices_list()]); DV # optional - sage.rings.number_field The Voronoi diagram of 5 points of dimension 2 in the Algebraic Real Field - sage: all(P.contains([0, 0]) for P in DV.regions().values()) + sage: all(P.contains([0, 0]) for P in DV.regions().values()) # optional - sage.rings.number_field True - sage: any(P.interior_contains([0, 0]) for P in DV.regions().values()) + sage: any(P.interior_contains([0, 0]) for P in DV.regions().values()) # optional - sage.rings.number_field False If the vertices are not converted to ``AA`` before, the method throws an error:: - sage: polytopes.dodecahedron().vertices_list()[0][0].parent() + sage: polytopes.dodecahedron().vertices_list()[0][0].parent() # optional - sage.rings.number_field Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: VoronoiDiagram(polytopes.dodecahedron().vertices_list()) + sage: VoronoiDiagram(polytopes.dodecahedron().vertices_list()) # optional - sage.rings.number_field Traceback (most recent call last): ... NotImplementedError: Base ring of the Voronoi diagram must be @@ -232,9 +232,9 @@ def _repr_(self): EXAMPLES:: - sage: V = VoronoiDiagram(polytopes.regular_polygon(3).vertices()); V + sage: V = VoronoiDiagram(polytopes.regular_polygon(3).vertices()); V # optional - sage.rings.number_field The Voronoi diagram of 3 points of dimension 2 in the Algebraic Real Field - sage: VoronoiDiagram([]) + sage: VoronoiDiagram([]) # optional - sage.rings.number_field The empty Voronoi diagram. """ if self._n: From d1b3bca6595d91a6b704e94b257ccc272eca8076 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 22:34:55 -0700 Subject: [PATCH 225/378] src/sage/geometry/integral_points.pyx: Add # optional - sage.rings.number_field --- src/sage/geometry/integral_points.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/geometry/integral_points.pyx b/src/sage/geometry/integral_points.pyx index 8db5599877f..28c256061b3 100644 --- a/src/sage/geometry/integral_points.pyx +++ b/src/sage/geometry/integral_points.pyx @@ -1196,8 +1196,8 @@ cdef class InequalityCollection: Check that :trac:`21037` is fixed:: sage: P = Polyhedron(vertices=((0, 0), (17,3))) - sage: P += 1/1000*polytopes.regular_polygon(5) - sage: P.integral_points() + sage: P += 1/1000*polytopes.regular_polygon(5) # optional - sage.rings.number_field + sage: P.integral_points() # optional - sage.rings.number_field ((0, 0), (17, 3)) """ cdef list A From 98522e02b7d0665d2d0f3b44cecc491dfc40e932 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 26 Oct 2021 22:46:37 -0700 Subject: [PATCH 226/378] src/sage/numerical: Add # optional - sage.rings.number_field --- src/sage/numerical/backends/generic_backend.pyx | 14 +++++++------- .../numerical/backends/interactivelp_backend.pyx | 14 +++++++------- src/sage/numerical/mip.pyx | 12 ++++++------ 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/sage/numerical/backends/generic_backend.pyx b/src/sage/numerical/backends/generic_backend.pyx index bc4cc83741b..5e0adb0a915 100644 --- a/src/sage/numerical/backends/generic_backend.pyx +++ b/src/sage/numerical/backends/generic_backend.pyx @@ -1691,18 +1691,18 @@ cpdef GenericBackend get_solver(constraint_generation = False, solver = None, ba <...sage.numerical.backends.ppl_backend.PPLBackend...> sage: p.base_ring() Rational Field - sage: p = get_solver(base_ring=AA); p + sage: p = get_solver(base_ring=AA); p # optional - sage.rings.number_field <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() + sage: p.base_ring() # optional - sage.rings.number_field Algebraic Real Field - sage: d = polytopes.dodecahedron() - sage: p = get_solver(base_ring=d.base_ring()); p + sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: p = get_solver(base_ring=d.base_ring()); p # optional - sage.rings.number_field <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() + sage: p.base_ring() # optional - sage.rings.number_field Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? - sage: p = get_solver(solver='InteractiveLP', base_ring=QQ); p + sage: p = get_solver(solver='InteractiveLP', base_ring=QQ); p # optional - sage.rings.number_field <...sage.numerical.backends.interactivelp_backend.InteractiveLPBackend...> - sage: p.base_ring() + sage: p.base_ring() # optional - sage.rings.number_field Rational Field Passing a callable as the 'solver':: diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index 6b26a21f1e2..b5a02474ae8 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -53,17 +53,17 @@ cdef class InteractiveLPBackend: This backend can work with irrational algebraic numbers:: - sage: poly = polytopes.dodecahedron(base_ring=AA) - sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) - sage: lp.set_objective(x[0] + x[1] + x[2]) + sage: poly = polytopes.dodecahedron(base_ring=AA) # optional - sage.rings.number_field + sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) # optional - sage.rings.number_field + sage: lp.set_objective(x[0] + x[1] + x[2]) # optional - sage.rings.number_field sage: lp.solve() 2.291796067500631? - sage: lp.get_values(x[0], x[1], x[2]) + sage: lp.get_values(x[0], x[1], x[2]) # optional - sage.rings.number_field [0.763932022500211?, 0.763932022500211?, 0.763932022500211?] - sage: lp.set_objective(x[0] - x[1] - x[2]) - sage: lp.solve() + sage: lp.set_objective(x[0] - x[1] - x[2]) # optional - sage.rings.number_field + sage: lp.solve() # optional - sage.rings.number_field 2.291796067500631? - sage: lp.get_values(x[0], x[1], x[2]) + sage: lp.get_values(x[0], x[1], x[2]) # optional - sage.rings.number_field [0.763932022500211?, -0.763932022500211?, -0.763932022500211?] """ diff --git a/src/sage/numerical/mip.pyx b/src/sage/numerical/mip.pyx index 47f89dbef39..4180f3f6b9f 100644 --- a/src/sage/numerical/mip.pyx +++ b/src/sage/numerical/mip.pyx @@ -663,13 +663,13 @@ cdef class MixedIntegerLinearProgram(SageObject): sage: p = MixedIntegerLinearProgram(solver='ppl') sage: p.base_ring() Rational Field - sage: from sage.rings.all import AA - sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) - sage: p.base_ring() + sage: from sage.rings.qqbar import AA # optional - sage.rings.number_field + sage: p = MixedIntegerLinearProgram(solver='InteractiveLP', base_ring=AA) # optional - sage.rings.number_field + sage: p.base_ring() # optional - sage.rings.number_field Algebraic Real Field - sage: d = polytopes.dodecahedron() - sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) - sage: p.base_ring() + sage: d = polytopes.dodecahedron() # optional - sage.rings.number_field + sage: p = MixedIntegerLinearProgram(base_ring=d.base_ring()) # optional - sage.rings.number_field + sage: p.base_ring() # optional - sage.rings.number_field Number Field in sqrt5 with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790? """ return self._backend.base_ring() From 9627d4ae5447bc72805c1ab920f5ce24b231cb6c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 27 Oct 2021 12:02:23 +0200 Subject: [PATCH 227/378] trac #32306: possible fix --- src/sage/graphs/strongly_regular_db.pyx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/sage/graphs/strongly_regular_db.pyx b/src/sage/graphs/strongly_regular_db.pyx index 0089412092b..cdbd9e3b345 100644 --- a/src/sage/graphs/strongly_regular_db.pyx +++ b/src/sage/graphs/strongly_regular_db.pyx @@ -2628,13 +2628,20 @@ def SRG_1288_792_476_504(): cdef bint seems_feasible(int v, int k, int l, int mu): r""" - Tests is the set of parameters seems feasible + Check if the set of parameters seems feasible. INPUT: - ``v,k,l,mu`` (integers) + + TESTS: + + :trac:`32306` is fixed:: + + sage: from sage.graphs.strongly_regular_db import strongly_regular_graph + sage: strongly_regular_graph(16384, 8256, 4160, 4160, existence=True) + True """ - cdef int r,s,f,g cdef uint_fast32_t tmp[2] if (v<0 or k<=0 or l<0 or mu<0 or From e10245f58c9b7e2d8080e9eebb0d98abece1121c Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 27 Oct 2021 13:21:01 +0200 Subject: [PATCH 228/378] trac #32783: add # random --- src/sage/graphs/generic_graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index d0850f13357..2b330c5449f 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -574,7 +574,7 @@ def __eq__(self, other): True sage: G = graphs.RandomGNP(8, .9999) sage: H = graphs.CompleteGraph(8) - sage: G == H # most often true + sage: G == H # random - most often true True sage: G = Graph({0: [1, 2, 3, 4, 5, 6, 7]} ) sage: H = Graph({1: [0], 2: [0], 3: [0], 4: [0], 5: [0], 6: [0], 7: [0]} ) From 4d7ac2f75ff8d703b26d499daef4de2087d105b1 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 27 Oct 2021 15:41:24 +0200 Subject: [PATCH 229/378] fixup --- src/sage/rings/integer.pyx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/rings/integer.pyx b/src/sage/rings/integer.pyx index fefe92b7d02..b53b5a1a161 100644 --- a/src/sage/rings/integer.pyx +++ b/src/sage/rings/integer.pyx @@ -198,7 +198,7 @@ except ImportError: pari_gen = () -set_integer_from_pari_gen = None +set_integer_from_gen = None pari_divisors_small = None n_factor_to_list = None pari_is_prime_power = None @@ -646,8 +646,8 @@ cdef class Integer(sage.structure.element.EuclideanDomainElement): raise TypeError("Cannot convert non-integral float to integer") elif isinstance(x, pari_gen): - global set_integer_from_pari_gen - if set_integer_from_pari_gen is None: + global set_integer_from_gen + if set_integer_from_gen is None: from sage.libs.pari.convert_sage import set_integer_from_gen set_integer_from_gen(self, x) From 9424a24cb59f00c4fb0e19a2356dc208317a5b09 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Wed, 27 Oct 2021 19:52:24 +0200 Subject: [PATCH 230/378] Some minor reviewer's changes --- src/sage/libs/singular/singular.pyx | 195 +++++++++++++--------------- 1 file changed, 90 insertions(+), 105 deletions(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index 6c6c907359c..bf8b461fea2 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -62,16 +62,16 @@ cdef Rational si2sa_QQ(number *n, number **nn, ring *_ring): INPUT: - - ``n`` - a (pointer to) a singular rational number + - ``n`` - a (pointer to) a singular rational number - - ``*n`` - a pointer to a pointer like before + - ``*n`` - a pointer to a pointer like before - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` OUTPUT: - - A sage Rational + - A sage Rational TESTS:: @@ -134,14 +134,14 @@ cdef Integer si2sa_ZZ(number *n, ring *_ring): INPUT: - - ``n`` - a (pointer to) a singular integer number + - ``n`` - a (pointer to) a singular integer number - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` OUTPUT: - - A sage Integer + - A sage Integer TESTS:: @@ -169,12 +169,12 @@ cdef FFgivE si2sa_GFqGivaro(number *n, ring *_ring, Cache_givaro cache): INPUT: - - ``n`` - a (pointer to) a singular number in a finite field + - ``n`` - a (pointer to) a singular number in a finite field - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``cache`` - A Givaro number field + - ``cache`` - A Givaro number field OUTPUT: @@ -225,16 +225,16 @@ cdef FFgf2eE si2sa_GFqNTLGF2E(number *n, ring *_ring, Cache_ntl_gf2e cache): INPUT: - - ``n`` - a (pointer to) a singular number in a finite field + - ``n`` - a (pointer to) a singular number in a finite field - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``cache`` - A ntl_gf2e number field + - ``cache`` - A ntl_gf2e number field OUTPUT: - - A sage element of ``cache`` + - A sage element of ``cache`` TESTS:: @@ -276,16 +276,16 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number in a finite field + - ``n`` - a (pointer to) a singular number in a finite field - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``base`` - A sage finite field + - ``base`` - A sage finite field OUTPUT: - - A sage element of ``base`` + - A sage element of ``base`` TESTS:: @@ -304,7 +304,6 @@ cdef object si2sa_GFq_generic(number *n, ring *_ring, object base): sage: R. = F[] sage: R(-1).constant_coefficient() # indirect doctest 2147483646 - """ cdef poly *z cdef long c @@ -340,17 +339,17 @@ cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number in a transcendental extension + - ``n`` - a (pointer to) a singular number in a transcendental extension of the rationals - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``base`` - A sage FractionField + - ``base`` - A sage FractionField OUTPUT: - - A sage element of ``base`` + - A sage element of ``base`` TESTS:: @@ -370,7 +369,6 @@ cdef object si2sa_transext_QQ(number *n, ring *_ring, object base): [x^3 + (3*a - 3*b)/(a + b)*x*y, y^2 + a/b*x] sage: R.term_order() Degree reverse lexicographic term order - """ cdef poly *numer @@ -431,17 +429,17 @@ cdef object si2sa_transext_FF(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number in a transcendental extension - of the rationals + - ``n`` - a (pointer to) a singular number in a transcendental extension + of the rationals - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``base`` - A sage FractionField + - ``base`` - A sage FractionField OUTPUT: - - A sage element of ``base`` + - A sage element of ``base`` TESTS:: @@ -452,7 +450,6 @@ cdef object si2sa_transext_FF(number *n, ring *_ring, object base): -2 sage: type(n) - """ cdef poly *numer @@ -515,17 +512,17 @@ cdef object si2sa_NF(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number in an algebraic extension of - the rationals + - ``n`` - a (pointer to) a singular number in an algebraic extension of + the rationals - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``base`` - A sage NumberField + - ``base`` - A sage NumberField OUTPUT: - - A sage element of ``base`` + - A sage element of ``base`` TESTS:: @@ -580,16 +577,16 @@ cdef inline object si2sa_ZZmod(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number in a ring of integers modulo n + - ``n`` - a (pointer to) a singular number in a ring of integers modulo n - - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field - lives ``n`` + - ``_ ring`` - a (pointer to) a singular ring, in whose coefficient field + lives ``n`` - - ``base`` - A sage IntegerModRing + - ``base`` - A sage IntegerModRing OUTPUT: - - A sage element of ``base`` + - A sage element of ``base`` TESTS:: @@ -641,14 +638,14 @@ cdef number *sa2si_QQ(Rational r, ring *_ring): INPUT: - - ``r`` - a sage rational number + - ``r`` - a sage rational number - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -672,14 +669,14 @@ cdef number *sa2si_GFqGivaro(int quo, ring *_ring): INPUT: - - ``quo`` - a sage integer + - ``quo`` - a sage integer - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number Number field elements are represented as polynomials in the number field generator. In this case, ``quo`` is the integer resulting from evaluating @@ -698,7 +695,6 @@ cdef number *sa2si_GFqGivaro(int quo, ring *_ring): (z2 + 1) sage: R(F.gen()^2) + 1 (z2 - 1) - """ if _ring != currRing: rChangeCurrRing(_ring) @@ -743,14 +739,14 @@ cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): INPUT: - - ``elem`` - a sage element of a ntl_gf2e finite field + - ``elem`` - a sage element of a ntl_gf2e finite field - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -764,7 +760,6 @@ cdef number *sa2si_GFqNTLGF2E(FFgf2eE elem, ring *_ring): (z20 + 1) sage: R(F.gen()^21) + 1 (z20^11 + z20^10 + z20^8 + z20^7 + z20^6 + z20^5 + z20^2 + z20 + 1) - """ if _ring != currRing: rChangeCurrRing(_ring) cdef int i @@ -810,14 +805,14 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): INPUT: - - ``elem`` - a sage element of a generic finite field + - ``elem`` - a sage element of a generic finite field - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -831,7 +826,6 @@ cdef number *sa2si_GFq_generic(object elem, ring *_ring): (z20 + 1) sage: R(F.gen()^21) + 1 (z20^14 - z20^12 - z20^11 - z20^10 - z20^9 + z20^6 + z20^5 + z20^4 - z20^2 + z20 + 1) - """ cdef int i cdef number *n1 @@ -878,14 +872,14 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): INPUT: - - ``elem`` - a sage element of a FractionField of polynomials over the rationals + - ``elem`` - a sage element of a FractionField of polynomials over the rationals - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -929,7 +923,6 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): sage: f = x + y + 1 sage: R(f) x + y + 1 - """ cdef int j @@ -954,7 +947,7 @@ cdef number *sa2si_transext_QQ(object elem, ring *_ring): nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function - if (nMapFuncPtr is NULL): + if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") numerdic = elem.numerator().dict() @@ -1034,14 +1027,14 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring): INPUT: - - ``elem`` - a sage element of a FractionField of polynomials over the rationals + - ``elem`` - a sage element of a FractionField of polynomials over the rationals - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -1053,9 +1046,6 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring): 3 sage: Integer(n) 5 - - - """ cdef int j cdef number *n1 @@ -1076,7 +1066,7 @@ cdef number *sa2si_transext_FF(object elem, ring *_ring): nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function - if (nMapFuncPtr is NULL): + if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") numerdic = elem.numerator().dict() @@ -1140,14 +1130,14 @@ cdef number *sa2si_NF(object elem, ring *_ring): INPUT: - - ``elem`` - a sage element of a NumberField + - ``elem`` - a sage element of a NumberField - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -1163,7 +1153,6 @@ cdef number *sa2si_NF(object elem, ring *_ring): (a + 1) sage: R(F.gen()^5) + 1 (-a^2 + a + 2) - """ cdef int i cdef number *n1 @@ -1178,7 +1167,7 @@ cdef number *sa2si_NF(object elem, ring *_ring): nMapFuncPtr = naSetMap(_ring.cf, currRing.cf) # choose correct mapping function - if (nMapFuncPtr is NULL): + if nMapFuncPtr is NULL: raise RuntimeError("Failed to determine nMapFuncPtr") elem = list(elem) @@ -1203,7 +1192,6 @@ cdef number *sa2si_NF(object elem, ring *_ring): rComplete(qqr,1) qqr.ShortOut = 0 - nMapFuncPtr = naSetMap( qqr.cf , _ring.cf ) # choose correct mapping function cdef poly *_p for i from 0 <= i < len(elem): @@ -1234,14 +1222,14 @@ cdef number *sa2si_ZZ(Integer d, ring *_ring): INPUT: - - ``elem`` - a sage Integer + - ``elem`` - a sage Integer - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live OUTPUT: - - A (pointer to) a singular number + - A (pointer to) a singular number TESTS:: @@ -1267,11 +1255,9 @@ cdef inline number *sa2si_ZZmod(IntegerMod_abstract d, ring *_ring): INPUT: - - ``elem`` - a sage IntegerMod - - - ``_ ring`` - a (pointer to) a singular ring, where the resul will live - + - ``elem`` - a sage IntegerMod + - ``_ ring`` - a (pointer to) a singular ring, where the resul will live TESTS:: @@ -1351,15 +1337,15 @@ cdef object si2sa(number *n, ring *_ring, object base): INPUT: - - ``n`` - a (pointer to) a singular number + - ``n`` - a (pointer to) a singular number - - ``_ring`` - a (pointer to) the singular ring where ``n`` lives + - ``_ring`` - a (pointer to) the singular ring where ``n`` lives - - ``object`` - the sage parent where the result will live + - ``object`` - the sage parent where the result will live OUTPUT: - An element of ``base`` + An element of ``base`` """ if isinstance(base, FiniteField_prime_modn): return base(_ring.cf.cfInt(n, _ring.cf)) @@ -1402,14 +1388,14 @@ cdef number *sa2si(Element elem, ring * _ring): INPUT: - - ``elem`` - a sage element from a parent. The parent must have a - corresponding singular coefficient type. + - ``elem`` - a sage element from a parent. The parent must have a + corresponding singular coefficient type. - - ``_ring`` - a (pointer to) the singular ring where the result will live. + - ``_ring`` - a (pointer to) the singular ring where the result will live. OUTPUT: - a (pointer to) a singular number + a (pointer to) a singular number """ cdef int i = 0 if isinstance(elem._parent, FiniteField_prime_modn): @@ -1436,14 +1422,13 @@ cdef number *sa2si(Element elem, ring * _ring): if _ring.cf.type == n_unknown: return n_Init(int(elem),_ring) return sa2si_ZZmod(elem, _ring) - elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), RationalField): - return sa2si_transext_QQ(elem, _ring) + elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)): + if isinstance(elem._parent.base().base_ring(), RationalField): + return sa2si_transext_QQ(elem, _ring) + elif isinstance(elem._parent.base().base_ring(), FiniteField_prime_modn): + return sa2si_transext_FF(elem, _ring) - elif isinstance(elem._parent, FractionField_generic) and isinstance(elem._parent.base(), (MPolynomialRing_libsingular, PolynomialRing_field)) and isinstance(elem._parent.base().base_ring(), FiniteField_prime_modn): - return sa2si_transext_FF(elem, _ring) - - else: - raise ValueError("cannot convert to SINGULAR number") + raise ValueError("cannot convert to SINGULAR number") cdef object si2sa_intvec(intvec *v): @@ -1452,11 +1437,11 @@ cdef object si2sa_intvec(intvec *v): INPUT: - - ``v`` - a (pointer to) a singular intvec + - ``v`` - a (pointer to) a singular intvec OUTPUT: - a sage tuple + a sage tuple """ cdef int r cdef list l = list() From fb9faa69e62b5af763c6116815eb01f6c6b8d255 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Oct 2021 22:05:24 -0700 Subject: [PATCH 231/378] src/sage/rings/infinity.py: Fix up: Only call .parent() on elements --- src/sage/rings/infinity.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/infinity.py b/src/sage/rings/infinity.py index 567d5cc769b..33afda67bd9 100644 --- a/src/sage/rings/infinity.py +++ b/src/sage/rings/infinity.py @@ -724,7 +724,7 @@ def _element_constructor_(self, x): elif isinstance(x, float): if x in [float('+inf'), float('-inf')]: return self.gen() - elif isinstance(x.parent(), sage.rings.abc.RealIntervalField): + elif isinstance(x, RingElement) and isinstance(x.parent(), sage.rings.abc.RealIntervalField): if x.upper().is_infinity() or x.lower().is_infinity(): return self.gen() else: @@ -1189,7 +1189,7 @@ def _element_constructor_(self, x): return self.gen(0) if x == float('-inf'): return self.gen(1) - elif isinstance(x.parent(), sage.rings.abc.RealIntervalField): + elif isinstance(x, RingElement) and isinstance(x.parent(), sage.rings.abc.RealIntervalField): if x.upper().is_positive_infinity(): return self.gen(0) if x.lower().is_negative_infinity(): From 853cfb77983cdd4ce47f340ae5c1ed12af9b77be Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Oct 2021 23:19:01 -0700 Subject: [PATCH 232/378] src/sage/geometry/polyhedron/library.py: Add missing import of RDF --- src/sage/geometry/polyhedron/library.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 3b031e6c81d..65598886f25 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -2768,6 +2768,7 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula vertices = [transf * v.change_ring(AA) for v in vertices] br = AA if not exact: + from sage.rings.real_double import RDF vertices = [v.change_ring(RDF) for v in vertices] br = RDF return Polyhedron(vertices=vertices, backend=backend, base_ring=br) From 35c1b5f1311268ddfcd3d83c741ab8bf51b1b224 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Oct 2021 23:49:19 -0700 Subject: [PATCH 233/378] build/pkgs/gsl/spkg-install.in: Also pass CPPFLAGS, CFLAGS to configure --- build/pkgs/gsl/spkg-install.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/pkgs/gsl/spkg-install.in b/build/pkgs/gsl/spkg-install.in index ef156a7a5c5..44b8d9d4863 100644 --- a/build/pkgs/gsl/spkg-install.in +++ b/build/pkgs/gsl/spkg-install.in @@ -1,5 +1,8 @@ cd src -sdh_configure LIBS="`pkg-config --libs-only-l cblas` -lm" LDFLAGS="$LDFLAGS `pkg-config --libs-only-L cblas`" +sdh_configure LIBS="`pkg-config --libs-only-l cblas` -lm" \ + LDFLAGS="$LDFLAGS `pkg-config --libs-only-L cblas`" \ + CPPFLAGS="$CPPFLAGS `pkg-config --cflags-only-I cblas`" \ + CFLAGS="$CFLAGS `pkg-config --cflags-only-other cblas`" sdh_make sdh_make_install From b846c0a9e1b36a99bd714630553808d18204dba4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 27 Oct 2021 23:53:24 -0700 Subject: [PATCH 234/378] src/sage/numerical/backends/interactivelp_backend.pyx: Add missing # optional --- src/sage/numerical/backends/interactivelp_backend.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/numerical/backends/interactivelp_backend.pyx b/src/sage/numerical/backends/interactivelp_backend.pyx index b5a02474ae8..366baf4da26 100644 --- a/src/sage/numerical/backends/interactivelp_backend.pyx +++ b/src/sage/numerical/backends/interactivelp_backend.pyx @@ -56,7 +56,7 @@ cdef class InteractiveLPBackend: sage: poly = polytopes.dodecahedron(base_ring=AA) # optional - sage.rings.number_field sage: lp, x = poly.to_linear_program(solver='InteractiveLP', return_variable=True) # optional - sage.rings.number_field sage: lp.set_objective(x[0] + x[1] + x[2]) # optional - sage.rings.number_field - sage: lp.solve() + sage: lp.solve() # optional - sage.rings.number_field 2.291796067500631? sage: lp.get_values(x[0], x[1], x[2]) # optional - sage.rings.number_field [0.763932022500211?, 0.763932022500211?, 0.763932022500211?] From e1664fff95fb671e91bc41737518f7442dd4690f Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Thu, 28 Oct 2021 08:59:20 +0200 Subject: [PATCH 235/378] use different precisions in doctest --- src/sage/rings/continued_fraction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index ce55ac87867..d1af820e3fe 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -263,7 +263,7 @@ def rat_interval_cf_list(r1, r2): sage: rat_interval_cf_list(257/113, 5224/2297) [2, 3, 1, 1, 1, 4] sage: for prec in range(10,54): - ....: R = RealIntervalField(20) + ....: R = RealIntervalField(prec) ....: for _ in range(100): ....: x = R.random_element() * R.random_element() + R.random_element() / 100 ....: l = x.lower().exact_rational() From 91175519586b984be1b469a7eb49679b3ecbe998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 28 Oct 2021 10:38:07 +0200 Subject: [PATCH 236/378] 32696: fix failing doctest --- src/sage/finance/stock.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/sage/finance/stock.py b/src/sage/finance/stock.py index ed8cb8ed90b..aa1dbb7dc99 100644 --- a/src/sage/finance/stock.py +++ b/src/sage/finance/stock.py @@ -551,9 +551,7 @@ def load_from_file(self, file): sage: with open(filename, 'w') as fobj: ....: _ = fobj.write("Date,Open,High,Low,Close,Volume\n1212405780,187.80,187.80,187.80,187.80,100\n1212407640,187.75,188.00,187.75,188.00,2000\n1212407700,188.00,188.00,188.00,188.00,1000\n1212408000,188.00,188.11,188.00,188.00,2877\n1212408060,188.00,188.00,188.00,188.00,687") sage: finance.Stock('aapl').load_from_file(filename)[:5] - doctest:warning... - DeprecationWarning: Importing finance from here is deprecated... - [ + ... 1212408060 188.00 188.00 188.00 188.00 687, 1212408000 188.00 188.11 188.00 188.00 2877, 1212407700 188.00 188.00 188.00 188.00 1000, From fd91cb6a89a9f947b2369cea5d9cf9a71f31dc2c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 24 Oct 2021 12:58:43 -0700 Subject: [PATCH 237/378] build/bin/sage-dist-helpers (sdh_pip_install): Pass options on to sdh_store_and_pip_install_wheel --- build/bin/sage-dist-helpers | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 91defc8a0f4..79c4e632a94 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -253,6 +253,7 @@ sdh_pip_install() { build_isolation_option="--find-links=$SAGE_SPKG_WHEELS" ;; -*) + options="$options $1" ;; *) break @@ -260,11 +261,10 @@ sdh_pip_install() { esac shift done - options="$options $build_isolation_option" - python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $options "$@" || \ + python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $options $build_isolation_option "$@" || \ sdh_die "Error building a wheel for $PKG_NAME" - sdh_store_and_pip_install_wheel . + sdh_store_and_pip_install_wheel $options . } sdh_store_wheel() { From 8f3bd8fb495a4b1a1179a55aa4d9af1501d6f565 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 28 Oct 2021 16:35:00 -0700 Subject: [PATCH 238/378] build/bin/sage-dist-helpers: Only extract special ooptions --build-isolation and --no-deps from the front, pass --no-deps only to install --- build/bin/sage-dist-helpers | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/build/bin/sage-dist-helpers b/build/bin/sage-dist-helpers index 79c4e632a94..704985a5e37 100644 --- a/build/bin/sage-dist-helpers +++ b/build/bin/sage-dist-helpers @@ -56,11 +56,12 @@ # be given as arguments. If $SAGE_DESTDIR is not set then the command is # run with $SAGE_SUDO, if set. # -# - sdh_pip_install [...] +# - sdh_pip_install [--no-deps] [--build-isolation] [...] # -# Runs `pip install` with the given arguments, as well as additional -# default arguments used for installing packages into Sage with pip. -# Currently this is just a wrapper around the `sage-pip-install` command. +# Builds a wheel using `pip wheel` with the given options [...], then installs +# the wheel. Unless the special option --build-isolation is given, +# the wheel is built using the option --no-build-isolation. +# If the special option --no-deps is given, it is passed to pip install. # If $SAGE_DESTDIR is not set then the command is run with $SAGE_SUDO, if # set. # @@ -240,8 +241,8 @@ sdh_pip_install() { echo "Installing $PKG_NAME" mkdir -p dist rm -f dist/*.whl + install_options="" # pip has --no-build-isolation but no flag that turns the default back on... - options="" build_isolation_option="--no-build-isolation --no-binary :all:" while [ $# -gt 0 ]; do case "$1" in @@ -252,8 +253,8 @@ sdh_pip_install() { # The SPKG needs to declare "setuptools_wheel" as a dependency. build_isolation_option="--find-links=$SAGE_SPKG_WHEELS" ;; - -*) - options="$options $1" + --no-deps) + install_options="$install_options $1" ;; *) break @@ -261,10 +262,10 @@ sdh_pip_install() { esac shift done - python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $options $build_isolation_option "$@" || \ + python3 -m pip wheel --use-feature=in-tree-build --wheel-dir=dist --verbose --no-deps --no-index --isolated --ignore-requires-python $build_isolation_option "$@" || \ sdh_die "Error building a wheel for $PKG_NAME" - sdh_store_and_pip_install_wheel $options . + sdh_store_and_pip_install_wheel $install_options . } sdh_store_wheel() { From bc59753278c61fca9d7b9264aa3015ec55731ea1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 24 Oct 2021 12:59:14 -0700 Subject: [PATCH 239/378] build/pkgs/flit_core/spkg-install.in: Use sdh_pip_install --no-deps --- build/pkgs/flit_core/spkg-install.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/pkgs/flit_core/spkg-install.in b/build/pkgs/flit_core/spkg-install.in index 37ac1a53437..8d6f80f4cc7 100644 --- a/build/pkgs/flit_core/spkg-install.in +++ b/build/pkgs/flit_core/spkg-install.in @@ -1,2 +1,3 @@ cd src -sdh_pip_install . +# We use --no-deps to suppress a warning regarding tomli. +sdh_pip_install --no-deps . From daddfc2da03b4df0b8c2a7d442d843028bbdeb2f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 28 Oct 2021 21:51:11 -0700 Subject: [PATCH 240/378] sage.rings.abc: Add doctests --- src/sage/rings/abc.pyx | 326 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 326 insertions(+) diff --git a/src/sage/rings/abc.pyx b/src/sage/rings/abc.pyx index 3407f8a311c..256b7d445a0 100644 --- a/src/sage/rings/abc.pyx +++ b/src/sage/rings/abc.pyx @@ -7,6 +7,24 @@ from sage.rings.ring import EuclideanDomain class NumberField_quadratic(Field): r""" Abstract base class for :class:`~sage.rings.number_field.number_field.NumberField_quadratic`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: import sage.rings.abc + sage: K. = QuadraticField(2) + sage: isinstance(K, sage.rings.abc.NumberField_quadratic) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.NumberField_quadratic.__subclasses__() + [] + + sage: len(sage.rings.abc.NumberField_quadratic.__subclasses__()) <= 1 + True """ pass @@ -15,6 +33,24 @@ class NumberField_quadratic(Field): class NumberField_cyclotomic(Field): r""" Abstract base class for :class:`~sage.rings.number_field.number_field.NumberField_cyclotomic`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: import sage.rings.abc + sage: K. = CyclotomicField(15) + sage: isinstance(K, sage.rings.abc.NumberField_cyclotomic) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.NumberField_cyclotomic.__subclasses__() + [] + + sage: len(sage.rings.abc.NumberField_cyclotomic.__subclasses__()) <= 1 + True """ pass @@ -23,6 +59,28 @@ class NumberField_cyclotomic(Field): class AlgebraicField_common(Field): r""" Abstract base class for :class:`~sage.rings.qqbar.AlgebraicField_common`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField_common) + True + sage: isinstance(AA, sage.rings.abc.AlgebraicField_common) + True + + By design, other than the abstract subclasses :class:`~sage.rings.abc.AlgebraicField` + and :class:`~sage.rings.abc.AlgebraicRealField`, there is only one direct implementation + subclass:: + + sage: sage.rings.abc.AlgebraicField_common.__subclasses__() + [, + , + ] + + sage: len(sage.rings.abc.AlgebraicField_common.__subclasses__()) <= 3 + True """ pass @@ -31,6 +89,24 @@ class AlgebraicField_common(Field): class AlgebraicField(AlgebraicField_common): r""" Abstract base class for :class:`~sage.rings.qqbar.AlgebraicField`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField) + True + sage: isinstance(AA, sage.rings.abc.AlgebraicField) + False + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.AlgebraicField.__subclasses__() + [] + + sage: len(sage.rings.abc.AlgebraicField.__subclasses__()) <= 1 + True """ pass @@ -39,6 +115,24 @@ class AlgebraicField(AlgebraicField_common): class AlgebraicRealField(AlgebraicField_common): r""" Abstract base class for :class:`~sage.rings.qqbar.AlgebraicRealField`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(QQbar, sage.rings.abc.AlgebraicRealField) + False + sage: isinstance(AA, sage.rings.abc.AlgebraicRealField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.AlgebraicRealField.__subclasses__() + [] + + sage: len(sage.rings.abc.AlgebraicRealField.__subclasses__()) <= 1 + True """ pass @@ -47,6 +141,22 @@ class AlgebraicRealField(AlgebraicField_common): cdef class RealField(Field): r""" Abstract base class for :class:`~sage.rings.real_mpfr.RealField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(RR, sage.rings.abc.RealField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.RealField.__subclasses__() + [] + + sage: len(sage.rings.abc.RealField.__subclasses__()) <= 1 + True """ pass @@ -55,6 +165,22 @@ cdef class RealField(Field): class RealBallField(Field): r""" Abstract base class for :class:`~sage.rings.real_arb.RealBallField`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(RBF, sage.rings.abc.RealBallField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.RealBallField.__subclasses__() + [] + + sage: len(sage.rings.abc.RealBallField.__subclasses__()) <= 1 + True """ pass @@ -63,6 +189,22 @@ class RealBallField(Field): cdef class RealIntervalField(Field): r""" Abstract base class for :class:`~sage.rings.real_mpfi.RealIntervalField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(RIF, sage.rings.abc.RealIntervalField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.RealIntervalField.__subclasses__() + [] + + sage: len(sage.rings.abc.RealIntervalField.__subclasses__()) <= 1 + True """ pass @@ -71,6 +213,22 @@ cdef class RealIntervalField(Field): cdef class RealDoubleField(Field): r""" Abstract base class for :class:`~sage.rings.real_double.RealDoubleField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(RDF, sage.rings.abc.RealDoubleField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.RealDoubleField.__subclasses__() + [] + + sage: len(sage.rings.abc.RealDoubleField.__subclasses__()) <= 1 + True """ pass @@ -79,6 +237,22 @@ cdef class RealDoubleField(Field): cdef class ComplexField(Field): r""" Abstract base class for :class:`~sage.rings.complex_mpfr.ComplexField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(CC, sage.rings.abc.ComplexField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.ComplexField.__subclasses__() + [] + + sage: len(sage.rings.abc.ComplexField.__subclasses__()) <= 1 + True """ pass @@ -87,6 +261,22 @@ cdef class ComplexField(Field): class ComplexBallField(Field): r""" Abstract base class for :class:`~sage.rings.complex_arb.ComplexBallField`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(CBF, sage.rings.abc.ComplexBallField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.ComplexBallField.__subclasses__() + [] + + sage: len(sage.rings.abc.ComplexBallField.__subclasses__()) <= 1 + True """ pass @@ -95,6 +285,22 @@ class ComplexBallField(Field): class ComplexIntervalField(Field): r""" Abstract base class for :class:`~sage.rings.complex_interval_field.ComplexIntervalField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(CIF, sage.rings.abc.ComplexIntervalField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.ComplexIntervalField.__subclasses__() + [] + + sage: len(sage.rings.abc.ComplexIntervalField.__subclasses__()) <= 1 + True """ pass @@ -103,6 +309,22 @@ class ComplexIntervalField(Field): cdef class ComplexDoubleField(Field): r""" Abstract base class for :class:`~sage.rings.complex_double.ComplexDoubleField_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(CDF, sage.rings.abc.ComplexDoubleField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.ComplexDoubleField.__subclasses__() + [] + + sage: len(sage.rings.abc.ComplexDoubleField.__subclasses__()) <= 1 + True """ pass @@ -111,6 +333,22 @@ cdef class ComplexDoubleField(Field): class IntegerModRing: r""" Abstract base class for :class:`~sage.rings.finite_rings.integer_mod_ring.IntegerModRing_generic`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(Integers(7), sage.rings.abc.IntegerModRing) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.IntegerModRing.__subclasses__() + [] + + sage: len(sage.rings.abc.IntegerModRing.__subclasses__()) <= 1 + True """ pass @@ -119,6 +357,23 @@ class IntegerModRing: class Order: r""" Abstract base class for :class:`~sage.rings.number_field.order.Order`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: K. = NumberField(x^2 + 1); O = K.order(2*a) + sage: isinstance(O, sage.rings.abc.Order) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.Order.__subclasses__() + [] + + sage: len(sage.rings.abc.Order.__subclasses__()) <= 1 + True """ pass @@ -127,6 +382,24 @@ class Order: class pAdicRing(EuclideanDomain): r""" Abstract base class for :class:`~sage.rings.padics.generic_nodes.pAdicRingGeneric`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(Zp(5), sage.rings.abc.pAdicRing) + True + sage: isinstance(Qp(5), sage.rings.abc.pAdicRing) + False + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.pAdicRing.__subclasses__() + [] + + sage: len(sage.rings.abc.pAdicRing.__subclasses__()) <= 1 + True """ pass @@ -135,6 +408,24 @@ class pAdicRing(EuclideanDomain): class pAdicField(Field): r""" Abstract base class for :class:`~sage.rings.padics.generic_nodes.pAdicFieldGeneric`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(Zp(5), sage.rings.abc.pAdicField) + False + sage: isinstance(Qp(5), sage.rings.abc.pAdicField) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.pAdicField.__subclasses__() + [] + + sage: len(sage.rings.abc.pAdicField.__subclasses__()) <= 1 + True """ pass @@ -143,6 +434,24 @@ class pAdicField(Field): cdef class SymbolicRing(CommutativeRing): r""" Abstract base class for :class:`~sage.rings.symbolic.ring.SymbolicRing`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: isinstance(SR, sage.rings.abc.SymbolicRing) + True + + By design, other than the abstract subclass :class:`~sage.rings.abc.CallableSymbolicExpressionRing`, + there is only one direct implementation subclass:: + + sage: sage.rings.abc.SymbolicRing.__subclasses__() + [, + ] + + sage: len(sage.rings.abc.SymbolicRing.__subclasses__()) <= 2 + True """ pass @@ -151,6 +460,23 @@ cdef class SymbolicRing(CommutativeRing): class CallableSymbolicExpressionRing(SymbolicRing): r""" Abstract base class for :class:`~sage.rings.symbolic.callable.CallableSymbolicExpressionRing_class`. + + This class is defined for the purpose of ``isinstance`` tests. It should not be + instantiated. + + EXAMPLES:: + + sage: f = x.function(x).parent() + sage: isinstance(f, sage.rings.abc.CallableSymbolicExpressionRing) + True + + By design, there is a unique direct subclass:: + + sage: sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__() + [] + + sage: len(sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__()) <= 1 + True """ pass From 5dc2d8d4b1bad8573f0aaae8034a89e2d241a849 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 28 Oct 2021 21:58:11 -0700 Subject: [PATCH 241/378] src/sage/rings/abc.pyx: Add # optional --- src/sage/rings/abc.pyx | 63 +++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/src/sage/rings/abc.pyx b/src/sage/rings/abc.pyx index 256b7d445a0..4d4e9bfd104 100644 --- a/src/sage/rings/abc.pyx +++ b/src/sage/rings/abc.pyx @@ -14,13 +14,13 @@ class NumberField_quadratic(Field): EXAMPLES:: sage: import sage.rings.abc - sage: K. = QuadraticField(2) - sage: isinstance(K, sage.rings.abc.NumberField_quadratic) + sage: K. = QuadraticField(2) # optional - sage.rings.number_field + sage: isinstance(K, sage.rings.abc.NumberField_quadratic) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.NumberField_quadratic.__subclasses__() + sage: sage.rings.abc.NumberField_quadratic.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.NumberField_quadratic.__subclasses__()) <= 1 @@ -40,13 +40,13 @@ class NumberField_cyclotomic(Field): EXAMPLES:: sage: import sage.rings.abc - sage: K. = CyclotomicField(15) - sage: isinstance(K, sage.rings.abc.NumberField_cyclotomic) + sage: K. = CyclotomicField(15) # optional - sage.rings.number_field + sage: isinstance(K, sage.rings.abc.NumberField_cyclotomic) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.NumberField_cyclotomic.__subclasses__() + sage: sage.rings.abc.NumberField_cyclotomic.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.NumberField_cyclotomic.__subclasses__()) <= 1 @@ -65,16 +65,17 @@ class AlgebraicField_common(Field): EXAMPLES:: - sage: isinstance(QQbar, sage.rings.abc.AlgebraicField_common) + sage: import sage.rings.abc + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field True - sage: isinstance(AA, sage.rings.abc.AlgebraicField_common) + sage: isinstance(AA, sage.rings.abc.AlgebraicField_common) # optional - sage.rings.number_field True By design, other than the abstract subclasses :class:`~sage.rings.abc.AlgebraicField` and :class:`~sage.rings.abc.AlgebraicRealField`, there is only one direct implementation subclass:: - sage: sage.rings.abc.AlgebraicField_common.__subclasses__() + sage: sage.rings.abc.AlgebraicField_common.__subclasses__() # optional - sage.rings.number_field [, , ] @@ -95,14 +96,15 @@ class AlgebraicField(AlgebraicField_common): EXAMPLES:: - sage: isinstance(QQbar, sage.rings.abc.AlgebraicField) + sage: import sage.rings.abc + sage: isinstance(QQbar, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field True - sage: isinstance(AA, sage.rings.abc.AlgebraicField) + sage: isinstance(AA, sage.rings.abc.AlgebraicField) # optional - sage.rings.number_field False By design, there is a unique direct subclass:: - sage: sage.rings.abc.AlgebraicField.__subclasses__() + sage: sage.rings.abc.AlgebraicField.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.AlgebraicField.__subclasses__()) <= 1 @@ -121,14 +123,15 @@ class AlgebraicRealField(AlgebraicField_common): EXAMPLES:: - sage: isinstance(QQbar, sage.rings.abc.AlgebraicRealField) + sage: import sage.rings.abc + sage: isinstance(QQbar, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field False - sage: isinstance(AA, sage.rings.abc.AlgebraicRealField) + sage: isinstance(AA, sage.rings.abc.AlgebraicRealField) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.AlgebraicRealField.__subclasses__() + sage: sage.rings.abc.AlgebraicRealField.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.AlgebraicRealField.__subclasses__()) <= 1 @@ -147,6 +150,7 @@ cdef class RealField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(RR, sage.rings.abc.RealField) True @@ -171,6 +175,7 @@ class RealBallField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(RBF, sage.rings.abc.RealBallField) True @@ -195,6 +200,7 @@ cdef class RealIntervalField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(RIF, sage.rings.abc.RealIntervalField) True @@ -219,6 +225,7 @@ cdef class RealDoubleField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(RDF, sage.rings.abc.RealDoubleField) True @@ -243,6 +250,7 @@ cdef class ComplexField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(CC, sage.rings.abc.ComplexField) True @@ -267,6 +275,7 @@ class ComplexBallField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(CBF, sage.rings.abc.ComplexBallField) True @@ -291,6 +300,7 @@ class ComplexIntervalField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(CIF, sage.rings.abc.ComplexIntervalField) True @@ -315,6 +325,7 @@ cdef class ComplexDoubleField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(CDF, sage.rings.abc.ComplexDoubleField) True @@ -339,6 +350,7 @@ class IntegerModRing: EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(Integers(7), sage.rings.abc.IntegerModRing) True @@ -363,13 +375,14 @@ class Order: EXAMPLES:: - sage: K. = NumberField(x^2 + 1); O = K.order(2*a) - sage: isinstance(O, sage.rings.abc.Order) + sage: import sage.rings.abc + sage: K. = NumberField(x^2 + 1); O = K.order(2*a) # optional - sage.rings.number_field + sage: isinstance(O, sage.rings.abc.Order) # optional - sage.rings.number_field True By design, there is a unique direct subclass:: - sage: sage.rings.abc.Order.__subclasses__() + sage: sage.rings.abc.Order.__subclasses__() # optional - sage.rings.number_field [] sage: len(sage.rings.abc.Order.__subclasses__()) <= 1 @@ -388,6 +401,7 @@ class pAdicRing(EuclideanDomain): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(Zp(5), sage.rings.abc.pAdicRing) True sage: isinstance(Qp(5), sage.rings.abc.pAdicRing) @@ -414,6 +428,7 @@ class pAdicField(Field): EXAMPLES:: + sage: import sage.rings.abc sage: isinstance(Zp(5), sage.rings.abc.pAdicField) False sage: isinstance(Qp(5), sage.rings.abc.pAdicField) @@ -440,13 +455,14 @@ cdef class SymbolicRing(CommutativeRing): EXAMPLES:: - sage: isinstance(SR, sage.rings.abc.SymbolicRing) + sage: import sage.rings.abc + sage: isinstance(SR, sage.rings.abc.SymbolicRing) # optional - sage.symbolic True By design, other than the abstract subclass :class:`~sage.rings.abc.CallableSymbolicExpressionRing`, there is only one direct implementation subclass:: - sage: sage.rings.abc.SymbolicRing.__subclasses__() + sage: sage.rings.abc.SymbolicRing.__subclasses__() # optional - sage.symbolic [, ] @@ -466,13 +482,14 @@ class CallableSymbolicExpressionRing(SymbolicRing): EXAMPLES:: - sage: f = x.function(x).parent() - sage: isinstance(f, sage.rings.abc.CallableSymbolicExpressionRing) + sage: import sage.rings.abc + sage: f = x.function(x).parent() # optional - sage.symbolic + sage: isinstance(f, sage.rings.abc.CallableSymbolicExpressionRing) # optional - sage.symbolic True By design, there is a unique direct subclass:: - sage: sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__() + sage: sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__() # optional - sage.symbolic [] sage: len(sage.rings.abc.CallableSymbolicExpressionRing.__subclasses__()) <= 1 From 01463095386995d8bbe2c487b19f67a4b70d535d Mon Sep 17 00:00:00 2001 From: dcoudert Date: Fri, 29 Oct 2021 08:37:50 +0200 Subject: [PATCH 242/378] trac #32748: remove extra spaces --- src/sage/graphs/graph_input.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 88f8bdad705..35caebb8c25 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -566,7 +566,6 @@ def from_networkx_graph(G, gnx, weighted=None, loops=None, multiedges=None, r""" Fill `G` with the data of a NetworkX (di)graph. - INPUT: - ``G`` -- a :class:`Graph` or :class:`DiGraph` @@ -581,12 +580,12 @@ def from_networkx_graph(G, gnx, weighted=None, loops=None, multiedges=None, - ``loops`` -- boolean (default: ``None``); whether to allow loops - ``multiedges`` -- boolean (default: ``None``); whether to allow multiple - edges + edges - ``convert_empty_dict_labels_to_None`` -- boolean (default: ``None``); - whether to replace the default edge labels used by NetworkX (empty - dictionaries) by ``None``, the default Sage edge label. When set to - ``False``, empty dictionaries are not converted to ``None``. + whether to replace the default edge labels used by NetworkX (empty + dictionaries) by ``None``, the default Sage edge label. When set to + ``False``, empty dictionaries are not converted to ``None``. EXAMPLES: From 6b92c81385ff5436f396fb2f34bc97f680fafb76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Oct 2021 13:58:46 +0200 Subject: [PATCH 243/378] fix pycodestyle E713 and E714 in modular/ folder --- .../modular/arithgroup/arithgroup_perm.py | 2 +- .../modular/arithgroup/congroup_gammaH.py | 11 ++--- src/sage/modular/hecke/submodule.py | 2 +- src/sage/modular/modform/ambient.py | 42 ++++++++++--------- src/sage/modular/pollack_stevens/manin_map.py | 2 +- src/sage/modular/pollack_stevens/space.py | 2 +- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/src/sage/modular/arithgroup/arithgroup_perm.py b/src/sage/modular/arithgroup/arithgroup_perm.py index fc70a66e4e1..315af89f38b 100644 --- a/src/sage/modular/arithgroup/arithgroup_perm.py +++ b/src/sage/modular/arithgroup/arithgroup_perm.py @@ -1819,7 +1819,7 @@ def cusp_widths(self,exp=False): else: c2 = len(c) // 2 if exp: - if not c2 in widths: + if c2 not in widths: widths[c2] = 0 widths[c2] += 1 else: diff --git a/src/sage/modular/arithgroup/congroup_gammaH.py b/src/sage/modular/arithgroup/congroup_gammaH.py index 2a292556944..06b42989139 100644 --- a/src/sage/modular/arithgroup/congroup_gammaH.py +++ b/src/sage/modular/arithgroup/congroup_gammaH.py @@ -930,7 +930,7 @@ def _find_cusps(self): a += w c = self.reduce_cusp(Cusp(a,d)) h = hash(c) - if not h in hashes: + if h not in hashes: hashes.append(h) s.append(c) return sorted(s) @@ -1427,13 +1427,14 @@ def _GammaH_coset_helper(N, H): for i in range(1, N): if gcd(i, N) != 1: continue - if not i in W: + if i not in W: t.append(t[0]*i) - W = W + [i*h for h in HH] + W += [i*h for h in HH] if len(W) == k: break return t + def mumu(N): """ Return 0 if any cube divides `N`. Otherwise return @@ -1464,9 +1465,9 @@ def mumu(N): if N < 1: raise ValueError("N must be at least 1") p = 1 - for _,r in factor(N): + for _, r in factor(N): if r > 2: - return ZZ(0) + return ZZ.zero() elif r == 1: p *= -2 return ZZ(p) diff --git a/src/sage/modular/hecke/submodule.py b/src/sage/modular/hecke/submodule.py index 186f08e1998..c3d54a7d030 100644 --- a/src/sage/modular/hecke/submodule.py +++ b/src/sage/modular/hecke/submodule.py @@ -158,7 +158,7 @@ def _element_constructor_(self, x, check=True): (1,23) """ z = self.ambient_hecke_module()(x).element() - if check and not z in self.__submodule: + if check and z not in self.__submodule: raise TypeError("x does not coerce to an element of this Hecke module") return self.element_class(self, z) diff --git a/src/sage/modular/modform/ambient.py b/src/sage/modular/modform/ambient.py index daf783f8fe8..febb0be8d37 100644 --- a/src/sage/modular/modform/ambient.py +++ b/src/sage/modular/modform/ambient.py @@ -58,15 +58,15 @@ True """ -#***************************************************************************** +# **************************************************************************** # Copyright (C) 2006 William Stein # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. -# http://www.gnu.org/licenses/ -#***************************************************************************** +# https://www.gnu.org/licenses/ +# **************************************************************************** import sage.modular.arithgroup.all as arithgroup import sage.modular.dirichlet as dirichlet @@ -86,6 +86,7 @@ from . import space from . import submodule + class ModularFormsAmbient(space.ModularFormsSpace, hecke.AmbientHeckeModule): """ @@ -103,13 +104,13 @@ def __init__(self, group, weight, base_ring, character=None, eis_only=False): True """ if not arithgroup.is_CongruenceSubgroup(group): - raise TypeError('group (=%s) must be a congruence subgroup'%group) + raise TypeError('group (=%s) must be a congruence subgroup' % group) weight = rings.Integer(weight) if character is None and arithgroup.is_Gamma0(group): character = dirichlet.TrivialCharacter(group.level(), base_ring) - self._eis_only=eis_only + self._eis_only = eis_only space.ModularFormsSpace.__init__(self, group, weight, character, base_ring) if eis_only: d = self._dim_eisenstein() @@ -135,10 +136,10 @@ def _repr_(self): 'Modular Forms space of dimension 1198 for Congruence Subgroup Gamma1(20) of weight 100 over Rational Field' """ if self._eis_only: - return "Modular Forms space for %s of weight %s over %s"%( + return "Modular Forms space for %s of weight %s over %s" % ( self.group(), self.weight(), self.base_ring()) else: - return "Modular Forms space of dimension %s for %s of weight %s over %s"%( + return "Modular Forms space of dimension %s for %s of weight %s over %s" % ( self.dimension(), self.group(), self.weight(), self.base_ring()) def _submodule_class(self): @@ -255,7 +256,7 @@ def _degeneracy_raising_matrix(self, M, t): im_gens = [] for x in self.basis(): fq = x.qexp(d) - fqt = fq(q**t).add_bigoh(d) # silly workaround for #5367 + fqt = fq(q**t).add_bigoh(d) # silly workaround for trac #5367 im_gens.append(M(fqt)) return A([M.coordinate_vector(u) for u in im_gens]) @@ -301,7 +302,7 @@ def is_ambient(self): """ return True - @cached_method(key=lambda self, sign: rings.Integer(sign)) # convert sign to an Integer before looking this up in the cache + @cached_method(key=lambda self, sign: rings.Integer(sign)) # convert sign to an Integer before looking this up in the cache def modular_symbols(self, sign=0): """ Return the corresponding space of modular symbols with the given @@ -323,10 +324,10 @@ def modular_symbols(self, sign=0): Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field """ sign = rings.Integer(sign) - return modsym.ModularSymbols(group = self.group(), - weight = self.weight(), - sign = sign, - base_ring = self.base_ring()) + return modsym.ModularSymbols(group=self.group(), + weight=self.weight(), + sign=sign, + base_ring=self.base_ring()) @cached_method def module(self): @@ -426,7 +427,7 @@ def set_precision(self, n): ] """ if n < 0: - raise ValueError("n (=%s) must be >= 0"%n) + raise ValueError("n (=%s) must be >= 0" % n) self.__prec = rings.Integer(n) #################################################################### @@ -460,7 +461,7 @@ def eisenstein_submodule(self): """ return eisenstein_submodule.EisensteinSubmodule(self) - @cached_method(key=lambda self, p: (rings.Integer(p) if p is not None else p)) # convert p to an Integer before looking this up in the cache + @cached_method(key=lambda self, p: (rings.Integer(p) if p is not None else p)) # convert p to an Integer before looking this up in the cache def new_submodule(self, p=None): """ Return the new or `p`-new submodule of this ambient @@ -510,10 +511,10 @@ def new_submodule(self, p=None): ... NotImplementedError """ - if not p is None: + if p is not None: p = rings.Integer(p) if not p.is_prime(): - raise ValueError("p (=%s) must be a prime or None."%p) + raise ValueError("p (=%s) must be a prime or None." % p) return self.cuspidal_submodule().new_submodule(p) + self.eisenstein_submodule().new_submodule(p) def _q_expansion(self, element, prec): @@ -798,9 +799,10 @@ def _compute_hecke_matrix(self, n): if d == 0: return matrix(self.base_ring(), 0, 0, []) from sage.modular.all import victor_miller_basis, hecke_operator_on_basis - vmb = victor_miller_basis(k, prec=d*n+1)[1:] + vmb = victor_miller_basis(k, prec=d * n + 1)[1:] Tcusp = hecke_operator_on_basis(vmb, n, k) - return Tcusp.block_sum(matrix(self.base_ring(), 1, 1, [sigma(n, k-1)])) + return Tcusp.block_sum(matrix(self.base_ring(), 1, 1, + [sigma(n, k - 1)])) else: return space.ModularFormsSpace._compute_hecke_matrix(self, n) @@ -844,4 +846,4 @@ def hecke_polynomial(self, n, var='x'): sage: ModularForms(17,4).hecke_matrix(2).charpoly() x^6 - 16*x^5 + 18*x^4 + 608*x^3 - 1371*x^2 - 4968*x + 7776 """ - return self.cuspidal_submodule().hecke_polynomial(n,var) * self.eisenstein_submodule().hecke_polynomial(n,var) + return self.cuspidal_submodule().hecke_polynomial(n, var) * self.eisenstein_submodule().hecke_polynomial(n, var) diff --git a/src/sage/modular/pollack_stevens/manin_map.py b/src/sage/modular/pollack_stevens/manin_map.py index ccb89aa8d98..21defc771d6 100644 --- a/src/sage/modular/pollack_stevens/manin_map.py +++ b/src/sage/modular/pollack_stevens/manin_map.py @@ -367,7 +367,7 @@ def compute_full_data(self): 38 """ for B in self._manin.reps(): - if not B in self._dict: + if B not in self._dict: self._dict[B] = self._compute_image_from_gens(B) def __add__(self, right): diff --git a/src/sage/modular/pollack_stevens/space.py b/src/sage/modular/pollack_stevens/space.py index f52d609b6e7..47097c27305 100644 --- a/src/sage/modular/pollack_stevens/space.py +++ b/src/sage/modular/pollack_stevens/space.py @@ -749,7 +749,7 @@ def random_element(self, M=None): ## now we compute nu_infty of Prop 5.1 of [PS1] t = self.coefficient_module().zero() for g in manin.gens()[1:]: - if (not g in manin.reps_with_two_torsion()) and (not g in manin.reps_with_three_torsion()): + if (g not in manin.reps_with_two_torsion()) and (g not in manin.reps_with_three_torsion()): t += D[g] * manin.gammas[g] - D[g] else: # this was previously MR.reps_with_two_torsion() but there is no variable MR defined... From 2578d365b3b405cbeb13f443201bbfe10841b3ef Mon Sep 17 00:00:00 2001 From: Florian Weber Date: Fri, 29 Oct 2021 16:39:34 +0200 Subject: [PATCH 244/378] improve error message of Elliptic-Curve constructor for singular Curves --- src/sage/schemes/elliptic_curves/ell_generic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/schemes/elliptic_curves/ell_generic.py b/src/sage/schemes/elliptic_curves/ell_generic.py index 965271f7241..c261b284fc6 100644 --- a/src/sage/schemes/elliptic_curves/ell_generic.py +++ b/src/sage/schemes/elliptic_curves/ell_generic.py @@ -145,7 +145,7 @@ def __init__(self, K, ainvs): self.__base_ring = K self.__ainvs = tuple(K(a) for a in ainvs) if self.discriminant() == 0: - raise ArithmeticError("invariants " + str(ainvs) + " define a singular curve") + raise ArithmeticError(self._equation_string() + " defines a singular curve") PP = projective_space.ProjectiveSpace(2, K, names='xyz') x, y, z = PP.coordinate_ring().gens() a1, a2, a3, a4, a6 = ainvs From b0f3ebc9ad1dbe2c3d2fdb9e24e31009b0e733a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Oct 2021 21:17:58 +0200 Subject: [PATCH 245/378] removing another bunch of py2/py3 tags --- src/sage/matroids/circuit_closures_matroid.pyx | 4 +--- src/sage/matroids/constructor.py | 10 ++-------- src/sage/matroids/dual_matroid.py | 8 ++------ src/sage/matroids/minor_matroid.py | 8 ++------ src/sage/matroids/utilities.py | 10 ++-------- src/sage/numerical/backends/glpk_backend.pyx | 12 ++---------- src/sage/repl/attach.py | 3 +-- src/sage/rings/morphism.pyx | 5 ++--- src/sage/rings/padics/CR_template.pxi | 5 +---- src/sage/rings/polynomial/multi_polynomial_ideal.py | 13 +++---------- src/sage/rings/polynomial/pbori/pbori.pyx | 4 +--- .../combinat_doctest.py | 7 ------- 12 files changed, 19 insertions(+), 70 deletions(-) diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 4f8844ac5fc..2b341a2d4c2 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -276,9 +276,7 @@ cdef class CircuitClosuresMatroid(Matroid): sage: M = matroids.named_matroids.Vamos() sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) - sage: sorted(X) # py2 - ['a', 'd', 'e', 'f'] - sage: sorted(X) # py3 random + sage: sorted(X) random ['a', 'd', 'e', 'f'] sage: M.is_independent(X) True diff --git a/src/sage/matroids/constructor.py b/src/sage/matroids/constructor.py index bdf12b12891..a2de93f9817 100644 --- a/src/sage/matroids/constructor.py +++ b/src/sage/matroids/constructor.py @@ -323,9 +323,7 @@ def Matroid(groundset=None, data=None, **kwds): sage: M = Matroid('abcd', circuits=['ab', 'acd']) sage: M.is_valid() True - sage: [sorted(C) for C in M.circuits()] # py2 - [['a']] - sage: [sorted(C) for C in M.circuits()] # py3 random + sage: [sorted(C) for C in M.circuits()] # random [['a']] @@ -609,11 +607,7 @@ def Matroid(groundset=None, data=None, **kwds): False sage: M.is_isomorphic(N) True - sage: Matrix(N) # py2 - [1 0 0 1 1 0] - [0 1 0 1 1 1] - [0 0 1 0 1 1] - sage: Matrix(N) # py3 random + sage: Matrix(N) # random [1 0 0 1 1 0] [0 1 0 1 1 1] [0 0 1 0 1 1] diff --git a/src/sage/matroids/dual_matroid.py b/src/sage/matroids/dual_matroid.py index a15117402ef..804e43f035b 100644 --- a/src/sage/matroids/dual_matroid.py +++ b/src/sage/matroids/dual_matroid.py @@ -188,9 +188,7 @@ def _max_independent(self, X): sage: M = matroids.named_matroids.Vamos().dual() sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) - sage: sorted(X) # py2 - ['a', 'c', 'd', 'e'] - sage: sorted(X) # py3 random + sage: sorted(X) # random ['a', 'c', 'd', 'e'] sage: M.is_independent(X) True @@ -267,9 +265,7 @@ def _max_coindependent(self, X): sage: M = matroids.named_matroids.Vamos().dual() sage: X = M._max_coindependent(set(['a', 'c', 'd', 'e', 'f'])) - sage: sorted(X) # py2 - ['a', 'd', 'e', 'f'] - sage: sorted(X) # py3 random + sage: sorted(X) # random ['a', 'd', 'e', 'f'] sage: M.is_coindependent(X) True diff --git a/src/sage/matroids/minor_matroid.py b/src/sage/matroids/minor_matroid.py index 88dea9cf1de..bc567d1d4ce 100644 --- a/src/sage/matroids/minor_matroid.py +++ b/src/sage/matroids/minor_matroid.py @@ -225,9 +225,7 @@ def _max_independent(self, X): sage: M = MinorMatroid(matroids.named_matroids.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) sage: X = M._max_independent(set(['a', 'd', 'e', 'g'])) - sage: sorted(X) # py2 - ['a', 'd', 'e'] - sage: sorted(X) # py3 # random + sage: sorted(X) # random ['a', 'd', 'e'] sage: M.is_independent(X) True @@ -279,9 +277,7 @@ def _max_coindependent(self, X): sage: M = MinorMatroid(matroids.named_matroids.Vamos(), ....: contractions=set('c'), deletions={'b', 'f'}) sage: X = M._max_coindependent(set(['a', 'd', 'e', 'g'])) - sage: sorted(X) # py2 - ['d', 'g'] - sage: sorted(X) # py3 random + sage: sorted(X) # random ['d', 'g'] sage: M.is_coindependent(X) True diff --git a/src/sage/matroids/utilities.py b/src/sage/matroids/utilities.py index 62742ede0bf..f856e32c87d 100644 --- a/src/sage/matroids/utilities.py +++ b/src/sage/matroids/utilities.py @@ -62,9 +62,7 @@ def setprint(X): sage: from sage.matroids.advanced import setprint sage: L = [{1, 2, 3}, {1, 2, 4}, {2, 3, 4}, {4, 1, 3}] - sage: print(L) # py2 - [set([1, 2, 3]), set([1, 2, 4]), set([2, 3, 4]), set([1, 3, 4])] - sage: print(L) # py3 + sage: print(L) [{1, 2, 3}, {1, 2, 4}, {2, 3, 4}, {1, 3, 4}] sage: setprint(L) [{1, 2, 3}, {1, 2, 4}, {1, 3, 4}, {2, 3, 4}] @@ -538,11 +536,7 @@ def lift_cross_ratios(A, lift_map=None): [6 1 0 0 1] [0 6 3 6 0] sage: Z = lift_cross_ratios(A, to_sixth_root_of_unity) - sage: Z # py2 - [ 1 0 1 1 1] - [ 1 1 0 0 z] - [ 0 1 -z -1 0] - sage: Z # py3 + sage: Z [ 1 0 1 1 1] [ 1 1 0 0 z] [ 0 -1 z 1 0] diff --git a/src/sage/numerical/backends/glpk_backend.pyx b/src/sage/numerical/backends/glpk_backend.pyx index 26f037647ed..3a60b981b43 100644 --- a/src/sage/numerical/backends/glpk_backend.pyx +++ b/src/sage/numerical/backends/glpk_backend.pyx @@ -1646,11 +1646,7 @@ cdef class GLPKBackend(GenericBackend): sage: p.add_variable() 0 - sage: p.variable_upper_bound(0, 'hey!') # py2 - Traceback (most recent call last): - ... - TypeError: a float is required - sage: p.variable_upper_bound(0, 'hey!') # py3 + sage: p.variable_upper_bound(0, 'hey!') Traceback (most recent call last): ... TypeError: must be real number, not str @@ -1750,11 +1746,7 @@ cdef class GLPKBackend(GenericBackend): sage: p.add_variable() 0 - sage: p.variable_lower_bound(0, 'hey!') # py2 - Traceback (most recent call last): - ... - TypeError: a float is required - sage: p.variable_lower_bound(0, 'hey!') # py3 + sage: p.variable_lower_bound(0, 'hey!') Traceback (most recent call last): ... TypeError: must be real number, not str diff --git a/src/sage/repl/attach.py b/src/sage/repl/attach.py index b4c4e63c699..8cbe64c1f94 100644 --- a/src/sage/repl/attach.py +++ b/src/sage/repl/attach.py @@ -249,8 +249,7 @@ def reset_load_attach_path(): sage: reset_load_attach_path(); load_attach_path() ['.'] sage: os.environ['SAGE_LOAD_ATTACH_PATH'] = '/veni/vidi:vici:' - sage: from imp import reload # py2 - sage: from importlib import reload # py3 + sage: from importlib import reload sage: reload(sage.repl.attach) # Simulate startup sage: load_attach_path() diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 8cf7181feed..6a96df172d8 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -1640,14 +1640,13 @@ cdef class RingHomomorphism_coercion(RingHomomorphism): sage: TestSuite(f).run() """ - def __init__(self, parent, check = True): + def __init__(self, parent, check=True): r""" TESTS: sage: from sage.rings.morphism import RingHomomorphism_coercion sage: parent = Hom(ZZ,ZZ) - sage: f = parent.__make_element_class__(RingHomomorphism_coercion)(parent) # py2 - sage: f = parent.__make_element_class__(RingHomomorphism_coercion)(parent) # py3 + sage: f = parent.__make_element_class__(RingHomomorphism_coercion)(parent) doctest:warning ... DeprecationWarning: Set the category of your morphism to a subcategory of Rings instead. diff --git a/src/sage/rings/padics/CR_template.pxi b/src/sage/rings/padics/CR_template.pxi index 7318873f9c5..3b9811827f3 100644 --- a/src/sage/rings/padics/CR_template.pxi +++ b/src/sage/rings/padics/CR_template.pxi @@ -1528,12 +1528,9 @@ cdef class CRElement(pAdicTemplateElement): sage: hash(R(17)) #indirect doctest 17 - sage: hash(R(-1)) # py3 + sage: hash(R(-1)) 1977844648 # 32-bit 95367431640624 # 64-bit - sage: hash(R(-1)) # py2 - 1977822444 # 32-bit - 95367431640624 # 64-bit """ if exactzero(self.ordp): return 0 diff --git a/src/sage/rings/polynomial/multi_polynomial_ideal.py b/src/sage/rings/polynomial/multi_polynomial_ideal.py index 07e0656baa5..c6d7dbc15c0 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ideal.py +++ b/src/sage/rings/polynomial/multi_polynomial_ideal.py @@ -2367,10 +2367,7 @@ def variety(self, ring=None): sage: sorted(I.variety(ring=RR), key=str) [{y: 0.361103080528647, x: 2.76929235423863}, {y: 1.00000000000000, x: 1.00000000000000}] - sage: I.variety(ring=AA) # py2 - [{x: 1, y: 1}, - {x: 2.769292354238632?, y: 0.3611030805286474?}] - sage: I.variety(ring=AA) # py3 + sage: I.variety(ring=AA) [{y: 1, x: 1}, {y: 0.3611030805286474?, x: 2.769292354238632?}] @@ -5012,9 +5009,7 @@ def weil_restriction(self): Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2 sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal - sage: J.variety() # py2 - [{y1: 1, x1: 1, x0: 1, y0: 0}] - sage: J.variety() # py3 + sage: J.variety() [{y1: 1, y0: 0, x1: 1, x0: 1}] sage: J.weil_restriction() # returns J @@ -5027,9 +5022,7 @@ def weil_restriction(self): sage: I = sage.rings.ideal.Katsura(P) sage: I.dimension() 0 - sage: I.variety() # py2 - [{y: 0, z: 0, x: 1}] - sage: I.variety() # py3 + sage: I.variety() [{z: 0, y: 0, x: 1}] sage: J = I.weil_restriction(); J diff --git a/src/sage/rings/polynomial/pbori/pbori.pyx b/src/sage/rings/polynomial/pbori/pbori.pyx index 615357f9aac..fafe1b30e72 100644 --- a/src/sage/rings/polynomial/pbori/pbori.pyx +++ b/src/sage/rings/polynomial/pbori/pbori.pyx @@ -1378,9 +1378,7 @@ cdef class BooleanPolynomialRing(MPolynomialRing_base): EXAMPLES:: sage: P. = BooleanPolynomialRing(3) - sage: [P._random_monomial_dfirst(3, (0,1,2)) for _ in range(10)] # py2 - [x*y*z, x*y*z, x*y*z, y*z, x*z, z, z, y*z, x*y*z, 1] - sage: [P._random_monomial_dfirst(3, (0,1,2)) for _ in range(10)] # py3 random + sage: [P._random_monomial_dfirst(3, (0,1,2)) for _ in range(10)] # random [x*y*z, x*y*z, x*y*z, x*y, x*z, x, x, y*z, x*y*z, 1] """ from sage.rings.integer_ring import ZZ diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py index 2a834741f4e..9dc4f6e430a 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/combinat_doctest.py @@ -288,13 +288,6 @@ [[[], [1, 2, 4], [1, 3], [1, 3, 4], [1, 4], [2], [2, 3], [2, 4], [4]], [[], [1, 2, 4], [1, 3], [2, 4], [3, 4]]] -Sage example in ./combinat.tex, line 1203:: - - sage: len(S) # py2 - Traceback (most recent call last): - ... - OverflowError: Python int too large to convert to C long - Sage example in ./combinat.tex, line 1237:: sage: P5 = Partitions(5); P5 From d05de3fe005feb99157b66dae0971e3c70698421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Fri, 29 Oct 2021 21:23:18 +0200 Subject: [PATCH 246/378] remove py2 tags in two more files --- src/sage/repl/ipython_kernel/interact.py | 8 ++------ src/sage/repl/ipython_kernel/widgets_sagenb.py | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 1e344d8373f..42f1b3e7291 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -140,9 +140,7 @@ def signature(self): sage: from sage.repl.ipython_kernel.interact import sage_interactive sage: def myfunc(x=[1,2,3], auto_update=False): pass - sage: sage_interactive(myfunc).signature().parameters # py2 - OrderedDict([('x', )]) - sage: sage_interactive(myfunc).signature().parameters # py3 + sage: sage_interactive(myfunc).signature().parameters mappingproxy({'x': }) """ return self.__signature @@ -203,9 +201,7 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): IntSlider(value=5, description=u'number', max=10) sage: sage_interactive.widget_from_tuple( (3, (0, 10)) ) IntSlider(value=3, max=10) - sage: sage_interactive.widget_from_tuple((2, dict(one=1, two=2, three=3))) # py2 - Dropdown(index=1, options={'three': 3, 'two': 2, 'one': 1}, value=2) - sage: sage_interactive.widget_from_tuple((2, dict(one=1, two=2, three=3))) # py3 + sage: sage_interactive.widget_from_tuple((2, dict(one=1, two=2, three=3))) Dropdown(index=1, options={'one': 1, 'two': 2, 'three': 3}, value=2) sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 33ce4898ca7..f01b99e60c6 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -458,13 +458,9 @@ def selector(values, label=None, default=None, nrows=None, ncols=None, width=Non is not ordered, it is better to use an :class:`OrderedDict`:: sage: from collections import OrderedDict - sage: selector(OrderedDict(one=1, two=2, three=3)) # py2 - Dropdown(options=OrderedDict([('one', 1), ('three', 3), ('two', 2)]), value=1) - sage: selector(OrderedDict(one=1, two=2, three=3)) # py3 + sage: selector(OrderedDict(one=1, two=2, three=3)) Dropdown(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1) - sage: selector(OrderedDict(one=1, two=2, three=3), buttons=True) # py2 - ToggleButtons(options=OrderedDict([('one', 1), ('three', 3), ('two', 2)]), value=1) - sage: selector(OrderedDict(one=1, two=2, three=3), buttons=True) # py3 + sage: selector(OrderedDict(one=1, two=2, three=3), buttons=True) ToggleButtons(options=OrderedDict([('one', 1), ('two', 2), ('three', 3)]), value=1) The values can be any kind of object: From 906abfeea7343d2c2afd49dd9912bb31cf05e978 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 13:57:56 -0700 Subject: [PATCH 247/378] sage.functions.log.log: Move to sage.misc.functional, replacing deprecated function log --- src/sage/functions/log.py | 183 +------------------------------ src/sage/misc/functional.py | 207 ++++++++++++++++++++++++++++++------ 2 files changed, 177 insertions(+), 213 deletions(-) diff --git a/src/sage/functions/log.py b/src/sage/functions/log.py index 291b71499fa..d322305b223 100644 --- a/src/sage/functions/log.py +++ b/src/sage/functions/log.py @@ -21,6 +21,8 @@ from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ +from sage.misc.functional import log as log + class Function_exp(GinacFunction): r""" @@ -274,187 +276,6 @@ def __init__(self): logb = Function_log2() -def log(*args, **kwds): - """ - Return the logarithm of the first argument to the base of - the second argument which if missing defaults to ``e``. - - It calls the ``log`` method of the first argument when computing - the logarithm, thus allowing the use of logarithm on any object - containing a ``log`` method. In other words, ``log`` works - on more than just real numbers. - - EXAMPLES:: - - sage: log(e^2) - 2 - - To change the base of the logarithm, add a second parameter:: - - sage: log(1000,10) - 3 - - The synonym ``ln`` can only take one argument:: - - sage: ln(RDF(10)) - 2.302585092994046 - sage: ln(2.718) - 0.999896315728952 - sage: ln(2.0) - 0.693147180559945 - sage: ln(float(-1)) - 3.141592653589793j - sage: ln(complex(-1)) - 3.141592653589793j - - You can use - :class:`RDF`, - :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a - numerical real approximation:: - - sage: log(1024, 2) - 10 - sage: RDF(log(1024, 2)) - 10.0 - sage: log(10, 4) - 1/2*log(10)/log(2) - sage: RDF(log(10, 4)) - 1.6609640474436813 - sage: log(10, 2) - log(10)/log(2) - sage: n(log(10, 2)) - 3.32192809488736 - sage: log(10, e) - log(10) - sage: n(log(10, e)) - 2.30258509299405 - - The log function works for negative numbers, complex - numbers, and symbolic numbers too, picking the branch - with angle between `-\\pi` and `\\pi`:: - - sage: log(-1+0*I) - I*pi - sage: log(CC(-1)) - 3.14159265358979*I - sage: log(-1.0) - 3.14159265358979*I - - Small integer powers are factored out immediately:: - - sage: log(4) - 2*log(2) - sage: log(1000000000) - 9*log(10) - sage: log(8) - 3*log(2) - 0 - sage: bool(log(8) == 3*log(2)) - True - - The ``hold`` parameter can be used to prevent automatic evaluation:: - - sage: log(-1,hold=True) - log(-1) - sage: log(-1) - I*pi - sage: I.log(hold=True) - log(I) - sage: I.log(hold=True).simplify() - 1/2*I*pi - - For input zero, the following behavior occurs:: - - sage: log(0) - -Infinity - sage: log(CC(0)) - -infinity - sage: log(0.0) - -infinity - - The log function also works in finite fields as long as the - argument lies in the multiplicative group generated by the base:: - - sage: F = GF(13); g = F.multiplicative_generator(); g - 2 - sage: a = F(8) - sage: log(a,g); g^log(a,g) - 3 - 8 - sage: log(a,3) - Traceback (most recent call last): - ... - ValueError: no logarithm of 8 found to base 3 modulo 13 - sage: log(F(9), 3) - 2 - - The log function also works for p-adics (see documentation for - p-adics for more information):: - - sage: R = Zp(5); R - 5-adic Ring with capped relative precision 20 - sage: a = R(16); a - 1 + 3*5 + O(5^20) - sage: log(a) - 3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + - 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + - 3*5^19 + O(5^20) - - - TESTS: - - Check if :trac:`10136` is fixed:: - - sage: ln(x).operator() is ln - True - sage: log(x).operator() is ln - True - - sage: log(1000, 10) - 3 - sage: log(3,-1) - -I*log(3)/pi - sage: log(int(8),2) - 3 - sage: log(8,int(2)) - 3 - sage: log(8,2) - 3 - sage: log(1/8,2) - -3 - sage: log(1/8,1/2) - 3 - sage: log(8,1/2) - -3 - - sage: log(1000, 10, base=5) - Traceback (most recent call last): - ... - TypeError: Symbolic function log takes at most 2 arguments (3 given) - - Check if :trac:`29164` is fixed:: - - sage: log(0, 2) - -Infinity - """ - base = kwds.pop('base', None) - if base: - args = args + (base,) - if not args: - raise TypeError("Symbolic function log takes at least 1 arguments (0 given)") - if len(args) == 1: - return ln(args[0], **kwds) - if len(args) > 2: - raise TypeError("Symbolic function log takes at most 2 arguments (%s given)" % (len(args) + 1 - (base is not None))) - try: - return args[0].log(args[1]) - except ValueError as ex: - if ex.args[0].startswith("no logarithm"): - raise - return logb(args[0], args[1]) - except (AttributeError, TypeError): - return logb(args[0], args[1]) - - class Function_polylog(GinacFunction): def __init__(self): r""" diff --git a/src/sage/misc/functional.py b/src/sage/misc/functional.py index b5430b48207..6ab5c6eeeab 100644 --- a/src/sage/misc/functional.py +++ b/src/sage/misc/functional.py @@ -992,19 +992,15 @@ def lift(x): raise ArithmeticError("no lift defined.") -def log(x, b=None): - r""" - Return the log of ``x`` to the base `b`. The default base is `e`. - - DEPRECATED by :trac:`19444` - - INPUT: - - - ``x`` -- number - - - `b` -- base (default: ``None``, which means natural log) +def log(*args, **kwds): + """ + Return the logarithm of the first argument to the base of + the second argument which if missing defaults to ``e``. - OUTPUT: number + It calls the ``log`` method of the first argument when computing + the logarithm, thus allowing the use of logarithm on any object + containing a ``log`` method. In other words, ``log`` works + on more than just real numbers. .. NOTE:: @@ -1014,28 +1010,175 @@ def log(x, b=None): EXAMPLES:: - sage: from sage.misc.functional import log sage: log(e^2) - doctest:warning... - DeprecationWarning: use .log() or log() from sage.functions.log instead - See http://trac.sagemath.org/19444 for details. 2 - sage: log(16,2) - 4 - sage: log(3.) - 1.09861228866811 - sage: log(float(3)) # abs tol 1e-15 - 1.0986122886681098 - """ - deprecation(19444, 'use .log() or log() from sage.functions.log instead') - if b is None: - if hasattr(x, 'log'): - return x.log() - return RDF(x).log() - else: - if hasattr(x, 'log'): - return x.log(b) - return RDF(x).log(b) + + To change the base of the logarithm, add a second parameter:: + + sage: log(1000,10) + 3 + + The synonym ``ln`` can only take one argument:: + + sage: ln(RDF(10)) + 2.302585092994046 + sage: ln(2.718) + 0.999896315728952 + sage: ln(2.0) + 0.693147180559945 + sage: ln(float(-1)) + 3.141592653589793j + sage: ln(complex(-1)) + 3.141592653589793j + + You can use + :class:`RDF`, + :class:`~sage.rings.real_mpfr.RealField` or ``n`` to get a + numerical real approximation:: + + sage: log(1024, 2) + 10 + sage: RDF(log(1024, 2)) + 10.0 + sage: log(10, 4) + 1/2*log(10)/log(2) + sage: RDF(log(10, 4)) + 1.6609640474436813 + sage: log(10, 2) + log(10)/log(2) + sage: n(log(10, 2)) + 3.32192809488736 + sage: log(10, e) + log(10) + sage: n(log(10, e)) + 2.30258509299405 + + The log function works for negative numbers, complex + numbers, and symbolic numbers too, picking the branch + with angle between `-\\pi` and `\\pi`:: + + sage: log(-1+0*I) + I*pi + sage: log(CC(-1)) + 3.14159265358979*I + sage: log(-1.0) + 3.14159265358979*I + + Small integer powers are factored out immediately:: + + sage: log(4) + 2*log(2) + sage: log(1000000000) + 9*log(10) + sage: log(8) - 3*log(2) + 0 + sage: bool(log(8) == 3*log(2)) + True + + The ``hold`` parameter can be used to prevent automatic evaluation:: + + sage: log(-1,hold=True) + log(-1) + sage: log(-1) + I*pi + sage: I.log(hold=True) + log(I) + sage: I.log(hold=True).simplify() + 1/2*I*pi + + For input zero, the following behavior occurs:: + + sage: log(0) + -Infinity + sage: log(CC(0)) + -infinity + sage: log(0.0) + -infinity + + The log function also works in finite fields as long as the + argument lies in the multiplicative group generated by the base:: + + sage: F = GF(13); g = F.multiplicative_generator(); g + 2 + sage: a = F(8) + sage: log(a,g); g^log(a,g) + 3 + 8 + sage: log(a,3) + Traceback (most recent call last): + ... + ValueError: no logarithm of 8 found to base 3 modulo 13 + sage: log(F(9), 3) + 2 + + The log function also works for p-adics (see documentation for + p-adics for more information):: + + sage: R = Zp(5); R + 5-adic Ring with capped relative precision 20 + sage: a = R(16); a + 1 + 3*5 + O(5^20) + sage: log(a) + 3*5 + 3*5^2 + 3*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 2*5^8 + 5^9 + + 5^11 + 2*5^12 + 5^13 + 3*5^15 + 2*5^16 + 4*5^17 + 3*5^18 + + 3*5^19 + O(5^20) + + + TESTS: + + Check if :trac:`10136` is fixed:: + + sage: ln(x).operator() is ln + True + sage: log(x).operator() is ln + True + + sage: log(1000, 10) + 3 + sage: log(3,-1) + -I*log(3)/pi + sage: log(int(8),2) + 3 + sage: log(8,int(2)) + 3 + sage: log(8,2) + 3 + sage: log(1/8,2) + -3 + sage: log(1/8,1/2) + 3 + sage: log(8,1/2) + -3 + + sage: log(1000, 10, base=5) + Traceback (most recent call last): + ... + TypeError: log takes at most 2 arguments (3 given) + + Check if :trac:`29164` is fixed:: + + sage: log(0, 2) + -Infinity + """ + base = kwds.pop('base', None) + if base: + args = args + (base,) + if not args: + raise TypeError("log takes at least 1 arguments (0 given)") + if len(args) == 1: + from sage.functions.log import ln + return ln(args[0], **kwds) + if len(args) > 2: + raise TypeError("log takes at most 2 arguments (%s given)" % (len(args) + 1 - (base is not None))) + try: + return args[0].log(args[1]) + except ValueError as ex: + if ex.args[0].startswith("no logarithm"): + raise + except (AttributeError, TypeError): + pass + from sage.functions.log import logb + return logb(args[0], args[1]) def minimal_polynomial(x, var='x'): From 5798a1cf996cfd546dcfe2b68007adda4ddad349 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:14:15 -0700 Subject: [PATCH 248/378] src/sage/coding/code_bounds.py: Import log from sage.misc.functional, add # optional - sage.symbolic to some doctests --- src/sage/coding/code_bounds.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/coding/code_bounds.py b/src/sage/coding/code_bounds.py index 9f5640ca1f4..f143aae7765 100644 --- a/src/sage/coding/code_bounds.py +++ b/src/sage/coding/code_bounds.py @@ -177,8 +177,7 @@ from sage.rings.all import QQ, RR, ZZ, RDF from sage.arith.misc import is_prime_power from sage.arith.all import binomial -from sage.functions.all import log -from sage.misc.functional import sqrt +from sage.misc.functional import sqrt, log from .delsarte_bounds import (delsarte_bound_hamming_space, delsarte_bound_additive_hamming_space) @@ -582,9 +581,9 @@ def entropy(x, q=2): sage: codes.bounds.entropy(0, 2) 0 - sage: codes.bounds.entropy(1/5,4).factor() + sage: codes.bounds.entropy(1/5,4).factor() # optional - sage.symbolic 1/10*(log(3) - 4*log(4/5) - log(1/5))/log(2) - sage: codes.bounds.entropy(1, 3) + sage: codes.bounds.entropy(1, 3) # optional - sage.symbolic log(2)/log(3) Check that values not within the limits are properly handled:: From 073411938fb470f00b31e9fa10e3eebb97b7b61d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:18:44 -0700 Subject: [PATCH 249/378] src/sage/graphs/generators/distance_regular.pyx: Import log from sage.misc.functional --- src/sage/graphs/generators/distance_regular.pyx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/sage/graphs/generators/distance_regular.pyx b/src/sage/graphs/generators/distance_regular.pyx index 55eee4d0a03..7b0479bad51 100644 --- a/src/sage/graphs/generators/distance_regular.pyx +++ b/src/sage/graphs/generators/distance_regular.pyx @@ -1865,7 +1865,7 @@ def is_classical_parameters_graph(list array): sage: is_classical_parameters_graph([27, 10, 1, 1, 10, 27]) False """ - from sage.functions.log import log + from sage.misc.functional import log from sage.rings.integer_ring import ZZ from sage.arith.misc import is_prime_power from sage.combinat.q_analogues import q_binomial @@ -2099,8 +2099,7 @@ def graph_with_classical_parameters(int d, int b, alpha_in, beta_in, int gamma): Generalised hexagon of order (2, 8): Graph on 819 vertices """ from sage.rings.rational import Rational - from sage.functions.log import log - from sage.misc.functional import sqrt + from sage.misc.functional import sqrt, log from sage.graphs.generators.families import JohnsonGraph, HammingGraph from sage.graphs.generators.classical_geometries import \ UnitaryDualPolarGraph, OrthogonalDualPolarGraph, SymplecticDualPolarGraph @@ -2383,7 +2382,7 @@ def is_near_polygon(array): """ from sage.arith.misc import is_prime_power from sage.combinat.q_analogues import q_binomial - from sage.functions.log import log + from sage.misc.functional import log if len(array) % 2 != 0: return False From 796b48b2bd89028a599c17c65b1e003026139d8f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:22:07 -0700 Subject: [PATCH 250/378] src/sage/coding/kasami_codes.pyx: Import log from sage.misc.functional --- src/sage/coding/kasami_codes.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/coding/kasami_codes.pyx b/src/sage/coding/kasami_codes.pyx index 09bb3cef4d1..2835e19b8de 100644 --- a/src/sage/coding/kasami_codes.pyx +++ b/src/sage/coding/kasami_codes.pyx @@ -322,7 +322,7 @@ class KasamiCode(AbstractLinearCode): sage: C.minimum_distance() 3 """ - from sage.functions.log import log + from sage.misc.functional import log m = log(self._s, 2) F = GF(self._s) From 0f775a214d3f4f2a16809ae7e71635187fecced6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:23:51 -0700 Subject: [PATCH 251/378] src/sage/misc/dev_tools.py: Update doctest regarding import_statements('log') --- src/sage/misc/dev_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/dev_tools.py b/src/sage/misc/dev_tools.py index 62d49bab39a..9864633df04 100644 --- a/src/sage/misc/dev_tools.py +++ b/src/sage/misc/dev_tools.py @@ -493,7 +493,7 @@ def import_statements(*objects, **kwds): :trac:`23779`):: sage: import_statements('log') - from sage.functions.log import log + from sage.misc.functional import log .. NOTE:: From 6be920adfce2571b18ecff648cec612454233d48 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:25:44 -0700 Subject: [PATCH 252/378] src/sage/combinat/words/finite_word.py: Change import of log for symbolic use to import from sage.functions.log --- src/sage/combinat/words/finite_word.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 609e701f7c7..18c02267c49 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1496,7 +1496,7 @@ def topological_entropy(self, n): if n == 0: return 1 pn = self.number_of_factors(n) - from sage.functions.all import log + from sage.functions.log import log return log(pn, base=d)/n def rauzy_graph(self, n): From 238e97efede530f77d5d802be867501cb5878c1e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 14:27:57 -0700 Subject: [PATCH 253/378] src/sage/matrix/operation_table.py: Change non-symbolic use of log to import from sage.misc.functional --- src/sage/matrix/operation_table.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/matrix/operation_table.py b/src/sage/matrix/operation_table.py index 6feda2215a5..6834d010c50 100644 --- a/src/sage/matrix/operation_table.py +++ b/src/sage/matrix/operation_table.py @@ -540,8 +540,8 @@ def _name_maker(self, names): ... ValueError: element names must be a list, or one of the keywords: 'letters', 'digits', 'elements' """ - from sage.functions.log import log - name_list=[] + from sage.misc.functional import log + name_list = [] if names == 'digits': if self._n == 0 or self._n == 1: width = 1 From d05e0fb75178c73034003fc9a31b6ff6f6442df6 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Sat, 30 Oct 2021 15:20:46 +0800 Subject: [PATCH 254/378] avoid crashing if extensions are already not in the list --- src/sage_docbuild/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sage_docbuild/__init__.py b/src/sage_docbuild/__init__.py index 2368d6cbf31..f27c6cf086e 100644 --- a/src/sage_docbuild/__init__.py +++ b/src/sage_docbuild/__init__.py @@ -1231,7 +1231,7 @@ def __init__(self, path): # Write self.dir/conf.py conf = r"""# This file is automatically generated by {}, do not edit! -import sys, os +import sys, os, contextlib sys.path.append({!r}) from sage.docs.conf import * @@ -1244,8 +1244,9 @@ def __init__(self, path): html_short_title = project htmlhelp_basename = name -extensions.remove('multidocs') # see #29651 -extensions.remove('inventory_builder') +with contextlib.suppress(ValueError): + extensions.remove('multidocs') # see #29651 + extensions.remove('inventory_builder') latex_domain_indices = False latex_documents = [ From e9076a2ecdaf9c7073ccafad68de3a2ef45687b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 30 Oct 2021 11:38:08 +0200 Subject: [PATCH 255/378] fix typo --- src/sage/matroids/circuit_closures_matroid.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/matroids/circuit_closures_matroid.pyx b/src/sage/matroids/circuit_closures_matroid.pyx index 2b341a2d4c2..2411e52fa81 100644 --- a/src/sage/matroids/circuit_closures_matroid.pyx +++ b/src/sage/matroids/circuit_closures_matroid.pyx @@ -276,7 +276,7 @@ cdef class CircuitClosuresMatroid(Matroid): sage: M = matroids.named_matroids.Vamos() sage: X = M._max_independent(set(['a', 'c', 'd', 'e', 'f'])) - sage: sorted(X) random + sage: sorted(X) # random ['a', 'd', 'e', 'f'] sage: M.is_independent(X) True From c2cde679ca4562912d8a38ea55f2af59d76192c7 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 30 Oct 2021 13:03:02 +0200 Subject: [PATCH 256/378] Explicitly set MPMATH_SAGE env variable --- src/bin/sage-env | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bin/sage-env b/src/bin/sage-env index b4c0c6ea207..15210dda7e2 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -652,6 +652,11 @@ if [ -z "$CYSIGNALS_CRASH_LOGS" ]; then export CYSIGNALS_CRASH_DAYS=7 # keep logs for 7 days fi +# Make sure mpmath uses Sage types +if [ -z "$MPMATH_SAGE" ]; then + export MPMATH_SAGE=1 +fi + # You can set environment variables in $SAGE_RC_FILE # (by default, this is the file $DOT_SAGE/sagerc). For example, # setting PS1 there will set your prompt when you run "sage --sh". From 143e90728caf2c225d09da801f13d9d9cbc20f1a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Oct 2021 12:33:05 -0700 Subject: [PATCH 257/378] tox.ini (local): passenv OPENBLAS_CONFIGURE --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 9bd5ece819d..2b31b5f0b01 100644 --- a/tox.ini +++ b/tox.ini @@ -117,6 +117,7 @@ passenv = local: SKIP_SYSTEM_PKG_INSTALL local: SKIP_BOOTSTRAP local: SKIP_CONFIGURE + local: OPENBLAS_CONFIGURE local-direct: * setenv = From d4b1b607d99af26b01eccf28512f89d2cbcef6d3 Mon Sep 17 00:00:00 2001 From: Antonio Rojas Date: Sat, 30 Oct 2021 21:36:29 +0200 Subject: [PATCH 258/378] Set the env variable in the Sage python library --- src/bin/sage-env | 5 ----- src/sage/env.py | 3 +++ 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/bin/sage-env b/src/bin/sage-env index 15210dda7e2..b4c0c6ea207 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -652,11 +652,6 @@ if [ -z "$CYSIGNALS_CRASH_LOGS" ]; then export CYSIGNALS_CRASH_DAYS=7 # keep logs for 7 days fi -# Make sure mpmath uses Sage types -if [ -z "$MPMATH_SAGE" ]; then - export MPMATH_SAGE=1 -fi - # You can set environment variables in $SAGE_RC_FILE # (by default, this is the file $DOT_SAGE/sagerc). For example, # setting PS1 there will set your prompt when you run "sage --sh". diff --git a/src/sage/env.py b/src/sage/env.py index e5af0374a2f..40ace135f0d 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -237,6 +237,9 @@ def var(key: str, *fallbacks: Optional[str], force: bool = False) -> Optional[st OPENMP_CFLAGS = var("OPENMP_CFLAGS", "") OPENMP_CXXFLAGS = var("OPENMP_CXXFLAGS", "") +# Make sure mpmath uses Sage types +os.environ['MPMATH_SAGE'] = '1' + # misc SAGE_BANNER = var("SAGE_BANNER", "") SAGE_IMPORTALL = var("SAGE_IMPORTALL", "yes") From fee0403038081c5f2b1a2a52c6950e34d31e8569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 30 Oct 2021 21:54:19 +0200 Subject: [PATCH 259/378] clean up various details in combinat --- src/sage/combinat/cartesian_product.py | 2 +- src/sage/combinat/composition.py | 2 +- src/sage/combinat/designs/database.py | 7 +++---- .../combinat/designs/incidence_structures.py | 12 ++++++------ src/sage/combinat/e_one_star.py | 2 +- src/sage/combinat/finite_state_machine.py | 4 ++-- src/sage/combinat/free_module.py | 4 ++-- src/sage/combinat/gelfand_tsetlin_patterns.py | 10 +++++----- src/sage/combinat/integer_vector_weighted.py | 8 ++++---- .../combinat/integer_vectors_mod_permgroup.py | 18 +++++++++--------- src/sage/combinat/matrices/dancing_links.pyx | 10 +++++----- .../multiset_partition_into_sets_ordered.py | 5 ++++- src/sage/combinat/partitions.pyx | 6 +++--- src/sage/combinat/posets/poset_examples.py | 5 +++-- src/sage/combinat/ranker.py | 4 ++-- .../root_lattice_realization_algebras.py | 10 ++++++---- .../combinat/root_system/type_reducible.py | 6 +++--- .../root_system/weight_lattice_realizations.py | 6 +++--- src/sage/combinat/skew_partition.py | 15 ++++++--------- src/sage/combinat/sloane_functions.py | 4 ++-- src/sage/combinat/tableau.py | 2 +- src/sage/combinat/tiling.py | 7 +++---- src/sage/combinat/words/finite_word.py | 10 +++++----- src/sage/combinat/words/words.py | 4 ++-- 24 files changed, 82 insertions(+), 81 deletions(-) diff --git a/src/sage/combinat/cartesian_product.py b/src/sage/combinat/cartesian_product.py index e2069f38e53..7b9cf8e62e6 100644 --- a/src/sage/combinat/cartesian_product.py +++ b/src/sage/combinat/cartesian_product.py @@ -57,7 +57,7 @@ class for ``cartesian_product``; sage: c = cartesian_product([F1, F2, F3]) sage: type(C.an_element()) - <... 'list'> + sage: type(c.an_element()) diff --git a/src/sage/combinat/composition.py b/src/sage/combinat/composition.py index 5f899c71106..46a6be10fad 100644 --- a/src/sage/combinat/composition.py +++ b/src/sage/combinat/composition.py @@ -2017,7 +2017,7 @@ def composition_iterator_fast(n): sage: L = list(composition_iterator_fast(4)); L [[1, 1, 1, 1], [1, 1, 2], [1, 2, 1], [1, 3], [2, 1, 1], [2, 2], [3, 1], [4]] sage: type(L[0]) - <... 'list'> + """ # Special cases if n < 0: diff --git a/src/sage/combinat/designs/database.py b/src/sage/combinat/designs/database.py index af61d7e3ace..02023998fc1 100644 --- a/src/sage/combinat/designs/database.py +++ b/src/sage/combinat/designs/database.py @@ -4206,7 +4206,7 @@ def BIBD_45_9_8(from_code=False): '7up5z9m9u', '7w7esu6fm', '7zmqtlrpd', '81tsbnzsw', '8kofgi1he', '8mhi35nc1', '9cv1pjiaw', '9d6ef1dah', '9dftsor9c', '9du8c1vcw', '9jr5vsnj4', 'a8b405mps', 'ajqhmxkj4', 'ax2xsvfic'] B = [Integer(x, base=36) for x in B] - return [[i for i in range(45) if x&(1< + sage: type(I.blocks()[0][0]) - <... 'sage.rings.finite_rings.integer_mod.IntegerMod_int'> + TESTS:: @@ -1290,7 +1290,7 @@ def complement(self,uniform=False): if k is False: raise ValueError("The incidence structure is not uniform.") - blocks = [] + blocks = [] num_blocks = self.num_blocks() i = 0 from itertools import combinations @@ -1388,9 +1388,9 @@ def relabel(self, perm=None, inplace=True): self._points = [perm[x] for x in self._points] if self._points == list(range(self.num_points())): - self._point_to_index = None + self._point_to_index = None else: - self._point_to_index = {v:i for i,v in enumerate(self._points)} + self._point_to_index = {v: i for i, v in enumerate(self._points)} __hash__ = None # This object is mutable because of .relabel() @@ -2128,7 +2128,7 @@ def edge_coloring(self): blocks = self.blocks() blocks_sets = [frozenset(b) for b in blocks] g = Graph([list(range(self.num_blocks())), - lambda x, y: len(blocks_sets[x]&blocks_sets[y])], + lambda x, y: len(blocks_sets[x] & blocks_sets[y])], loops=False) return [[blocks[i] for i in C] for C in g.coloring(algorithm="MILP")] diff --git a/src/sage/combinat/e_one_star.py b/src/sage/combinat/e_one_star.py index 2cca168d20f..924ee53e754 100644 --- a/src/sage/combinat/e_one_star.py +++ b/src/sage/combinat/e_one_star.py @@ -1066,7 +1066,7 @@ def repaint(self, cmap='Set1') -> None: global cm if cm is None: from matplotlib import cm - + assert cm is not None if cmap not in cm.datad: raise RuntimeError("Color map %s not known (type sorted(colors) for valid names)" % cmap) cmap = cm.__dict__[cmap] diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 2cdd4045c02..2675100539c 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -3886,10 +3886,10 @@ def __call__(self, *args, **kwargs): (1, 0, 1, 1, 0, 1, 0, 1, 1, 0) sage: type(inverter((1, 0, 1, 1, 0, 1, 0, 1, 1, 0), ....: automatic_output_type=False)) - <... 'list'> + sage: type(inverter((1, 0, 1, 1, 0, 1, 0, 1, 1, 0), ....: automatic_output_type=True)) - <... 'tuple'> + """ if not args: raise TypeError("Called with too few arguments.") diff --git a/src/sage/combinat/free_module.py b/src/sage/combinat/free_module.py index d9f5d7c8144..bae91d64145 100644 --- a/src/sage/combinat/free_module.py +++ b/src/sage/combinat/free_module.py @@ -338,7 +338,7 @@ def element_class(self): sage: A.element_class.mro() [, - <... 'sage.modules.with_basis.indexed_element.IndexedFreeModuleElement'>, + , ...] sage: a,b,c = A.algebra_generators() sage: a * b @@ -1152,7 +1152,7 @@ class CombinatorialFreeModule_Tensor(CombinatorialFreeModule): The basis of T is indexed by tuples of basis indices of F and G:: sage: T.basis().keys() - Image of Cartesian product of {1, 2}, {3, 4} by <... 'tuple'> + Image of Cartesian product of {1, 2}, {3, 4} by sage: T.basis().keys().list() [(1, 3), (1, 4), (2, 3), (2, 4)] diff --git a/src/sage/combinat/gelfand_tsetlin_patterns.py b/src/sage/combinat/gelfand_tsetlin_patterns.py index ff5a145cd92..08615c0eae7 100644 --- a/src/sage/combinat/gelfand_tsetlin_patterns.py +++ b/src/sage/combinat/gelfand_tsetlin_patterns.py @@ -920,11 +920,11 @@ def _list_iter(self, n): sage: len(L) == G.cardinality() True sage: type(L[0]) - <... 'list'> + """ # Setup the first row - iters = [None]*n - ret = [None]*n + iters = [None] * n + ret = [None] * n iters[0] = self._top_row_iter(n) ret[0] = next(iters[0]) min_pos = 0 @@ -959,7 +959,7 @@ def _top_row_iter(self, n): sage: for x in G._top_row_iter(3): x [2, 1, 0] """ - row = [-1]*n + row = [-1] * n pos = 0 while pos >= 0: if pos == n: @@ -967,7 +967,7 @@ def _top_row_iter(self, n): pos -= 1 continue # If it would create an invalid entry, backstep - if ( pos > 0 and (row[pos] >= row[pos-1] \ + if (pos > 0 and (row[pos] >= row[pos-1] or (self._strict and row[pos] == row[pos-1]-1)) ) \ or (self._k is not None and row[pos] >= self._k): row[pos] = -1 diff --git a/src/sage/combinat/integer_vector_weighted.py b/src/sage/combinat/integer_vector_weighted.py index 8f1b68ffe85..1c2c109217c 100644 --- a/src/sage/combinat/integer_vector_weighted.py +++ b/src/sage/combinat/integer_vector_weighted.py @@ -237,12 +237,12 @@ def __iter__(self): return perm = Word(self._weights).standard_permutation() - perm = [len(self._weights)-i for i in perm] + perm = [len(self._weights) - i for i in perm] l = [x for x in sorted(self._weights, reverse=True)] for x in iterator_fast(self._n, l): yield self.element_class(self, [x[i] for i in perm]) - #.action(x) - #_left_to_right_multiply_on_right(Permutation(x)) + # .action(x) + # _left_to_right_multiply_on_right(Permutation(x)) class WeightedIntegerVectors_all(DisjointUnionEnumeratedSets): @@ -360,7 +360,7 @@ def iterator_fast(n, l): Test that :trac:`20491` is fixed:: sage: type(list(iterator_fast(2, [2]))[0][0]) - <... 'sage.rings.integer.Integer'> + """ if n < 0: return diff --git a/src/sage/combinat/integer_vectors_mod_permgroup.py b/src/sage/combinat/integer_vectors_mod_permgroup.py index 911558b4921..ef7f278e98a 100644 --- a/src/sage/combinat/integer_vectors_mod_permgroup.py +++ b/src/sage/combinat/integer_vectors_mod_permgroup.py @@ -293,7 +293,7 @@ def _repr_(self): sage: IntegerVectorsModPermutationGroup(PermutationGroup([[(1,2,3)]])) Integer vectors of length 3 enumerated up to the action of Permutation Group with generators [(1,2,3)] """ - return "Integer vectors of length %s enumerated up to the action of %r"%(self.n, self._permgroup) + return "Integer vectors of length %s enumerated up to the action of %r" % (self.n, self._permgroup) def ambient(self): r""" @@ -317,7 +317,7 @@ def lift(self, elt): sage: v = S.lift(S([4,3,0,1])); v [4, 3, 0, 1] sage: type(v) - <... 'list'> + """ # TODO: For now, Sage integer vectors are just python list. # Once Integer vectors will have an element class, update this @@ -360,7 +360,7 @@ def retract(self, elt): """ # TODO: Once Sage integer vector will have a data structure # based on ClonableIntArray, remove the conversion intarray - assert len(elt) == self.n, "%s is a quotient set of %s"%(self, self.ambient()) + assert len(elt) == self.n, "%s is a quotient set of %s" % (self, self.ambient()) intarray = self.element_class(self, elt, check=False) return self.element_class(self, canonical_representative_of_orbit_of(self._sgs, intarray), check=False) @@ -628,11 +628,11 @@ def _repr_(self): """ if self._sum is not None: if self._max_part >= 0: - return "Vectors of length %s and of sum %s whose entries is in {0, ..., %s} enumerated up to the action of %s"%(self.n, self._sum, self._max_part, self.permutation_group()) + return "Vectors of length %s and of sum %s whose entries is in {0, ..., %s} enumerated up to the action of %s" % (self.n, self._sum, self._max_part, self.permutation_group()) else: - return "Integer vectors of length %s and of sum %s enumerated up to the action of %s"%(self.n, self._sum, self.permutation_group()) + return "Integer vectors of length %s and of sum %s enumerated up to the action of %s" % (self.n, self._sum, self.permutation_group()) else: - return "Integer vectors of length %s whose entries is in {0, ..., %s} enumerated up to the action of %s"%(self.n, self._max_part, self.permutation_group()) + return "Integer vectors of length %s whose entries is in {0, ..., %s} enumerated up to the action of %s" % (self.n, self._max_part, self.permutation_group()) def roots(self): r""" @@ -858,11 +858,11 @@ def retract(self, elt): """ # TODO: Once Sage integer vector will have a data structure # based on ClonableIntArray, remove the conversion intarray - assert len(elt) == self.n, "%s is a quotient set of %s"%(self, self.ambient()) + assert len(elt) == self.n, "%s is a quotient set of %s" % (self, self.ambient()) if self._sum is not None: - assert sum(elt) == self._sum, "%s is a quotient set of %s"%(self, self.ambient()) + assert sum(elt) == self._sum, "%s is a quotient set of %s" % (self, self.ambient()) if self._max_part >= 0: - assert max(elt) <= self._max_part, "%s is a quotient set of %s"%(self, self.ambient()) + assert max(elt) <= self._max_part, "%s is a quotient set of %s" % (self, self.ambient()) intarray = self.element_class(self, elt, check=False) return self.element_class(self, canonical_representative_of_orbit_of(self._sgs, intarray), check=False) diff --git a/src/sage/combinat/matrices/dancing_links.pyx b/src/sage/combinat/matrices/dancing_links.pyx index 12d0eea378a..ab43cef4260 100644 --- a/src/sage/combinat/matrices/dancing_links.pyx +++ b/src/sage/combinat/matrices/dancing_links.pyx @@ -135,7 +135,7 @@ cdef class dancing_linksWrapper: sage: x Dancing links solver for 3 columns and 2 rows sage: type(x) - <... 'sage.combinat.matrices.dancing_links.dancing_linksWrapper'> + TESTS: @@ -1064,17 +1064,17 @@ cdef class dancing_linksWrapper: # Construction of the columns (transpose of the rows) columns = [[] for _ in range(self.ncols())] - for i,row in enumerate(self.rows()): + for i, row in enumerate(self.rows()): for a in row: columns[a].append(i) # Constraints: exactly one 1 in each column - for j,column in enumerate(columns): + for j, column in enumerate(columns): S = p.sum(x[a] for a in column) name = "one 1 in {}-th column".format(j) - p.add_constraint(S==1, name=name) + p.add_constraint(S == 1, name=name) - return p,x + return p, x def one_solution_using_milp_solver(self, solver=None, integrality_tolerance=1e-3): r""" diff --git a/src/sage/combinat/multiset_partition_into_sets_ordered.py b/src/sage/combinat/multiset_partition_into_sets_ordered.py index 61bb667e2ba..1789a6d551a 100755 --- a/src/sage/combinat/multiset_partition_into_sets_ordered.py +++ b/src/sage/combinat/multiset_partition_into_sets_ordered.py @@ -2623,6 +2623,7 @@ def _has_nonempty_sets(x): and block and len(set(block)) == len(block)) for block in x) + def _union_of_sets(list_of_sets): """ Return the union of a list of iterables as a frozenset. @@ -2634,7 +2635,9 @@ def _union_of_sets(list_of_sets): sage: _union_of_sets(L) frozenset({1, 2, 3, 5, 6, 7}) """ - return reduce(lambda a,b: frozenset(a)|frozenset(b), list_of_sets, frozenset()) + return reduce(lambda a, b: frozenset(a) | frozenset(b), + list_of_sets, frozenset()) + def _concatenate(list_of_iters): """ diff --git a/src/sage/combinat/partitions.pyx b/src/sage/combinat/partitions.pyx index 12dc88c17b5..c528131892a 100644 --- a/src/sage/combinat/partitions.pyx +++ b/src/sage/combinat/partitions.pyx @@ -42,7 +42,7 @@ def ZS1_iterator(int n): sage: next(it) [4] sage: type(_) - <... 'list'> + """ # Easy cases. if n < 0: @@ -102,7 +102,7 @@ def ZS1_iterator_nk(int n, int k): sage: next(it) [4] sage: type(_) - <... 'list'> + """ # Easy cases. if n <= 0: @@ -137,7 +137,7 @@ def ZS1_iterator_nk(int n, int k): h -= 1 yield x[:m+1] else: - t = m - h + 1 # 1 + "the number of 1s to the right of x[h] that belong to the partition" + t = m - h + 1 # 1 + "the number of 1s to the right of x[h] that belong to the partition" r = x[h] - 1 # This loop finds the largest h such that x[:h] can be completed diff --git a/src/sage/combinat/posets/poset_examples.py b/src/sage/combinat/posets/poset_examples.py index c94a00a29db..f47310ccb35 100644 --- a/src/sage/combinat/posets/poset_examples.py +++ b/src/sage/combinat/posets/poset_examples.py @@ -213,7 +213,7 @@ def BooleanLattice(n, facade=None, use_subsets=False): if use_subsets: from sage.sets.set import Set - cur_level = [frozenset(range(1, n+1))] + cur_level = [frozenset(range(1, n + 1))] D = DiGraph() D.add_vertex(Set(cur_level[0])) while cur_level: @@ -227,7 +227,8 @@ def BooleanLattice(n, facade=None, use_subsets=False): return FiniteLatticePoset(D, category=FiniteLatticePosets(), facade=facade) - D = DiGraph({v: [Integer(v|(1< + sage: r {'a': 0, 'b': 1, 'c': 2} @@ -157,7 +157,7 @@ def count(): i = 0 while True: yield i - i+=1 + i += 1 counter = count() diff --git a/src/sage/combinat/root_system/root_lattice_realization_algebras.py b/src/sage/combinat/root_system/root_lattice_realization_algebras.py index ca2dba85e12..86b1e561f87 100644 --- a/src/sage/combinat/root_system/root_lattice_realization_algebras.py +++ b/src/sage/combinat/root_system/root_lattice_realization_algebras.py @@ -42,7 +42,7 @@ def _repr_(self): sage: RootSystem(["A",2,1]).ambient_space().algebra(QQ) # indirect doctest Algebra of the Ambient space of the Root system of type ['A', 2, 1] over Rational Field """ - return "Algebra of the %s over %s"%(self.basis().keys(),self.base_ring()) + return "Algebra of the %s over %s" % (self.basis().keys(), self.base_ring()) def some_elements(self): r""" @@ -1168,13 +1168,15 @@ def expand(self, alphabet): TESTS:: sage: type(p.expand(F.gens())) - <... 'sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair'> + sage: p = KL.zero() sage: p.expand(F.gens()) 0 sage: type(p.expand(F.gens())) - <... 'sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_mpair'> + """ codomain = alphabet[0].parent() - return codomain.sum( c * prod(X**int(n) for X,n in zip(alphabet,vector(m))) for m,c in self) + return codomain.sum(c * prod(X**int(n) + for X, n in zip(alphabet, vector(m))) + for m, c in self) diff --git a/src/sage/combinat/root_system/type_reducible.py b/src/sage/combinat/root_system/type_reducible.py index 3943f5573fd..2a503a7ff58 100644 --- a/src/sage/combinat/root_system/type_reducible.py +++ b/src/sage/combinat/root_system/type_reducible.py @@ -56,7 +56,7 @@ class CartanType(SageObject, CartanType_abstract): super classes (see :meth:`~sage.combinat.root_system.cartan_type.CartanType_abstract._add_abstract_superclass`):: sage: t.__class__.mro() - [, , <... 'sage.structure.sage_object.SageObject'>, , , , <... 'object'>] + [, , , , , , ] The index set of the reducible Cartan type is obtained by relabelling successively the nodes of the Dynkin diagrams of @@ -134,7 +134,7 @@ def __init__(self, types): if all(isinstance(t, cls) for t in types) ) self._add_abstract_superclass(super_classes) - def _repr_(self, compact = True): # We should make a consistent choice here + def _repr_(self, compact=True): # We should make a consistent choice here """ EXAMPLES:: @@ -144,7 +144,7 @@ def _repr_(self, compact = True): # We should make a consistent choice here sage: CartanType("A2",CartanType("F4~").dual()) A2xF4~* """ - return "x".join(t._repr_(compact = True) for t in self._types) + return "x".join(t._repr_(compact=True) for t in self._types) def _latex_(self): r""" diff --git a/src/sage/combinat/root_system/weight_lattice_realizations.py b/src/sage/combinat/root_system/weight_lattice_realizations.py index bc9baf632b4..946d116fbde 100644 --- a/src/sage/combinat/root_system/weight_lattice_realizations.py +++ b/src/sage/combinat/root_system/weight_lattice_realizations.py @@ -248,8 +248,8 @@ def _test_weight_lattice_realization(self, **options): sage: RootSystem(['A',3]).weight_lattice()._test_weight_lattice_realization() """ from sage.rings.integer_ring import ZZ - tester = self._tester(**options) - Lambda = self.fundamental_weights() + tester = self._tester(**options) + Lambda = self.fundamental_weights() alphacheck = self.simple_coroots() tester.assertEqual(tuple(Lambda.keys()), self.index_set()) @@ -868,7 +868,7 @@ def weyl_dimension(self, highest_weight): 16 sage: type(RootSystem(['A',3]).ambient_lattice().weyl_dimension([2,1,0,0])) - <... 'sage.rings.integer.Integer'> + """ highest_weight = self(highest_weight) if not highest_weight.is_dominant(): diff --git a/src/sage/combinat/skew_partition.py b/src/sage/combinat/skew_partition.py index 585e1802c74..ab84c33b0af 100644 --- a/src/sage/combinat/skew_partition.py +++ b/src/sage/combinat/skew_partition.py @@ -1005,7 +1005,7 @@ def to_list(self): sage: s.to_list() [[4, 3, 1], [2]] sage: type(s.to_list()) - <... 'list'> + """ return [list(_) for _ in list(self)] @@ -1504,9 +1504,9 @@ def from_row_and_column_length(self, rowL, colL): if not all(i>0 for i in rowL) or not all(i>0 for i in colL): raise ValueError("row and column length must be positive") if rowL == []: - return self.element_class(self, [[],[]]) + return self.element_class(self, [[], []]) colL_new = colL[:] - resIn = [] + resIn = [] resOut = [] inPOld = len(colL) for row in rowL: @@ -1714,13 +1714,10 @@ def _count_slide(self, co, overlap=0): sage: [ sp for sp in s if sp.row_lengths() == [2,1] ] [[2, 1] / []] """ - nn = len(co) result = 1 - for i in range(nn-1): - comb = min(co[i], co[i+1]) - comb += 1 - overlap - result *= comb - + shift = 1 - overlap + for i in range(len(co) - 1): + result *= min(co[i], co[i + 1]) + shift return result def cardinality(self): diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index 4307051be34..9ce8796a27a 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -5120,7 +5120,7 @@ def list(self, n): """ self._eval(n) # force computation return self._b[:n] - _k = 1 + _k = 1 class A000153(ExtremesOfPermanentsSequence): @@ -9170,7 +9170,7 @@ def trait_names(self): EXAMPLES:: sage: type(sloane.trait_names()) - <... 'list'> + """ try: return self.__trait_names diff --git a/src/sage/combinat/tableau.py b/src/sage/combinat/tableau.py index 6301ffd4a35..0976069a23d 100644 --- a/src/sage/combinat/tableau.py +++ b/src/sage/combinat/tableau.py @@ -2628,7 +2628,7 @@ def promotion_inverse(self, n): sage: T = Tableau([[1]]) sage: type(T.promotion_inverse(2)[0][0]) - <... 'sage.rings.integer.Integer'> + """ if self.is_rectangular(): n = Integer(n) diff --git a/src/sage/combinat/tiling.py b/src/sage/combinat/tiling.py index b34dad8f9ad..a3a5774a00d 100644 --- a/src/sage/combinat/tiling.py +++ b/src/sage/combinat/tiling.py @@ -426,15 +426,14 @@ def ncube_isometry_group_cosets(n, orientation_preserving=True): sage: [len(c) for c in cosets] [8, 8, 8, 8, 8, 8] sage: type(cosets[0][0]) - <... 'sage.matrix.matrix_rational_dense.Matrix_rational_dense'> - + """ from sage.misc.misc_c import prod from sage.matrix.constructor import diagonal_matrix G = ncube_isometry_group(n, orientation_preserving) # Construct the subgroup H of G of diagonal matrices - it = itertools.product((1,-1), repeat=n) + it = itertools.product((1, -1), repeat=n) if orientation_preserving: H = [diagonal_matrix(L) for L in it if prod(L) == 1] else: @@ -1490,7 +1489,7 @@ def self_surrounding(self, radius, remove_incomplete_copies=True, # Add one row to force the placement of the central tile coord_to_int = T.coord_to_int_dict() new_row = [coord_to_int[coord] for coord in self] - new_row.append(len(coord_to_int)) # to force this row in the solution + new_row.append(len(coord_to_int)) # to force this row in the solution forced_row_number = len(rows) rows.append(new_row) diff --git a/src/sage/combinat/words/finite_word.py b/src/sage/combinat/words/finite_word.py index 609e701f7c7..4fd441172eb 100644 --- a/src/sage/combinat/words/finite_word.py +++ b/src/sage/combinat/words/finite_word.py @@ -1321,7 +1321,7 @@ def factor_iterator(self, n=None): TESTS:: sage: type( Word('cacao').factor_iterator() ) - <... 'generator'> + """ return self.suffix_tree().factor_iterator(n) @@ -5288,15 +5288,15 @@ def _s(self, i): sage: w._s(1).parent() Finite words over {1, 2, 3} """ - unpaired_i = [] # positions of unpaired is - unpaired_ip = [] # positions of unpaired i+1s - for p,x in enumerate(self): + unpaired_i = [] # positions of unpaired is + unpaired_ip = [] # positions of unpaired i+1s + for p, x in enumerate(self): if x == i: if unpaired_ip: unpaired_ip.pop() else: unpaired_i.append(p) - elif x == i+1: + elif x == i + 1: unpaired_ip.append(p) unpaired = unpaired_i + unpaired_ip diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 852fca48876..8666f86d0c0 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -408,7 +408,7 @@ def _element_classes(self): sage: d = FiniteWords()._element_classes sage: type(d) - <... 'dict'> + sage: len(d) 7 sage: e = FiniteWords('abcdefg')._element_classes @@ -1347,7 +1347,7 @@ def _element_classes(self): sage: d = InfiniteWords()._element_classes sage: type(d) - <... 'dict'> + sage: len(d) 4 sage: e = InfiniteWords('abcdefg')._element_classes From 4ce61292fa67176642483cebf239f5954e3118de Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Sat, 30 Oct 2021 21:51:14 +0200 Subject: [PATCH 260/378] bump gmp to version 6.2.1 --- build/pkgs/gmp/checksums.ini | 6 +++--- build/pkgs/gmp/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/gmp/checksums.ini b/build/pkgs/gmp/checksums.ini index d2cf090de11..11a552f2352 100644 --- a/build/pkgs/gmp/checksums.ini +++ b/build/pkgs/gmp/checksums.ini @@ -1,5 +1,5 @@ tarball=gmp-VERSION.tar.xz -sha1=052a5411dc74054240eec58132d2cf41211d0ff6 -md5=a325e3f09e6d91e62101e59f9bda3ec1 -cksum=942462047 +sha1=0578d48607ec0e272177d175fd1807c30b00fdf2 +md5=0b82665c4a92fd2ade7440c13fcaa42b +cksum=1546558141 upstream_url=https://gmplib.org/download/gmp/gmp-VERSION.tar.xz diff --git a/build/pkgs/gmp/package-version.txt b/build/pkgs/gmp/package-version.txt index 6abaeb2f907..024b066c0bb 100644 --- a/build/pkgs/gmp/package-version.txt +++ b/build/pkgs/gmp/package-version.txt @@ -1 +1 @@ -6.2.0 +6.2.1 From e5aa9867491b44520e57c6f6c96c52786f964eb1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 30 Oct 2021 23:01:20 -0700 Subject: [PATCH 261/378] src/sage/geometry/polyhedron/library.py: Replace lazy_import of AA, QQbar by method-local imports --- src/sage/geometry/polyhedron/library.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/library.py b/src/sage/geometry/polyhedron/library.py index 65598886f25..63d1e6dfabb 100644 --- a/src/sage/geometry/polyhedron/library.py +++ b/src/sage/geometry/polyhedron/library.py @@ -83,7 +83,6 @@ from sage.rings.integer_ring import ZZ from sage.misc.lazy_import import lazy_import -lazy_import('sage.rings.qqbar', ['AA', 'QQbar']) from sage.rings.rational_field import QQ lazy_import('sage.combinat.permutation', 'Permutations') lazy_import('sage.groups.perm_gps.permgroup_named', 'AlternatingGroup') @@ -572,6 +571,7 @@ def regular_polygon(self, n, exact=True, base_ring=None, backend=None): omega = 2*base_ring.pi() / n verts = [((i*omega).sin(), (i*omega).cos()) for i in range(n)] except AttributeError: + from sage.rings.qqbar import QQbar z = QQbar.zeta(n) verts = [(base_ring((z**k).imag()), base_ring((z**k).real())) for k in range(n)] @@ -1374,6 +1374,7 @@ def construct_z(field): if exact and base_ring is None: # construct the exact number field + from sage.rings.qqbar import AA from sage.rings.number_field.number_field import NumberField R = QQ['x'] f = R([-1, 1, 1, 1]) @@ -2744,6 +2745,7 @@ def generalized_permutahedron(self, coxeter_type, point=None, exact=True, regula new_point.set_immutable() vertices.add(new_point) if regular: + from sage.rings.qqbar import AA from sage.matrix.constructor import matrix from sage.modules.free_module_element import vector # This transformation fixes the first root and adjust the other From 2ce2751edd81cc51e015e0de4137c7488a60fb19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 14:02:25 -0700 Subject: [PATCH 262/378] src/sage/interacts/library.py: Remove unused imports --- src/sage/interacts/library.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index b84132c635b..472ee9b06a7 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -65,7 +65,6 @@ from sage.symbolic.constants import pi from sage.symbolic.relation import solve from sage.symbolic.ring import SR -import math x = SR.var('x') @@ -1682,7 +1681,7 @@ def polar_prime_spiral( start, end = interval from sage.ext.fast_eval import fast_float - from math import floor, ceil + from math import ceil from sage.plot.colors import hue if start < 1 or end <= start: From 23d8441ad68c9b316d8564f4227b4f3983ee1a9b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 14:02:43 -0700 Subject: [PATCH 263/378] src/sage/interacts/library.py: suppress pyflakes warning --- src/sage/interacts/library.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/interacts/library.py b/src/sage/interacts/library.py index 472ee9b06a7..c4c57f382a5 100644 --- a/src/sage/interacts/library.py +++ b/src/sage/interacts/library.py @@ -71,6 +71,8 @@ # It is important that this file is lazily imported for this to work from sage.repl.user_globals import get_global +assert get_global # to suppress pyflakes warning + from sage.repl.ipython_kernel.all_jupyter import (interact, checkbox, input_box, input_grid, range_slider, selector, slider, text_control) From 48360b787422858df29c6fd0b95624b4e51b563f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 14:03:22 -0700 Subject: [PATCH 264/378] src/sage/libs/eclib/interface.py: Remove unused import --- src/sage/libs/eclib/interface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sage/libs/eclib/interface.py b/src/sage/libs/eclib/interface.py index 0da8527a589..3db3fd902fc 100644 --- a/src/sage/libs/eclib/interface.py +++ b/src/sage/libs/eclib/interface.py @@ -27,7 +27,6 @@ """ import sys from sage.structure.sage_object import SageObject -from sage.rings.integer import Integer from sage.rings.integer_ring import IntegerRing from .mwrank import _Curvedata, _two_descent, _mw, parse_point_list From da82ac511f3671401108b2fc7ea7ac3ed6564664 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Oct 2021 09:40:37 -0700 Subject: [PATCH 265/378] src/sage/rings/polynomial/polynomial_element.pyx: Use isinstance(..., sage.rings.abc.SymbolicRing) instead of ... is SR --- src/sage/rings/polynomial/polynomial_element.pyx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element.pyx b/src/sage/rings/polynomial/polynomial_element.pyx index 26fdab5cbca..05401515069 100644 --- a/src/sage/rings/polynomial/polynomial_element.pyx +++ b/src/sage/rings/polynomial/polynomial_element.pyx @@ -7630,9 +7630,9 @@ cdef class Polynomial(CommutativeAlgebraElement): back to pari (numpy will fail if some coefficient is infinite, for instance). - If L is SR, then the roots will be radical expressions, - computed as the solutions of a symbolic polynomial expression. - At the moment this delegates to + If L is SR (or one of its subrings), then the roots will be radical + expressions, computed as the solutions of a symbolic polynomial + expression. At the moment this delegates to :meth:`sage.symbolic.expression.Expression.solve` which in turn uses Maxima to find radical solutions. Some solutions may be lost in this approach. @@ -7904,8 +7904,7 @@ cdef class Polynomial(CommutativeAlgebraElement): else: return [rt for (rt, mult) in rts_mult] - from sage.symbolic.ring import SR - if L is SR: + if isinstance(L, sage.rings.abc.SymbolicRing): if self.degree() == 2: from sage.misc.functional import sqrt from sage.symbolic.expression import I @@ -7925,6 +7924,7 @@ cdef class Polynomial(CommutativeAlgebraElement): return l else: return [val for val,m in l] + from sage.symbolic.ring import SR vname = 'do_not_use_this_name_in_a_polynomial_coefficient' var = SR(vname) expr = self(var) From 3c821bdc9ef306f59bd5809b93935b03eb9e8781 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:09:51 -0700 Subject: [PATCH 266/378] sage.functions.other._eval_floor_ceil: Handle elements of symbolic subrings like elements of SR --- src/sage/functions/other.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sage/functions/other.py b/src/sage/functions/other.py index cd2adbb1bfb..3fd9048ea87 100644 --- a/src/sage/functions/other.py +++ b/src/sage/functions/other.py @@ -20,7 +20,7 @@ from sage.symbolic.function import GinacFunction, BuiltinFunction from sage.symbolic.expression import Expression, register_symbol, symbol_table -from sage.symbolic.ring import SR +from sage.symbolic.ring import SR, SymbolicRing from sage.rings.integer import Integer from sage.rings.integer_ring import ZZ from sage.rings.rational import Rational @@ -179,6 +179,15 @@ def _eval_floor_ceil(self, x, method, bits=0, **kwds): Traceback (most recent call last): ... ValueError: Calling ceil() on infinity or NaN + + Test that elements of symbolic subrings work in the same way as + elements of ``SR``, :trac:`32724`:: + + sage: SCR = SR.subring(no_variables=True) + sage: floor(log(2^(3/2)) / log(2) + 1/2) + 2 + sage: floor(SCR(log(2^(-3/2)) / log(2) + 1/2)) + -1 """ # First, some obvious things... try: @@ -215,8 +224,8 @@ def _eval_floor_ceil(self, x, method, bits=0, **kwds): from sage.rings.all import RealIntervalField # Might it be needed to simplify x? This only applies for - # elements of SR. - need_to_simplify = (s_parent(x) is SR) + # elements of SR (or its subrings) + need_to_simplify = isinstance(s_parent(x), SymbolicRing) # An integer which is close to x. We use this to increase precision # by subtracting this guess before converting to an interval field. From f1c9258889ae9e45b6d82c1ae9421890e2de569c Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:18:48 -0700 Subject: [PATCH 267/378] src/sage/combinat/q_analogues.py: Handle symbolic subrings like SR --- src/sage/combinat/q_analogues.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/sage/combinat/q_analogues.py b/src/sage/combinat/q_analogues.py index 10333aaa455..bf5f5c985bc 100644 --- a/src/sage/combinat/q_analogues.py +++ b/src/sage/combinat/q_analogues.py @@ -172,7 +172,8 @@ def q_binomial(n, k, q=None, algorithm='auto'): uses the naive algorithm. When both ``n`` and ``k`` are big, one uses the cyclotomic algorithm. - - If ``q`` is in the symbolic ring, one uses the cyclotomic algorithm. + - If ``q`` is in the symbolic ring (or a symbolic subring), one uses + the cyclotomic algorithm. - Otherwise one uses the naive algorithm, unless ``q`` is a root of unity, then one uses the cyclotomic algorithm. @@ -248,7 +249,7 @@ def q_binomial(n, k, q=None, algorithm='auto'): This also works for variables in the symbolic ring:: sage: z = var('z') - sage: factor(q_binomial(4,2,z)) + sage: factor(q_binomial(4, 2, z)) (z^2 + z + 1)*(z^2 + 1) This also works for complex roots of unity:: @@ -346,8 +347,8 @@ def q_binomial(n, k, q=None, algorithm='auto'): elif is_polynomial: algorithm = 'cyclotomic' else: - from sage.symbolic.ring import SR - if R is SR: + import sage.rings.abc + if isinstance(R, sage.rings.abc.SymbolicRing): algorithm = 'cyclotomic' else: algorithm = 'naive' From f98855b9633090e728d197202a9a9fc4dfcfd446 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:44:33 -0700 Subject: [PATCH 268/378] src/sage/dynamics/arithmetic_dynamics/projective_ds.py: Use sage.rings.abc.SymbolicRing instead of 'is SR' --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index d4cb66af782..7033a64bbef 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -105,7 +105,6 @@ class initialization directly. from sage.parallel.ncpus import ncpus from sage.parallel.use_fork import p_iter_fork from sage.dynamics.arithmetic_dynamics.projective_ds_helper import (_fast_possible_periods,_all_periodic_points) -from sage.symbolic.ring import SR from itertools import count, product from .endPN_automorphism_group import ( automorphism_group_QQ_CRT, @@ -422,8 +421,8 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): if len(polys) != domain.ambient_space().coordinate_ring().ngens(): raise ValueError('Number of polys does not match dimension of {}'.format(domain)) R = domain.base_ring() - if R is SR: - raise TypeError("Symbolic Ring cannot be the base ring") + if isinstance(R, sage.rings.abc.SymbolicRing): + raise TypeError("the base ring cannot be the Symbolic Ring or a symbolic subring") if is_ProductProjectiveSpaces(domain): splitpolys = domain._factors(polys) From 7f1500e4cdebfd8ee87f61749a11e0e23e4c65b9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 20:59:17 -0700 Subject: [PATCH 269/378] src/sage/geometry/polyhedron/parent.py: For backend='normaliz', accept subrings of SR --- src/sage/geometry/polyhedron/parent.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/parent.py b/src/sage/geometry/polyhedron/parent.py index 48bed4a9553..8ac51827d61 100644 --- a/src/sage/geometry/polyhedron/parent.py +++ b/src/sage/geometry/polyhedron/parent.py @@ -15,6 +15,7 @@ from sage.modules.free_module import FreeModule, is_FreeModule from sage.misc.cachefunc import cached_method, cached_function from sage.misc.lazy_import import lazy_import +import sage.rings.abc from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ from sage.rings.real_double import RDF @@ -113,6 +114,13 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * ... ValueError: the 'polymake' backend for polyhedron cannot be used with Algebraic Real Field + sage: Polyhedra(QQ, 2, backend='normaliz') # optional - pynormaliz + Polyhedra in QQ^2 + sage: Polyhedra(SR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + Polyhedra in (Symbolic Ring)^2 + sage: SCR = SR.subring(no_variables=True) # optional - sage.symbolic + sage: Polyhedra(SCR, 2, backend='normaliz') # optional - pynormaliz # optional - sage.symbolic + Polyhedra in (Symbolic Constants Subring)^2 """ if ambient_space_or_base_ring is not None: if ambient_space_or_base_ring in Rings(): @@ -161,7 +169,7 @@ def Polyhedra(ambient_space_or_base_ring=None, ambient_dim=None, backend=None, * return Polyhedra_QQ_normaliz(base_ring, ambient_dim, backend) elif backend == 'normaliz' and base_ring is ZZ: return Polyhedra_ZZ_normaliz(base_ring, ambient_dim, backend) - elif backend == 'normaliz' and (base_ring is SR or base_ring.is_exact()): + elif backend == 'normaliz' and (isinstance(base_ring, sage.rings.abc.SymbolicRing) or base_ring.is_exact()): return Polyhedra_normaliz(base_ring, ambient_dim, backend) elif backend == 'cdd' and base_ring in (ZZ, QQ): return Polyhedra_QQ_cdd(QQ, ambient_dim, backend) From 76e09622cf24f5137eb8b611e349e3bb4988d61b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 21:06:13 -0700 Subject: [PATCH 270/378] [Diff]ScalarFieldAlgebra._coerce_map_from_: Also coerce from subrings of SR --- src/sage/manifolds/differentiable/scalarfield_algebra.py | 8 ++++++-- src/sage/manifolds/scalarfield_algebra.py | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/sage/manifolds/differentiable/scalarfield_algebra.py b/src/sage/manifolds/differentiable/scalarfield_algebra.py index be5d9176cd3..7bbf5a39146 100644 --- a/src/sage/manifolds/differentiable/scalarfield_algebra.py +++ b/src/sage/manifolds/differentiable/scalarfield_algebra.py @@ -32,7 +32,7 @@ class `C^k` over a topological field `K` (in #****************************************************************************** from sage.rings.infinity import infinity -from sage.symbolic.ring import SR +from sage.symbolic.ring import SymbolicRing from sage.manifolds.scalarfield_algebra import ScalarFieldAlgebra from sage.manifolds.differentiable.scalarfield import DiffScalarField @@ -406,6 +406,10 @@ def _coerce_map_from_(self, other): sage: CM = M.scalar_field_algebra() sage: CM._coerce_map_from_(SR) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: CM._coerce_map_from_(SCR) + True sage: CM._coerce_map_from_(X.function_ring()) True sage: U = M.open_subset('U', coord_def={X: x>0}) @@ -418,7 +422,7 @@ def _coerce_map_from_(self, other): """ from sage.manifolds.chart_func import ChartFunctionRing - if other is SR: + if isinstance(other, SymbolicRing): return True # coercion from the base ring (multiplication by the # algebra unit, i.e. self.one()) # cf. ScalarField._lmul_() for the implementation of diff --git a/src/sage/manifolds/scalarfield_algebra.py b/src/sage/manifolds/scalarfield_algebra.py index 6d6ba2f88ca..52c89fd9959 100644 --- a/src/sage/manifolds/scalarfield_algebra.py +++ b/src/sage/manifolds/scalarfield_algebra.py @@ -36,7 +36,7 @@ from sage.misc.cachefunc import cached_method from sage.categories.commutative_algebras import CommutativeAlgebras from sage.categories.topological_spaces import TopologicalSpaces -from sage.symbolic.ring import SR +from sage.symbolic.ring import SymbolicRing, SR from sage.manifolds.scalarfield import ScalarField class ScalarFieldAlgebra(UniqueRepresentation, Parent): @@ -509,6 +509,10 @@ def _coerce_map_from_(self, other): sage: CM = M.scalar_field_algebra() sage: CM._coerce_map_from_(SR) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: CM._coerce_map_from_(SCR) + True sage: CM._coerce_map_from_(X.function_ring()) True sage: U = M.open_subset('U', coord_def={X: x>0}) @@ -520,7 +524,7 @@ def _coerce_map_from_(self, other): """ from .chart_func import ChartFunctionRing - if other is SR: + if isinstance(other, SymbolicRing): return True # coercion from the base ring (multiplication by the # algebra unit, i.e. self.one()) # cf. ScalarField._lmul_() for the implementation of From b7470d1784904f04607fbc537ee8995f90c499b1 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:14:14 -0700 Subject: [PATCH 271/378] Matrix.is_{positive_operator,cross_positive,lyapunov_like}_on: Handle symbolic subrings like SR --- src/sage/matrix/matrix2.pyx | 38 ++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index 2f2f1cee854..3a9fc7d802a 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -14288,7 +14288,6 @@ cdef class Matrix(Matrix1): code. The boolean ``semi`` argument exists only to change "greater than zero" into "greater than or equal to zero." """ - from sage.symbolic.ring import SR from sage.rings.real_lazy import RLF,CLF R = self.base_ring() @@ -14297,7 +14296,7 @@ cdef class Matrix(Matrix1): R.has_coerce_map_from(RLF) or CLF.has_coerce_map_from(R) or R.has_coerce_map_from(CLF) or - R is SR): + isinstance(R, sage.rings.abc.SymbolicRing)): # This is necessary to avoid "going through the motions" # with e.g. a one-by-one identity matrix over the finite # field of order 5^2, which might otherwise look positive- @@ -16904,8 +16903,15 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_positive_operator_on(K) + True """ - from sage.symbolic.ring import SR import sage.geometry.abc if K2 is None: @@ -16913,7 +16919,7 @@ cdef class Matrix(Matrix1): if not (isinstance(K1, sage.geometry.abc.ConvexRationalPolyhedralCone) and isinstance(K2, sage.geometry.abc.ConvexRationalPolyhedralCone)): raise TypeError('K1 and K2 must be cones.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) @@ -17048,13 +17054,20 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_cross_positive_on(K) + True """ - from sage.symbolic.ring import SR import sage.geometry.abc if not isinstance(K, sage.geometry.abc.ConvexRationalPolyhedralCone): raise TypeError('K must be a cone.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) @@ -17302,6 +17315,15 @@ cdef class Matrix(Matrix1): ValueError: The base ring of the matrix is neither symbolic nor exact. + Symbolic subrings are fine:: + + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: K = Cone([(1,2,3), (4,5,6)]) + sage: L = identity_matrix(SCR, 3) + sage: L.is_lyapunov_like_on(K) + True + A matrix is Lyapunov-like on a cone if and only if both the matrix and its negation are cross-positive on the cone:: @@ -17314,14 +17336,12 @@ cdef class Matrix(Matrix1): ....: (-L).is_cross_positive_on(K)) # long time sage: actual == expected # long time True - """ - from sage.symbolic.ring import SR import sage.geometry.abc if not isinstance(K, sage.geometry.abc.ConvexRationalPolyhedralCone): raise TypeError('K must be a cone.') - if not self.base_ring().is_exact() and not self.base_ring() is SR: + if not self.base_ring().is_exact() and not isinstance(self.base_ring(), sage.rings.abc.SymbolicRing): msg = 'The base ring of the matrix is neither symbolic nor exact.' raise ValueError(msg) From 5fca7fcdbc9370b47bfdeb7883a4c3bce602283d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:33:14 -0700 Subject: [PATCH 272/378] continued_fraction: Handle symbolic subrings like SR --- src/sage/rings/continued_fraction.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/sage/rings/continued_fraction.py b/src/sage/rings/continued_fraction.py index cf5f8b1f9eb..d7d77afb8a7 100644 --- a/src/sage/rings/continued_fraction.py +++ b/src/sage/rings/continued_fraction.py @@ -207,6 +207,7 @@ from sage.structure.sage_object import SageObject from sage.structure.richcmp import richcmp_method, rich_to_bool +import sage.rings.abc from .integer import Integer from .integer_ring import ZZ from .infinity import Infinity @@ -2601,6 +2602,12 @@ def continued_fraction(x, value=None): sage: continued_fraction(1.575709393346379) [1; 1, 1, 2, 1, 4, 18, 1, 5, 2, 25037802, 7, 1, 3, 1, 28, 1, 8, 2] + + Constants in symbolic subrings work like constants in ``SR``:: + + sage: SCR = SR.subring(no_variables=True) + sage: continued_fraction(SCR(pi)) + [3; 7, 15, 1, 292, 1, 1, 1, 2, 1, 3, 1, 14, 2, 1, 1, 2, 2, 2, 2, ...] """ if isinstance(x, ContinuedFraction_base): @@ -2675,10 +2682,9 @@ def continued_fraction(x, value=None): if x.parent().is_exact(): return ContinuedFraction_real(x) - # we treat separately the symbolic ring that holds all constants and - # which is not exact - from sage.symbolic.ring import SR - if x.parent() == SR: + # We treat the Symbolic Ring and its subrings separately. They hold all constants and + # are not exact. + if isinstance(x.parent(), sage.rings.abc.SymbolicRing): return ContinuedFraction_real(x) return continued_fraction(continued_fraction_list(x)) From 038eb9f5b13f606f29935b70c47a20ba1cb506a7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:46:11 -0700 Subject: [PATCH 273/378] src/sage/symbolic/pynac_impl.pxi (py_is_integer, py_is_exact): Handle symbolic subrings like SR --- src/sage/symbolic/pynac_impl.pxi | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/sage/symbolic/pynac_impl.pxi b/src/sage/symbolic/pynac_impl.pxi index 4b46fc69133..482593b2ef4 100644 --- a/src/sage/symbolic/pynac_impl.pxi +++ b/src/sage/symbolic/pynac_impl.pxi @@ -307,7 +307,6 @@ cdef subs_args_to_PyTuple(const GExMap& map, unsigned options, const GExVector& ] x """ - from sage.symbolic.ring import SR res = [] res.append(new_SubstitutionMap_from_GExMap(map)) res.append(options) @@ -1118,6 +1117,10 @@ cdef bint py_is_integer(x): True sage: py_is_integer(SR(5)) True + sage: SCR = SR.subring(no_variables=True); SCR + Symbolic Constants Subring + sage: py_is_integer(SCR(5)) + True sage: py_is_integer(4/2) True sage: py_is_integer(QQbar(sqrt(2))^2) @@ -1132,8 +1135,8 @@ cdef bint py_is_integer(x): if not isinstance(x, Element): return False P = (x)._parent - from .ring import SR - return (P is SR or P.is_exact()) and x in ZZ + from .ring import SymbolicRing + return (isinstance(P, SymbolicRing) or P.is_exact()) and x in ZZ def py_is_integer_for_doctests(x): @@ -1221,8 +1224,8 @@ cdef bint py_is_exact(x): if not isinstance(x, Element): return False P = (x)._parent - from .ring import SR - return P is SR or P.is_exact() + from .ring import SymbolicRing + return isinstance(P, SymbolicRing) or P.is_exact() cdef py_numer(n): From ff83c4cbca77c709021afb00a5632b80f02e0683 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 31 Oct 2021 22:54:10 -0700 Subject: [PATCH 274/378] sage.repl.ipython_kernel (widget_from_tuple, slider): Handle symbolic subrings like SR --- src/sage/repl/ipython_kernel/interact.py | 12 ++++++++++-- src/sage/repl/ipython_kernel/widgets_sagenb.py | 14 +++++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/sage/repl/ipython_kernel/interact.py b/src/sage/repl/ipython_kernel/interact.py index 1e344d8373f..b9970f551a7 100644 --- a/src/sage/repl/ipython_kernel/interact.py +++ b/src/sage/repl/ipython_kernel/interact.py @@ -41,7 +41,7 @@ from .widgets import EvalText, SageColorPicker from .widgets_sagenb import input_grid from sage.structure.element import parent -from sage.symbolic.ring import SR +import sage.rings.abc from sage.plot.colors import Color from sage.structure.element import Matrix @@ -209,6 +209,14 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): Dropdown(index=1, options={'one': 1, 'two': 2, 'three': 3}, value=2) sage: sage_interactive.widget_from_tuple( (sqrt(2), pi) ) FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) + + TESTS: + + Symbolic subrings:: + + sage: SCR = SR.subring(no_variables=True) + sage: sage_interactive.widget_from_tuple( (SCR(sqrt(2)), SCR(pi)) ) + FloatSlider(value=2.277903107981444, max=3.141592653589793, min=1.4142135623730951) """ # Support (description, abbrev) if len(abbrev) == 2 and isinstance(abbrev[0], str): @@ -223,7 +231,7 @@ def widget_from_tuple(cls, abbrev, *args, **kwds): # Numerically evaluate symbolic expressions def n(x): - if parent(x) is SR: + if isinstance(parent(x), sage.rings.abc.SymbolicRing): return x.numerical_approx() else: return x diff --git a/src/sage/repl/ipython_kernel/widgets_sagenb.py b/src/sage/repl/ipython_kernel/widgets_sagenb.py index 33ce4898ca7..45c2d9350ce 100644 --- a/src/sage/repl/ipython_kernel/widgets_sagenb.py +++ b/src/sage/repl/ipython_kernel/widgets_sagenb.py @@ -42,8 +42,7 @@ from sage.structure.all import parent from sage.arith.srange import srange from sage.plot.colors import Color -from sage.symbolic.ring import SR -from sage.rings.all import RR +import sage.rings.abc from .widgets import HTMLText as text_control @@ -234,6 +233,14 @@ def slider(vmin, vmax=None, step_size=None, default=None, label=None, display_va True sage: slider(5, display_value=False).readout False + + Symbolic subrings work like ``SR``:: + + sage: SCR = SR.subring(no_variables=True) + sage: w = slider(SCR(e), SCR(pi)); w + TransformFloatSlider(value=2.718281828459045, max=3.141592653589793, min=2.718281828459045) + sage: parent(w.get_interact_value()) + Real Field with 53 bits of precision """ kwds = {"readout": display_value} if label: @@ -271,7 +278,8 @@ def err(v): p = parent(sum(x for x in (vmin, vmax, step_size) if x is not None)) # Change SR to RR - if p is SR: + if isinstance(p, sage.rings.abc.SymbolicRing): + from sage.rings.real_mpfr import RR p = RR # Convert all inputs to the common parent From 03f17c9f764eeebb1e1cdaa2004f8ce7fac9022e Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 1 Nov 2021 10:01:04 -0700 Subject: [PATCH 275/378] build/pkgs/polymake/spkg-configure.m4: In AC_RUN_IFELSE for libpolymake, use shell_enable, set_application --- build/pkgs/polymake/spkg-configure.m4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/pkgs/polymake/spkg-configure.m4 b/build/pkgs/polymake/spkg-configure.m4 index e081356478d..fb7be48bebb 100644 --- a/build/pkgs/polymake/spkg-configure.m4 +++ b/build/pkgs/polymake/spkg-configure.m4 @@ -25,6 +25,8 @@ SAGE_SPKG_CONFIGURE([polymake], [ #include ]], [[ polymake::Main* main_polymake_session = new polymake::Main; + main_polymake_session->shell_enable(); + main_polymake_session->set_application("polytope"); ]] )], [ AC_MSG_RESULT([yes]) From c0486f849d83ad847469d083f186a3b2e5a7e63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 1 Nov 2021 19:11:23 +0100 Subject: [PATCH 276/378] remove the "bound_method" py2/py3 doctest adapter --- .../coercion_and_categories.rst | 2 +- .../algebras/steenrod/steenrod_algebra.py | 4 +- src/sage/categories/algebras_with_basis.py | 2 +- src/sage/categories/category_with_axiom.py | 2 +- .../categories/examples/semigroups_cython.pyx | 6 +- src/sage/categories/finite_enumerated_sets.py | 16 ++--- .../categories/hopf_algebras_with_basis.py | 2 +- src/sage/categories/magmas.py | 2 +- src/sage/categories/realizations.py | 2 +- src/sage/categories/sets_cat.py | 5 +- src/sage/combinat/integer_lists/lists.py | 4 +- src/sage/combinat/root_system/plot.py | 10 ++-- src/sage/combinat/words/words.py | 4 +- src/sage/doctest/parsing.py | 58 +------------------ .../sets/disjoint_union_enumerated_sets.py | 4 +- src/sage/structure/category_object.pyx | 2 +- src/sage/structure/element.pyx | 4 +- 17 files changed, 36 insertions(+), 93 deletions(-) diff --git a/src/doc/en/thematic_tutorials/coercion_and_categories.rst b/src/doc/en/thematic_tutorials/coercion_and_categories.rst index 4a8d86c0ae9..846b68f5210 100644 --- a/src/doc/en/thematic_tutorials/coercion_and_categories.rst +++ b/src/doc/en/thematic_tutorials/coercion_and_categories.rst @@ -1742,7 +1742,7 @@ The new test is inherited from the category. Since ``an_element()`` is returning complicated element, ``_test_factorisation`` is a serious test:: sage: P.an_element()._test_factorisation - + .. end of output diff --git a/src/sage/algebras/steenrod/steenrod_algebra.py b/src/sage/algebras/steenrod/steenrod_algebra.py index 3eb15efd811..a9120b91415 100644 --- a/src/sage/algebras/steenrod/steenrod_algebra.py +++ b/src/sage/algebras/steenrod/steenrod_algebra.py @@ -2628,7 +2628,7 @@ def gens(self): sage: A3 = SteenrodAlgebra(3, 'adem') sage: A3.gens() - Lazy family ((i))_{i in Non negative integers} + Lazy family ((i))_{i in Non negative integers} sage: A3.gens()[0] beta sage: A3.gens()[1] @@ -2647,7 +2647,7 @@ def gens(self): sage: SteenrodAlgebra(p=5, profile=[[2,1], [2,2,2]]).gens() Family (Q_0, P(1), P(5)) sage: SteenrodAlgebra(profile=lambda n: n).gens() - Lazy family ((i))_{i in Non negative integers} + Lazy family ((i))_{i in Non negative integers} You may also use ``algebra_generators`` instead of ``gens``:: diff --git a/src/sage/categories/algebras_with_basis.py b/src/sage/categories/algebras_with_basis.py index 701b428a836..972c9a94b76 100644 --- a/src/sage/categories/algebras_with_basis.py +++ b/src/sage/categories/algebras_with_basis.py @@ -56,7 +56,7 @@ class AlgebrasWithBasis(CategoryWithAxiom_over_base_ring): B[word: acb] sage: A.product - sage: A.product(a*b,b) B[word: abb] diff --git a/src/sage/categories/category_with_axiom.py b/src/sage/categories/category_with_axiom.py index 075e1542a7b..cbd3823ab5e 100644 --- a/src/sage/categories/category_with_axiom.py +++ b/src/sage/categories/category_with_axiom.py @@ -358,7 +358,7 @@ class from the base category class:: nested class ``Ds.Green`` or not (an implementation detail):: sage: Cs().Green - + Thanks to this feature (implemented in :meth:`CategoryWithAxiom.__classget__`), the user is systematically referred to the documentation of this diff --git a/src/sage/categories/examples/semigroups_cython.pyx b/src/sage/categories/examples/semigroups_cython.pyx index 6b6e179bc3a..c05ab880fb6 100644 --- a/src/sage/categories/examples/semigroups_cython.pyx +++ b/src/sage/categories/examples/semigroups_cython.pyx @@ -189,17 +189,17 @@ class LeftZeroSemigroup(LeftZeroSemigroupPython): That's really the only method which is obtained from the category ... :: sage: S(42).is_idempotent - + sage: S(42).is_idempotent() True sage: S(42)._pow_int - + sage: S(42)^10 42 sage: S(42).is_idempotent - + sage: S(42).is_idempotent() True """ diff --git a/src/sage/categories/finite_enumerated_sets.py b/src/sage/categories/finite_enumerated_sets.py index 0f423dbb5de..b4f98de21f2 100644 --- a/src/sage/categories/finite_enumerated_sets.py +++ b/src/sage/categories/finite_enumerated_sets.py @@ -117,7 +117,7 @@ def _cardinality_from_iterator(self, *ignored_args, **ignored_kwds): sage: class FreshExample(Example): pass sage: C = FreshExample(); C.rename("FreshExample") sage: C.cardinality - + This method shall return an ``Integer``; we test this here, because :meth:`_test_enumerated_set_iter_cardinality` @@ -323,21 +323,21 @@ def _list_from_iterator(self): sage: class FreshExample(Example): pass sage: C = FreshExample(); C.rename("FreshExample") sage: C.list - + sage: C.unrank - + sage: C.cardinality - + sage: l1 = C.list(); l1 [1, 2, 3] sage: C.list - + sage: C.unrank - + sage: C.cardinality - + sage: C.__iter__ - + We finally check that nothing breaks before and after calling explicitly the method ``.list()``:: diff --git a/src/sage/categories/hopf_algebras_with_basis.py b/src/sage/categories/hopf_algebras_with_basis.py index e5e0e05fe57..f74ff60b7dd 100644 --- a/src/sage/categories/hopf_algebras_with_basis.py +++ b/src/sage/categories/hopf_algebras_with_basis.py @@ -58,7 +58,7 @@ class HopfAlgebrasWithBasis(CategoryWithAxiom_over_base_ring): B[(1,2)] sage: A.product # todo: not quite ... - + sage: A.product(b,b) B[()] diff --git a/src/sage/categories/magmas.py b/src/sage/categories/magmas.py index 5aa2b09e0c4..a2707f5f3dd 100644 --- a/src/sage/categories/magmas.py +++ b/src/sage/categories/magmas.py @@ -1185,7 +1185,7 @@ def product_by_coercion(self, left, right): sage: Out = Sets().WithRealizations().example().Out(); Out The subset algebra of {1, 2, 3} over Rational Field in the Out basis sage: Out.product - + sage: Out.product.__module__ 'sage.categories.magmas' sage: x = Out.an_element() diff --git a/src/sage/categories/realizations.py b/src/sage/categories/realizations.py index 757b2f3aba3..1d64bca5f03 100644 --- a/src/sage/categories/realizations.py +++ b/src/sage/categories/realizations.py @@ -36,7 +36,7 @@ class RealizationsCategory(RegressiveCovariantConstructionCategory): TESTS:: sage: Sets().Realizations - + sage: Sets().Realizations() Category of realizations of sets sage: Sets().Realizations().super_categories() diff --git a/src/sage/categories/sets_cat.py b/src/sage/categories/sets_cat.py index fdebfd93799..f86d8e961ea 100644 --- a/src/sage/categories/sets_cat.py +++ b/src/sage/categories/sets_cat.py @@ -956,14 +956,13 @@ def _element_constructor_(self): sage: A.element_class sage: A._element_constructor_ - + sage: B = SymmetricGroup(3).algebra(ZZ) sage: B.element_class <...SymmetricGroupAlgebra_n_with_category.element_class'> sage: B._element_constructor_ - + """ if hasattr(self, "element_class"): return self._element_constructor_from_element_class diff --git a/src/sage/combinat/integer_lists/lists.py b/src/sage/combinat/integer_lists/lists.py index 8795add6e56..5143e5cb5e8 100644 --- a/src/sage/combinat/integer_lists/lists.py +++ b/src/sage/combinat/integer_lists/lists.py @@ -299,7 +299,7 @@ def _element_constructor_default(self, l): ....: Element = MyElt sage: L = MyIntegersLists(5) sage: L._element_constructor_ - + """ return self.element_class(self, l) @@ -320,7 +320,7 @@ def _element_constructor_nocheck(self, l): iterator:: sage: L._element_constructor_ - + sage: L._element_constructor_([1,2,3]) [1, 2, 3] """ diff --git a/src/sage/combinat/root_system/plot.py b/src/sage/combinat/root_system/plot.py index 41371737f7a..706cc57fc18 100644 --- a/src/sage/combinat/root_system/plot.py +++ b/src/sage/combinat/root_system/plot.py @@ -846,7 +846,7 @@ def __init__(self, space, 2 sage: options._projections [Weight space over the Rational Field of the Root system of type ['B', 2], - ] + ] sage: L = RootSystem(['B',2,1]).ambient_space() sage: options = L.plot_parse_options() @@ -854,24 +854,24 @@ def __init__(self, space, 2 sage: options._projections [Ambient space of the Root system of type ['B', 2], - ] + ] sage: options = L.plot_parse_options(affine=True) sage: options.dimension 2 sage: options._projections [Ambient space of the Root system of type ['B', 2], - ] + ] sage: options = L.plot_parse_options(affine=False) sage: options._projections - [] + [] sage: options.dimension 3 sage: options = L.plot_parse_options(affine=False, projection='barycentric') sage: options._projections - [] + [] sage: options.dimension 3 """ diff --git a/src/sage/combinat/words/words.py b/src/sage/combinat/words/words.py index 852fca48876..03c13796e9d 100644 --- a/src/sage/combinat/words/words.py +++ b/src/sage/combinat/words/words.py @@ -135,9 +135,9 @@ def __init__(self, alphabet=None, category=None): True sage: Words('abc').sortkey_letters - + sage: Words('bac').sortkey_letters - + """ if isinstance(alphabet, (int, Integer)): from sage.sets.integer_range import IntegerRange diff --git a/src/sage/doctest/parsing.py b/src/sage/doctest/parsing.py index 3346ca14a24..4378c45c713 100644 --- a/src/sage/doctest/parsing.py +++ b/src/sage/doctest/parsing.py @@ -173,59 +173,6 @@ def normalize_long_repr(s): return _long_repr_re.sub(lambda m: m.group(1), s) -_normalize_bound_method_re = re.compile( - r'[^. ]+)\sof\s(?P.+)>', re.M | re.S) - -def normalize_bound_method_repr(s): - """ - Normalize differences between Python 2 and 3 in how bound methods are - represented. - - On Python 2 bound methods are represented using the class name of the - object the method was bound to, whereas on Python 3 they are represented - with the fully-qualified name of the function that implements the method. - - In the context of a doctest it's almost impossible to convert accurately - from the latter to the former or vice-versa, so we simplify the reprs of - bound methods to just the bare method name. - - This is slightly regressive since it means one can't use the repr of a - bound method to test whether some element is getting a method from the - correct class (important sometimes in the cases of dynamic classes). - However, such tests could be written could be written more explicitly to - emphasize that they are testing such behavior. - - EXAMPLES: - - :: - - sage: from sage.doctest.parsing import normalize_bound_method_repr - sage: el = Semigroups().example().an_element() - sage: el - 42 - sage: el.is_idempotent - - sage: normalize_bound_method_repr(repr(el.is_idempotent)) - '' - - An example where the object ``repr`` contains whitespace:: - - sage: U = DisjointUnionEnumeratedSets( - ....: Family([1, 2, 3], Partitions), facade=False) - sage: U._element_constructor_ - - sage: normalize_bound_method_repr(repr(U._element_constructor_)) - '' - """ - - def subst(m): - return ''.format(**m.groupdict()) - - return _normalize_bound_method_re.sub(subst, s) - - # Collection of fixups applied in the SageOutputChecker. Each element in this # this list a pair of functions applied to the actual test output ('g' for # "got") and the expected test output ('w' for "wanted"). The first function @@ -240,10 +187,7 @@ def subst(m): (lambda g, w: 'u"' in w or "u'" in w, lambda g, w: (g, remove_unicode_u(w))), (lambda g, w: 'L' in w or 'l' in w, - lambda g, w: (g, normalize_long_repr(w))), - (lambda g, w: ' sage: U = DisjointUnionEnumeratedSets( ....: Family([1,2,3], Partitions), facade=True) sage: U._element_constructor_ - """ if not self._facade: diff --git a/src/sage/structure/category_object.pyx b/src/sage/structure/category_object.pyx index 98ab3d16a45..334ee91430d 100644 --- a/src/sage/structure/category_object.pyx +++ b/src/sage/structure/category_object.pyx @@ -782,7 +782,7 @@ cdef class CategoryObject(SageObject): its categories, that is from ``EuclideanDomains().parent_class``:: sage: ZZ._test_associativity - + sage: ZZ._test_associativity(verbose = True) sage: TestSuite(ZZ).run(verbose = True) running ._test_additive_associativity() . . . pass diff --git a/src/sage/structure/element.pyx b/src/sage/structure/element.pyx index 76df456113e..369d3e25f18 100644 --- a/src/sage/structure/element.pyx +++ b/src/sage/structure/element.pyx @@ -474,7 +474,7 @@ cdef class Element(SageObject): category of ``CommutativeRings()``:: sage: 1.is_idempotent - + sage: 1.is_idempotent.__module__ 'sage.categories.magmas' @@ -485,7 +485,7 @@ cdef class Element(SageObject): ... AttributeError: 'sage.rings.integer.Integer' object has no attribute 'blah_blah' sage: Semigroups().example().an_element().is_idempotent - + sage: Semigroups().example().an_element().blah_blah Traceback (most recent call last): ... From d5058483689a479fa5ea0b29ad625437fa0272fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 15:49:05 +0100 Subject: [PATCH 277/378] 32813: added description to script 'sage -t' --- src/bin/sage-runtests | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index d7a416185f8..6b73e07cbab 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -28,7 +28,10 @@ def _get_optional_defaults(): if __name__ == "__main__": - parser = argparse.ArgumentParser(usage="sage -t [options] filenames") + parser = argparse.ArgumentParser(usage="sage -t [options] filenames", + description="Run all tests in a file or a list of files whose extensions " + "are one of the following: " + ".py, .pyx, .pxd, .pxi, .sage, .spyx, .tex, .rst.") parser.add_argument("-p", "--nthreads", dest="nthreads", type=int, nargs='?', const=0, default=1, metavar="N", help="tests in parallel using N threads with 0 interpreted as max(2, min(8, cpu_count()))") From cb2cb0023271428c7f498fd25cd7237760104071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 15:49:43 +0100 Subject: [PATCH 278/378] 32813: improved error message for invalid extension file provided to 'sage -t' --- src/sage/doctest/sources.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 7acb33de658..f9f9259da5f 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -514,7 +514,8 @@ def __init__(self, path, options): self.path = path DocTestSource.__init__(self, options) base, ext = os.path.splitext(path) - if ext in ('.py', '.pyx', '.pxd', '.pxi', '.sage', '.spyx'): + valid_code_ext = ('.py', '.pyx', '.pxd', '.pxi', '.sage', '.spyx') + if ext in valid_code_ext: self.__class__ = dynamic_class('PythonFileSource',(FileDocTestSource,PythonSource)) self.encoding = "utf-8" elif ext == '.tex': @@ -524,7 +525,9 @@ def __init__(self, path, options): self.__class__ = dynamic_class('RestFileSource',(FileDocTestSource,RestSource)) self.encoding = "utf-8" else: - raise ValueError("unknown file extension %r"%ext) + valid_ext = ", ".join(valid_code_ext + ('.tex', '.rst')) + raise ValueError("unknown extension (={}) for the file to test," + " valid extensions are: {}".format(ext, valid_ext)) def __iter__(self): r""" From 8068ba5d1b1e0919c9059d04dede6472b9f6bbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:02:25 +0100 Subject: [PATCH 279/378] 32650: Creating feature dvipng --- src/sage/features/dvipng.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/sage/features/dvipng.py diff --git a/src/sage/features/dvipng.py b/src/sage/features/dvipng.py new file mode 100644 index 00000000000..27c5bddc059 --- /dev/null +++ b/src/sage/features/dvipng.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +r""" +Check for dvipng +""" +# **************************************************************************** +# Copyright (C) 2021 Sebastien Labbe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from . import Executable + +class dvipng(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``dvipng`` + + EXAMPLES:: + + sage: from sage.features.dvipng import dvipng + sage: dvipng().is_present() # optional: dvipng + FeatureTestResult('dvipng', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.dvipng import dvipng + sage: isinstance(dvipng(), dvipng) + True + """ + Executable.__init__(self, "dvipng", executable="dvipng", + url="https://savannah.nongnu.org/projects/dvipng/") From a96e94d31d38c59db30d1995711203777cd67a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:02:36 +0100 Subject: [PATCH 280/378] 32650: Creating feature pdf2svg --- src/sage/features/pdf2svg.py | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/sage/features/pdf2svg.py diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py new file mode 100644 index 00000000000..1176706f127 --- /dev/null +++ b/src/sage/features/pdf2svg.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +r""" +Check for pdf2svg +""" +# **************************************************************************** +# Copyright (C) 2021 Sebastien Labbe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from . import Executable + +class pdf2svg(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``pdf2svg`` + + EXAMPLES:: + + sage: from sage.features.pdf2svg import pdf2svg + sage: pdf2svg().is_present() # optional: pdf2svg + FeatureTestResult('pdf2svg', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.pdf2svg import pdf2svg + sage: isinstance(pdf2svg(), pdf2svg) + True + """ + Executable.__init__(self, "pdf2svg", executable="pdf2svg", + url="http://www.cityinthesky.co.uk/opensource/pdf2svg/") From 870d461bdd5484894ff3d7c030f33757bea99bd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:02:52 +0100 Subject: [PATCH 281/378] 32650: Creating features latex, xelatex, pdflatex, lualatex --- src/sage/features/latex.py | 121 +++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/sage/features/latex.py diff --git a/src/sage/features/latex.py b/src/sage/features/latex.py new file mode 100644 index 00000000000..8352e031ca9 --- /dev/null +++ b/src/sage/features/latex.py @@ -0,0 +1,121 @@ +# -*- coding: utf-8 -*- +r""" +Check for pdflatex and equivalent programs +""" +# **************************************************************************** +# Copyright (C) 2021 Sebastien Labbe +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# https://www.gnu.org/licenses/ +# **************************************************************************** + +from . import Executable, FeatureTestResult + +class latex(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``latex`` + + EXAMPLES:: + + sage: from sage.features.latex import latex + sage: latex().is_present() # optional: latex + FeatureTestResult('latex', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.latex import latex + sage: isinstance(latex(), latex) + True + """ + Executable.__init__(self, "latex", executable="latex", + url="https://www.latex-project.org/") + + def is_functional(self): + r""" + Return whether `latex` in the path is functional. + + EXAMPLES: + + sage: from sage.features.latex import latex + sage: latex().is_functional() # optional: latex + FeatureTestResult('latex', True) + """ + from sage.misc.latex import _run_latex_, _latex_file_ + from sage.misc.temporary_file import tmp_filename + try: + f = tmp_filename(ext='.tex') + O = open(f, 'w') + O.write(_latex_file_('2+3')) + O.close() + _run_latex_(f) + return FeatureTestResult(self, True) + except Exception: + return FeatureTestResult(self, False, reason="Running latex on a sample file raised an exception") + +class pdflatex(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``pdflatex`` + + EXAMPLES:: + + sage: from sage.features.latex import pdflatex + sage: pdflatex().is_present() # optional: pdflatex + FeatureTestResult('pdflatex', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.latex import pdflatex + sage: isinstance(pdflatex(), pdflatex) + True + """ + Executable.__init__(self, "pdflatex", executable="pdflatex", + url="https://www.latex-project.org/") + +class xelatex(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``xelatex`` + + EXAMPLES:: + + sage: from sage.features.latex import xelatex + sage: xelatex().is_present() # optional: xelatex + FeatureTestResult('xelatex', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.latex import xelatex + sage: isinstance(xelatex(), xelatex) + True + """ + Executable.__init__(self, "xelatex", executable="xelatex", + url="https://www.latex-project.org/") + +class lualatex(Executable): + r""" + A :class:`sage.features.Feature` describing the presence of ``lualatex`` + + EXAMPLES:: + + sage: from sage.features.latex import lualatex + sage: lualatex().is_present() # optional: lualatex + FeatureTestResult('lualatex', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.latex import lualatex + sage: isinstance(lualatex(), lualatex) + True + """ + Executable.__init__(self, "lualatex", executable="lualatex", + url="https://www.latex-project.org/") From 385569e797b35f16a1f336ec25bfa8126bfdf969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:04:00 +0100 Subject: [PATCH 282/378] 32650: adding latex, xelatex, pdflatex, lualatex, pdf2svg, dvipng to doctest/external.py --- src/sage/doctest/external.py | 72 +++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 3b22670ec61..11270d32128 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -77,6 +77,45 @@ def has_latex(): except Exception: return False +def has_xelatex(): + """ + Test if xelatex is available. + + EXAMPLES:: + + sage: from sage.doctest.external import has_xelatex + sage: has_xelatex() # optional -- xelatex + FeatureTestResult('xelatex', True) + """ + from sage.features.latex import xelatex + return xelatex().is_present() + +def has_pdflatex(): + """ + Test if pdflatex is available. + + EXAMPLES:: + + sage: from sage.doctest.external import has_pdflatex + sage: has_pdflatex() # optional -- pdflatex + FeatureTestResult('pdflatex', True) + """ + from sage.features.latex import pdflatex + return pdflatex().is_present() + +def has_lualatex(): + """ + Test if lualatex is available. + + EXAMPLES:: + + sage: from sage.doctest.external import has_lualatex + sage: has_lualatex() # optional -- lualatex + FeatureTestResult('lualatex', True) + """ + from sage.features.latex import lualatex + return lualatex().is_present() + def has_magma(): """ Test if Magma is available. @@ -274,6 +313,32 @@ def has_imagemagick(): from sage.features.imagemagick import ImageMagick return ImageMagick().is_present() +def has_dvipng(): + """ + Test if dvipng is available. + + EXAMPLES:: + + sage: from sage.doctest.external import has_dvipng + sage: has_dvipng() # optional -- dvipng + FeatureTestResult('dvipng', True) + """ + from sage.features.dvipng import dvipng + return dvipng().is_present() + +def has_pdf2svg(): + """ + Test if pdf2svg is available. + + EXAMPLES:: + + sage: from sage.doctest.external import has_pdf2svg + sage: has_pdf2svg() # optional -- pdf2svg + FeatureTestResult('pdf2svg', True) + """ + from sage.features.pdf2svg import pdf2svg + return pdf2svg().is_present() + def has_rubiks(): """ Test if the rubiks package (``cu2``, ``cubex``, ``dikcube``, @@ -345,12 +410,14 @@ class AvailableSoftware(object): sage: external_software ['4ti2', 'cplex', + 'dvipng', 'ffmpeg', 'graphviz', 'gurobi', 'imagemagick', 'internet', 'latex', + 'lualatex', 'macaulay2', 'magma', 'maple', @@ -358,8 +425,11 @@ class AvailableSoftware(object): 'matlab', 'octave', 'pandoc', + 'pdf2svg', + 'pdflatex', 'rubiks', - 'scilab'] + 'scilab', + 'xelatex'] sage: 'internet' in available_software # random, optional - internet True sage: available_software.issuperset(set(['internet','latex'])) # random, optional - internet latex From f3291d8191a32978090febfb343fe2af39b43ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:05:02 +0100 Subject: [PATCH 283/378] 32650: using features instead of have_program in misc/latex.py --- src/sage/misc/latex.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index b7dbccdbcd8..c57f7eefeb6 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -80,8 +80,8 @@ def have_latex() -> bool: sage: have_latex() # random True """ - from sage.misc.sage_ostools import have_program - return have_program('latex') + from sage.features.latex import latex + return latex().is_present() @cached_function @@ -98,8 +98,8 @@ def have_pdflatex() -> bool: sage: have_pdflatex() # random True """ - from sage.misc.sage_ostools import have_program - return have_program('pdflatex') + from sage.features.latex import pdflatex + return pdflatex().is_present() @cached_function @@ -116,8 +116,8 @@ def have_xelatex() -> bool: sage: have_xelatex() # random True """ - from sage.misc.sage_ostools import have_program - return have_program('xelatex') + from sage.features.latex import xelatex + return xelatex().is_present() @cached_function @@ -134,9 +134,8 @@ def have_dvipng() -> bool: sage: have_dvipng() # random True """ - from sage.misc.sage_ostools import have_program - return have_program('dvipng') - + from sage.features.dvipng import dvipng + return dvipng().is_present() @cached_function def have_convert() -> bool: @@ -153,8 +152,8 @@ def have_convert() -> bool: sage: have_convert() # random True """ - from sage.misc.sage_ostools import have_program - return have_program('convert') + from sage.features.imagemagick import ImageMagick + return ImageMagick().is_present() def list_function(x): From d4559932b6311de0a825154947daaedbda9099e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:31:47 +0100 Subject: [PATCH 284/378] 32650: using features in plot/animate.py --- src/sage/plot/animate.py | 287 ++++++++++++++++++++++----------------- 1 file changed, 159 insertions(+), 128 deletions(-) diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index 82632fefcb8..96388659111 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -576,50 +576,100 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, See www.imagemagick.org and www.ffmpeg.org for more information. """ - from sage.misc.sage_ostools import have_program - have_convert = have_program('convert') - have_ffmpeg = self._have_ffmpeg() - if use_ffmpeg or not have_convert: - if have_ffmpeg: - self.ffmpeg(savefile=savefile, show_path=show_path, - output_format='.gif', delay=delay, - iterations=iterations) - else: - if not have_convert: - msg = """ -Error: Neither ImageMagick nor ffmpeg appears to be installed. Saving an -animation to a GIF file or displaying an animation requires one of these -packages, so please install one of them and try again. - -See www.imagemagick.org and www.ffmpeg.org for more information.""" - else: - msg = """ -Error: ffmpeg does not appear to be installed. Download it from -www.ffmpeg.org, or use 'convert' to produce gifs instead.""" - raise OSError(msg) + from sage.features.imagemagick import ImageMagick + from sage.features.ffmpeg import FFmpeg + + if not ImageMagick().is_present() and not FFmpeg().is_present(): + raise OSError("Error: Neither ImageMagick nor ffmpeg appear to " + "be installed. Saving an animation to a GIF file or " + "displaying an animation requires one of these " + "packages, so please install one of them and try " + "again. See www.imagemagick.org and www.ffmpeg.org " + "for more information.") + + if use_ffmpeg or not ImageMagick().is_present(): + self.ffmpeg(savefile=savefile, show_path=show_path, + output_format='.gif', delay=delay, + iterations=iterations) else: - if not savefile: - savefile = tmp_filename(ext='.gif') - if not savefile.endswith('.gif'): - savefile += '.gif' - savefile = os.path.abspath(savefile) - d = self.png() - cmd = ( 'cd "%s"; sage-native-execute convert -dispose Background ' - '-delay %s -loop %s *.png "%s"' ) % ( d, int(delay), - int(iterations), savefile ) - from subprocess import check_call, CalledProcessError - try: - check_call(cmd, shell=True) - if show_path: - print("Animation saved to file %s." % savefile) - except (CalledProcessError, OSError): - msg = """ -Error: Cannot generate GIF animation. Verify that convert -(ImageMagick) or ffmpeg is installed, and that the objects passed to -the animate command can be saved in PNG image format. - -See www.imagemagick.org and www.ffmpeg.org for more information.""" - raise OSError(msg) + self._gif_from_imagemagick(savefile=savefile, show_path=show_path, + delay=delay, iterations=iterations) + + def _gif_from_imagemagick(self, savefile=None, show_path=False, + delay=20, iterations=0): + r""" + Return a movie showing an animation composed from rendering + the frames in ``self``. + + This method will only work if ``imagemagick`` is installed (command + ``convert``). See https://www.imagemagick.org for information + about ``imagemagick``. + + INPUT: + + - ``savefile`` -- file that the mpeg gets saved to. + + .. warning:: + + This will overwrite ``savefile`` if it already exists. + + - ``show_path`` -- boolean (default: ``False``); if ``True``, + print the path to the saved file + + - ``delay`` - (default: 20) delay in hundredths of a + second between frames + + - ``iterations`` - integer (default: 0); number of iterations + of animation. If 0, loop forever. + + If ``savefile`` is not specified: in notebook mode, display + the animation; otherwise, save it to a default file name. Use + :func:`sage.misc.verbose.set_verbose` with ``level=1`` to see + additional output. + + EXAMPLES:: + + sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], + ....: xmin=0, xmax=2*pi, ymin=-1, ymax=1, figsize=[2,1]) + sage: td = tmp_dir() + sage: a._gif_from_imagemagick(savefile=td + 'new.gif') # optional -- imagemagick + + .. note:: + + If imagemagick is not installed, you will get an error message + like this:: + + FeatureNotPresentError: imagemagick is not available. + Executable 'convert' not found on PATH. + Further installation instructions might be available at + https://www.imagemagick.org/. + + """ + from sage.features.imagemagick import ImageMagick + ImageMagick().require() + + if not savefile: + savefile = tmp_filename(ext='.gif') + if not savefile.endswith('.gif'): + savefile += '.gif' + savefile = os.path.abspath(savefile) + + d = self.png() + cmd = ( 'cd "%s"; sage-native-execute convert -dispose Background ' + '-delay %s -loop %s *.png "%s"' ) % ( d, int(delay), + int(iterations), savefile ) + from subprocess import check_call, CalledProcessError + try: + check_call(cmd, shell=True) + if show_path: + print("Animation saved to file %s." % savefile) + except (CalledProcessError, OSError): + raise OSError("Error: Cannot generate GIF animation. " + "Verify that convert (ImageMagick) or ffmpeg is " + "installed, and that the objects passed to the " + "animate command can be saved in PNG image format. " + "See www.imagemagick.org and www.ffmpeg.org for " + "more information.") def _rich_repr_(self, display_manager, **kwds): """ @@ -778,19 +828,6 @@ def show(self, delay=None, iterations=None, **kwds): dm = get_display_manager() dm.display_immediately(self, **kwds) - def _have_ffmpeg(self): - """ - Return True if the program 'ffmpeg' is installed. See - www.ffmpeg.org to download ffmpeg. - - EXAMPLES:: - - sage: a = animate([plot(sin, -1,1)], xmin=0, ymin=0) - sage: a._have_ffmpeg() # random: depends on whether ffmpeg is installed - False - """ - from sage.misc.sage_ostools import have_program - return have_program('ffmpeg') def ffmpeg(self, savefile=None, show_path=False, output_format=None, ffmpeg_options='', delay=None, iterations=0, pix_fmt='rgb24'): @@ -860,86 +897,80 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, If ffmpeg is not installed, you will get an error message like this:: - Error: ffmpeg does not appear to be installed. Saving an animation to - a movie file in any format other than GIF requires this software, so - please install it and try again. - - See www.ffmpeg.org for more information. - + FeatureNotPresentError: ffmpeg is not available. + Executable 'ffmpeg' not found on PATH. + Further installation instructions might be available at https://www.ffmpeg.org/. TESTS:: sage: a.ffmpeg(output_format='gif',delay=30,iterations=5) # optional -- ffmpeg """ - if not self._have_ffmpeg(): - msg = """Error: ffmpeg does not appear to be installed. Saving an animation to -a movie file in any format other than GIF requires this software, so -please install it and try again.""" - raise OSError(msg) + from sage.features.ffmpeg import FFmpeg + FFmpeg().require() + + if savefile is None: + if output_format is None: + output_format = '.mpg' + else: + if output_format[0] != '.': + output_format = '.'+output_format + savefile = tmp_filename(ext=output_format) else: - if savefile is None: - if output_format is None: - output_format = '.mpg' + if output_format is None: + suffix = os.path.splitext(savefile)[1] + if len(suffix) > 0: + output_format = suffix else: - if output_format[0] != '.': - output_format = '.'+output_format - savefile = tmp_filename(ext=output_format) + output_format = '.mpg' + if not savefile.endswith(output_format): + savefile += output_format + early_options = '' + if output_format == '.gif': + # We try to set reasonable options for gif output. + # + # Older versions of ffmpeg (before 0.9, summer 2011) + # use the option -loop_output instead of -loop. + # Setting iterations=None is a way of preventing sage + # from adding the -loop option. A separate + # -loop_output option can be added with the + # ffmpeg_options argument. + if iterations is not None: + loop_cmd = '-loop {0} '.format(iterations) else: - if output_format is None: - suffix = os.path.splitext(savefile)[1] - if len(suffix) > 0: - output_format = suffix - else: - output_format = '.mpg' - if not savefile.endswith(output_format): - savefile += output_format - early_options = '' - if output_format == '.gif': - # We try to set reasonable options for gif output. - # - # Older versions of ffmpeg (before 0.9, summer 2011) - # use the option -loop_output instead of -loop. - # Setting iterations=None is a way of preventing sage - # from adding the -loop option. A separate - # -loop_output option can be added with the - # ffmpeg_options argument. - if iterations is not None: - loop_cmd = '-loop {0} '.format(iterations) - else: - loop_cmd = '' - # A pix_fmt value is required for some but not all - # ffmpeg installations. Setting pix_fmt=None will - # prevent sage from adding this option, and it may be - # controlled separately through ffmpeg_options. - if pix_fmt is not None: - pix_fmt_cmd = '-pix_fmt {0} '.format(pix_fmt) - else: - pix_fmt_cmd = '' - ffmpeg_options += ' {0}{1}'.format(pix_fmt_cmd,loop_cmd) - if delay is not None and output_format != '.mpeg' and output_format != '.mpg': - early_options += ' -r %s ' % int(100/delay) - savefile = os.path.abspath(savefile) - pngdir = self.png() - pngs = os.path.join(pngdir, "%08d.png") - # For ffmpeg, it seems that some options, like '-g ... -r - # ...', need to come before the input file names, while - # some options, like '-pix_fmt rgb24', need to come - # afterwards. Hence 'early_options' and 'ffmpeg_options' - cmd = 'cd "%s"; sage-native-execute ffmpeg -y -f image2 %s -i %s %s %s' % (pngdir, early_options, pngs, ffmpeg_options, savefile) - from subprocess import check_call, CalledProcessError, PIPE - try: - if sage.misc.verbose.get_verbose() > 0: - set_stderr = None - else: - set_stderr = PIPE - sage.misc.verbose.verbose("Executing '%s'" % cmd,level=1) - sage.misc.verbose.verbose("\n---- ffmpeg output below ----\n") - check_call(cmd, shell=True, stderr=set_stderr) - if show_path: - print("Animation saved to file %s." % savefile) - except (CalledProcessError, OSError): - print("Error running ffmpeg.") - raise + loop_cmd = '' + # A pix_fmt value is required for some but not all + # ffmpeg installations. Setting pix_fmt=None will + # prevent sage from adding this option, and it may be + # controlled separately through ffmpeg_options. + if pix_fmt is not None: + pix_fmt_cmd = '-pix_fmt {0} '.format(pix_fmt) + else: + pix_fmt_cmd = '' + ffmpeg_options += ' {0}{1}'.format(pix_fmt_cmd,loop_cmd) + if delay is not None and output_format != '.mpeg' and output_format != '.mpg': + early_options += ' -r %s ' % int(100/delay) + savefile = os.path.abspath(savefile) + pngdir = self.png() + pngs = os.path.join(pngdir, "%08d.png") + # For ffmpeg, it seems that some options, like '-g ... -r + # ...', need to come before the input file names, while + # some options, like '-pix_fmt rgb24', need to come + # afterwards. Hence 'early_options' and 'ffmpeg_options' + cmd = 'cd "%s"; sage-native-execute ffmpeg -y -f image2 %s -i %s %s %s' % (pngdir, early_options, pngs, ffmpeg_options, savefile) + from subprocess import check_call, CalledProcessError, PIPE + try: + if sage.misc.verbose.get_verbose() > 0: + set_stderr = None + else: + set_stderr = PIPE + sage.misc.verbose.verbose("Executing '%s'" % cmd,level=1) + sage.misc.verbose.verbose("\n---- ffmpeg output below ----\n") + check_call(cmd, shell=True, stderr=set_stderr) + if show_path: + print("Animation saved to file %s." % savefile) + except (CalledProcessError, OSError): + print("Error running ffmpeg.") + raise def apng(self, savefile=None, show_path=False, delay=20, iterations=0): r""" From cf02094eda368e2e9ad381b0bad65e06c56c383a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 17:39:05 +0100 Subject: [PATCH 285/378] 32650: using features in plot/graphics.py and plot/multigraphics.py --- src/sage/plot/graphics.py | 12 ++++++++---- src/sage/plot/multigraphics.py | 12 ++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index fce17eec618..61fa25dd277 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -3310,10 +3310,14 @@ def save(self, filename, **kwds): # on the file extension. # PGF is handled by a different backend if ext == '.pgf': - from sage.misc.sage_ostools import have_program - latex_implementations = [i for i in ["xelatex", "pdflatex", - "lualatex"] - if have_program(i)] + from sage.features.latex import xelatex,pdflatex,lualatex + latex_implementations = [] + if xelatex().is_present(): + latex_implementations.append('xelatex') + if pdflatex().is_present(): + latex_implementations.append('pdflatex') + if lualatex().is_present(): + latex_implementations.append('lualatex') if not latex_implementations: raise ValueError("Matplotlib requires either xelatex, " "lualatex, or pdflatex.") diff --git a/src/sage/plot/multigraphics.py b/src/sage/plot/multigraphics.py index 6fa90dd6bbc..6f441561a99 100644 --- a/src/sage/plot/multigraphics.py +++ b/src/sage/plot/multigraphics.py @@ -453,10 +453,14 @@ def save(self, filename, figsize=None, **kwds): # depending on the file extension. # PGF is handled by a different backend if ext == '.pgf': - from sage.misc.sage_ostools import have_program - latex_implementations = [i for i in ["xelatex", "pdflatex", - "lualatex"] - if have_program(i)] + from sage.features.latex import xelatex,pdflatex,lualatex + latex_implementations = [] + if xelatex().is_present(): + latex_implementations.append('xelatex') + if pdflatex().is_present(): + latex_implementations.append('pdflatex') + if lualatex().is_present(): + latex_implementations.append('lualatex') if not latex_implementations: raise ValueError("Matplotlib requires either xelatex, " "lualatex, or pdflatex.") From 28f1f4a5fef37adebff969b86913533501f8fa76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Tue, 2 Nov 2021 22:18:18 +0100 Subject: [PATCH 286/378] 32650: deprecating have_* functions in misc/latex.py in favor of features --- src/sage/misc/latex.py | 64 +++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index c57f7eefeb6..2c41565519a 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -80,6 +80,9 @@ def have_latex() -> bool: sage: have_latex() # random True """ + from .superseded import deprecation + deprecation(32650, 'the function have_latex() is replaced by: ' + 'from sage.features.latex import latex;latex().is_present()') from sage.features.latex import latex return latex().is_present() @@ -98,6 +101,9 @@ def have_pdflatex() -> bool: sage: have_pdflatex() # random True """ + from .superseded import deprecation + deprecation(32650, 'the function have_pdflatex() is replaced by: ' + 'from sage.features.latex import pdflatex;pdflatex().is_present()') from sage.features.latex import pdflatex return pdflatex().is_present() @@ -116,6 +122,9 @@ def have_xelatex() -> bool: sage: have_xelatex() # random True """ + from .superseded import deprecation + deprecation(32650, 'the function have_xelatex() is replaced by: ' + 'from sage.features.latex import xelatex;xelatex().is_present()') from sage.features.latex import xelatex return xelatex().is_present() @@ -134,6 +143,9 @@ def have_dvipng() -> bool: sage: have_dvipng() # random True """ + from .superseded import deprecation + deprecation(32650, 'the function have_dvipng() is replaced by: ' + 'from sage.features.dvipng import dvipng;dvipng().is_present()') from sage.features.dvipng import dvipng return dvipng().is_present() @@ -152,6 +164,9 @@ def have_convert() -> bool: sage: have_convert() # random True """ + from .superseded import deprecation + deprecation(32650, 'the function have_convert() is replaced by: ' + 'from sage.features.imagemagick import imagemagick;imagemagick().is_present()') from sage.features.imagemagick import ImageMagick return ImageMagick().is_present() @@ -699,27 +714,21 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i engine = _Latex_prefs._option["engine"] if not engine or engine == "latex": - if not have_latex(): - print("Error: LaTeX does not seem to be installed. Download it from") - print("ctan.org and try again.") - return "Error" + from sage.features.latex import latex + latex().require() command = "latex" # 'suffix' is used in the 'convert' command list suffix = "ps" return_suffix = "dvi" elif engine == "pdflatex": - if not have_pdflatex(): - print("Error: PDFLaTeX does not seem to be installed. Download it from") - print("ctan.org and try again.") - return "Error" + from sage.features.latex import pdflatex + pdflatex().require() command = "pdflatex" suffix = "pdf" return_suffix = "pdf" elif engine == "xelatex": - if not have_xelatex(): - print("Error: XeLaTeX does not seem to be installed. Download it from") - print("ctan.org and try again.") - return "Error" + from sage.features.latex import xelatex + xelatex().require() command = "xelatex" suffix = "pdf" return_suffix = "pdf" @@ -727,8 +736,11 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i raise ValueError("Unsupported LaTeX engine.") # if png output + latex, check to see if dvipng or convert is installed. + from sage.features.imagemagick import ImageMagick + from sage.features.dvipng import dvipng if png: - if (not engine or engine == "latex") and not (have_dvipng() or have_convert()): + if ((not engine or engine == "latex") + and not (dvipng().is_present() or ImageMagick().is_present())): print() print("Error: neither dvipng nor convert (from the ImageMagick suite)") print("appear to be installed. Displaying LaTeX, PDFLaTeX output") @@ -739,22 +751,10 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i print("http://www.imagemagick.org to download these programs.") return "Error" # if png output + pdflatex, check to see if convert is installed. - elif engine == "pdflatex" and not have_convert(): - print() - print("Error: convert (from the ImageMagick suite) does not") - print("appear to be installed. Displaying PDFLaTeX output") - print("requires this program, so please install and try again.") - print() - print("Go to http://www.imagemagick.org to download it.") - return "Error" - elif engine == "xelatex" and not have_convert(): - print() - print("Error: convert (from the ImageMagick suite) does not") - print("appear to be installed. Displaying XeLaTeX output") - print("requires this program, so please install and try again.") - print() - print("Go to http://www.imagemagick.org to download it.") - return "Error" + elif engine == "pdflatex": + ImageMagick().require() + elif engine == "xelatex": + ImageMagick().require() # check_validity: check to see if the dvi file is okay by trying # to convert to a png file. if this fails, return_suffix will be # set to "pdf". return_suffix is the return value for this @@ -763,7 +763,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i # thus if not png output, check validity of dvi output if dvipng # or convert is installed. else: - check_validity = have_dvipng() + check_validity = dvipng().is_present() # set up filenames, other strings: base, filename = os.path.split(filename) filename = os.path.splitext(filename)[0] # get rid of extension @@ -816,7 +816,7 @@ def subpcall(x): e = e and subpcall(convert) else: # latex if (png or check_validity): - if have_dvipng(): + if dvipng().is_present(): if debug: print(lt) print(dvipng) @@ -829,7 +829,7 @@ def subpcall(x): # fail also, so we'll still catch the error.) if dvipng_error: if png: - if have_convert(): + if ImageMagick().is_present(): if debug: print("'dvipng' failed; trying 'convert' instead...") print(dvips) From 0f7cca71c8faebaae554fddd0d3ae0ff00e51195 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 3 Nov 2021 11:22:16 +0100 Subject: [PATCH 287/378] euclidean division may still work, if the leading coefficient is not a unit --- .../polynomial/polynomial_element_generic.py | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_element_generic.py b/src/sage/rings/polynomial/polynomial_element_generic.py index a8a5065f827..275470b15fd 100644 --- a/src/sage/rings/polynomial/polynomial_element_generic.py +++ b/src/sage/rings/polynomial/polynomial_element_generic.py @@ -767,16 +767,20 @@ def quo_rem(self, other): Returns the quotient and remainder of the Euclidean division of ``self`` and ``other``. - Raises ZerodivisionError if ``other`` is zero. Raises ArithmeticError - if ``other`` has a nonunit leading coefficient. + Raises ZerodivisionError if ``other`` is zero. + + Raises ArithmeticError if ``other`` has a nonunit leading coefficient + and this causes the Euclidean division to fail. EXAMPLES:: - sage: P. = PolynomialRing(ZZ,sparse=True) - sage: R. = PolynomialRing(P,sparse=True) + sage: P. = PolynomialRing(ZZ, sparse=True) + sage: R. = PolynomialRing(P, sparse=True) sage: f = R.random_element(10) - sage: g = y^5+R.random_element(4) - sage: q,r = f.quo_rem(g) + sage: while x.divides(f.leading_coefficient()): + ....: f = R.random_element(10) + sage: g = y^5 + R.random_element(4) + sage: q, r = f.quo_rem(g) sage: f == q*g + r and r.degree() < g.degree() True sage: g = x*y^5 @@ -790,25 +794,32 @@ def quo_rem(self, other): ... ZeroDivisionError: Division by zero polynomial + If the leading coefficient of ``other`` is not a unit, Euclidean division may still work:: + + sage: f = -x*y^10 + 2*x*y^7 + y^3 - 2*x^2*y^2 - y + sage: g = x*y^5 + sage: f.quo_rem(g) + (-y^5 + 2*y^2, y^3 - 2*x^2*y^2 - y) + TESTS:: - sage: P. = PolynomialRing(ZZ,sparse=True) - sage: f = x^10-4*x^6-5 - sage: g = 17*x^22+x^15-3*x^5+1 - sage: q,r = g.quo_rem(f) + sage: P. = PolynomialRing(ZZ, sparse=True) + sage: f = x^10 - 4*x^6 - 5 + sage: g = 17*x^22 + x^15 - 3*x^5 + 1 + sage: q, r = g.quo_rem(f) sage: g == f*q + r and r.degree() < f.degree() True sage: zero = P(0) sage: zero.quo_rem(f) (0, 0) sage: Q. = IntegerModRing(14)[] - sage: f = y^10-4*y^6-5 - sage: g = 17*y^22+y^15-3*y^5+1 - sage: q,r = g.quo_rem(f) + sage: f = y^10 - 4*y^6 - 5 + sage: g = 17*y^22 + y^15 - 3*y^5 + 1 + sage: q, r = g.quo_rem(f) sage: g == f*q + r and r.degree() < f.degree() True - sage: f += 2*y^10 # 3 is invertible mod 14 - sage: q,r = g.quo_rem(f) + sage: f += 2*y^10 # 3 is invertible mod 14 + sage: q, r = g.quo_rem(f) sage: g == f*q + r and r.degree() < f.degree() True From 4b2e8b832956a4e427779c2727f33eca73c9053f Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 3 Nov 2021 11:39:47 +0100 Subject: [PATCH 288/378] fix two tests failing at random --- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 6 +++--- src/sage/rings/polynomial/multi_polynomial_ring_base.pyx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index d4cb66af782..7eacde3babc 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -6940,10 +6940,10 @@ def conjugating_set(self, other, R=None, num_cpus=2): sage: P. = ProjectiveSpace(GF(7), 1) sage: D6 = DynamicalSystem_projective([y^2, x^2]) - sage: D6.conjugating_set(D6) + sage: sorted(D6.conjugating_set(D6)) [ - [1 0] [0 1] [0 2] [4 0] [2 0] [0 4] - [0 1], [1 0], [1 0], [0 1], [0 1], [1 0] + [0 1] [0 2] [0 4] [1 0] [2 0] [4 0] + [1 0], [1 0], [1 0], [0 1], [0 1], [0 1] ] :: diff --git a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx index 4378d955880..5b99c540de2 100644 --- a/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_ring_base.pyx @@ -990,7 +990,7 @@ cdef class MPolynomialRing_base(sage.rings.ring.CommutativeRing): sage: R = QQ['x,y'] sage: S = R['t,u'] - sage: f = S.random_element(degree=2, terms=1) + sage: f = S._random_nonzero_element(degree=2, terms=1) sage: len(list(f)) 1 sage: f.degree() <= 2 From bb58f1b8e29ea4589ab309205e2fdebff6ece52d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Wed, 3 Nov 2021 12:06:47 +0100 Subject: [PATCH 289/378] 32813: also provide the filename in error message not only the wrong extension --- src/sage/doctest/sources.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index f9f9259da5f..f60c275af74 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -495,6 +495,18 @@ class FileDocTestSource(DocTestSource): TESTS:: sage: TestSuite(FDS).run() + + :: + + sage: from sage.doctest.control import DocTestDefaults + sage: from sage.doctest.sources import FileDocTestSource + sage: filename = tmp_filename(ext=".txtt") + sage: FDS = FileDocTestSource(filename,DocTestDefaults()) + Traceback (most recent call last): + ... + ValueError: unknown extension for the file to test (=...txtt), + valid extensions are: .py, .pyx, .pxd, .pxi, .sage, .spyx, .tex, .rst + """ def __init__(self, path, options): """ @@ -526,8 +538,8 @@ def __init__(self, path, options): self.encoding = "utf-8" else: valid_ext = ", ".join(valid_code_ext + ('.tex', '.rst')) - raise ValueError("unknown extension (={}) for the file to test," - " valid extensions are: {}".format(ext, valid_ext)) + raise ValueError("unknown extension for the file to test (={})," + " valid extensions are: {}".format(path, valid_ext)) def __iter__(self): r""" From 13728fe03171f8d3359fcf8e28052850e56f9789 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Wed, 3 Nov 2021 12:19:39 +0100 Subject: [PATCH 290/378] 32818: args -> args.filenames --- src/bin/sage-runtests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/sage-runtests b/src/bin/sage-runtests index d7a416185f8..882456dd15d 100755 --- a/src/bin/sage-runtests +++ b/src/bin/sage-runtests @@ -156,7 +156,7 @@ if __name__ == "__main__": pytest_options = ["--import-mode", "importlib"] if args.verbose: pytest_options.append("-v") - exit_code_pytest = pytest.main(pytest_options + args) + exit_code_pytest = pytest.main(pytest_options + args.filenames) except ModuleNotFoundError: print("Pytest is not installed, skip checking tests that rely on it.") From 70c97a544569939d2210efb75be8aec5893c72c8 Mon Sep 17 00:00:00 2001 From: LLewark Date: Wed, 3 Nov 2021 13:53:02 +0100 Subject: [PATCH 291/378] Currently, the determinant is implemented only for knots. However, the determinant for multi-component links is defined in the same way as for knots. So I propose to allow multi-component links in the determinant function. Moreover, it seems simpler to take determinant of the symmetrized Seifert matrix, instead of the evaluation of the Alexander polynomial at -1. --- src/sage/knots/link.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index ff7a64eee4f..ec8ad1399c1 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1926,19 +1926,19 @@ def determinant(self): sage: L = Link(B([1]*16 + [2,1,2,1,2,2,2,2,2,2,2,1,2,1,2,-1,2,-2])) sage: L.determinant() 65 + sage: B = BraidGroup(3) + sage: Link(B([1, 2, 1, 1, 2])).determinant() + 4 TESTS:: + sage: B = BraidGroup(3) sage: Link(B([1, 2, 1, -2, -1])).determinant() - Traceback (most recent call last): - ... - NotImplementedError: determinant implemented only for knots + 0 """ - if self.is_knot(): - a = self.alexander_polynomial() - return Integer(abs(a(-1))) - - raise NotImplementedError("determinant implemented only for knots") + V = self.seifert_matrix() + m = V + V.transpose() + return Integer(abs(m.det())) def is_alternating(self): r""" From 69e5084843796bdf02985a203a2d8c30de774f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 3 Nov 2021 20:59:25 +0100 Subject: [PATCH 292/378] fix E713 and E714 in geometry --- src/sage/geometry/cone.py | 4 ++-- src/sage/geometry/cone_catalog.py | 4 ++-- src/sage/geometry/hasse_diagram.py | 2 +- src/sage/geometry/lattice_polytope.py | 6 +++--- src/sage/geometry/newton_polygon.py | 4 ++-- src/sage/geometry/polyhedron/backend_cdd.py | 2 +- src/sage/geometry/polyhedron/base_mutable.py | 2 +- src/sage/geometry/toric_lattice.py | 2 +- src/sage/geometry/triangulation/element.py | 6 +++--- src/sage/geometry/triangulation/point_configuration.py | 5 ++--- 10 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/sage/geometry/cone.py b/src/sage/geometry/cone.py index 5fbe3784b80..5f0d2d84fa5 100644 --- a/src/sage/geometry/cone.py +++ b/src/sage/geometry/cone.py @@ -1520,7 +1520,7 @@ def __init__(self, rays=None, lattice=None, self._ambient_ray_indices = tuple(ambient_ray_indices) superinit(ambient.rays(self._ambient_ray_indices), ambient.lattice()) - if not PPL is None: + if PPL is not None: self._PPL_C_Polyhedron = PPL def _sage_input_(self, sib, coerced): @@ -5466,7 +5466,7 @@ def random_element(self, ring=ZZ): sage: sum(K.random_element() for i in range(10)) in K.lattice() True """ - if not ring in [ZZ, QQ]: + if ring not in [ZZ, QQ]: # This cone theoretically lives in a real vector space, # but in Sage, we work over the rationals to avoid # numerical issues. Thus ``ring`` must consist of diff --git a/src/sage/geometry/cone_catalog.py b/src/sage/geometry/cone_catalog.py index 005f341e353..980d2e55c38 100644 --- a/src/sage/geometry/cone_catalog.py +++ b/src/sage/geometry/cone_catalog.py @@ -470,12 +470,12 @@ def rearrangement(p, ambient_dim=None, lattice=None): (ambient_dim, lattice) = _preprocess_args(ambient_dim, lattice) - if p < 1 or p > ambient_dim or not p in ZZ: + if p < 1 or p > ambient_dim or p not in ZZ: raise ValueError("order p=%s should be an integer between 1 " "and ambient_dim=%d, inclusive" % (p, ambient_dim)) I = matrix.identity(ZZ, ambient_dim) - M = matrix.ones(ZZ, ambient_dim) - p*I + M = matrix.ones(ZZ, ambient_dim) - p * I G = matrix.identity(ZZ, ambient_dim).rows() + M.rows() return Cone(G, lattice=lattice) diff --git a/src/sage/geometry/hasse_diagram.py b/src/sage/geometry/hasse_diagram.py index 29c46604e56..eeed5f560d9 100644 --- a/src/sage/geometry/hasse_diagram.py +++ b/src/sage/geometry/hasse_diagram.py @@ -157,7 +157,7 @@ def default_face_constructor(atoms, coatoms, **kwds): # Now G == {H[atom] : atom in minimals} for atom in minimals: # 9: for g in G: g_atoms, g_coatoms = H[atom] - if not required_atoms is None: + if required_atoms is not None: if g_atoms.isdisjoint(required_atoms): continue if (g_atoms, g_coatoms) in faces: diff --git a/src/sage/geometry/lattice_polytope.py b/src/sage/geometry/lattice_polytope.py index a02d9ed9d5a..9e663d40ea0 100644 --- a/src/sage/geometry/lattice_polytope.py +++ b/src/sage/geometry/lattice_polytope.py @@ -5520,10 +5520,10 @@ def convex_hull(points): vpoints = [] for p in points: v = vector(ZZ, p) - if not v in vpoints: + if v not in vpoints: vpoints.append(v) p0 = vpoints[0] - vpoints = [p-p0 for p in vpoints] + vpoints = [p - p0 for p in vpoints] N = ZZ**p0.degree() H = N.submodule(vpoints) if H.rank() == 0: @@ -5534,7 +5534,7 @@ def convex_hull(points): H_points = [H.coordinates(p) for p in vpoints] H_polytope = LatticePolytope(H_points) vpoints = (H_polytope.vertices() * H.basis_matrix()).rows(copy=False) - vpoints = [p+p0 for p in vpoints] + vpoints = [p + p0 for p in vpoints] return vpoints diff --git a/src/sage/geometry/newton_polygon.py b/src/sage/geometry/newton_polygon.py index ad977843958..7bd135abad0 100644 --- a/src/sage/geometry/newton_polygon.py +++ b/src/sage/geometry/newton_polygon.py @@ -723,7 +723,7 @@ def _element_constructor_(self, arg, sort_slopes=True, last_slope=Infinity): return self.element_class(polyhedron, parent=self) if arg == 1: polyhedron = Polyhedron(base_ring=self.base_ring(), - vertices=[(0,0)], rays=[(0,1)]) + vertices=[(0, 0)], rays=[(0, 1)]) return self.element_class(polyhedron, parent=self) if not isinstance(arg, list): try: @@ -736,7 +736,7 @@ def _element_constructor_(self, arg, sort_slopes=True, last_slope=Infinity): x = y = 0 vertices = [(x, y)] for slope in arg: - if not slope in self.base_ring(): + if slope not in self.base_ring(): raise TypeError("argument must be a list of coordinates or a list of (rational) slopes") x += 1 y += slope diff --git a/src/sage/geometry/polyhedron/backend_cdd.py b/src/sage/geometry/polyhedron/backend_cdd.py index 3a24dca5cb2..9f1f4d86ec5 100644 --- a/src/sage/geometry/polyhedron/backend_cdd.py +++ b/src/sage/geometry/polyhedron/backend_cdd.py @@ -292,7 +292,7 @@ def parse_H_representation(intro, data): from itertools import chain # We add equations to the end of the Hrepresentation. for i in chain( - (j for j in range(len(data)) if not j in equations), + (j for j in range(len(data)) if j not in equations), equations): line = data[i] coefficients = [R(x) for x in line] diff --git a/src/sage/geometry/polyhedron/base_mutable.py b/src/sage/geometry/polyhedron/base_mutable.py index d982135f1f5..6cf6a911eda 100644 --- a/src/sage/geometry/polyhedron/base_mutable.py +++ b/src/sage/geometry/polyhedron/base_mutable.py @@ -128,7 +128,7 @@ def _add_dependent_object(self, ob): sage: r Relative interior of None """ - if not ob._polyhedron is self: + if ob._polyhedron is not self: raise ValueError self._dependent_objects.append(ob) diff --git a/src/sage/geometry/toric_lattice.py b/src/sage/geometry/toric_lattice.py index e8920bfb701..7e566dc39cc 100644 --- a/src/sage/geometry/toric_lattice.py +++ b/src/sage/geometry/toric_lattice.py @@ -1170,7 +1170,7 @@ def dual(self): 2-d lattice, quotient of 3-d lattice M by Sublattice """ if "_dual" not in self.__dict__: - if not self is self.saturation(): + if self is not self.saturation(): raise ValueError("only dual lattices of saturated sublattices " "can be constructed! Got %s." % self) self._dual = (self.ambient_module().dual() / diff --git a/src/sage/geometry/triangulation/element.py b/src/sage/geometry/triangulation/element.py index 9aea06b7fb5..0c1544e9a6d 100644 --- a/src/sage/geometry/triangulation/element.py +++ b/src/sage/geometry/triangulation/element.py @@ -92,7 +92,7 @@ def triangulation_render_2d(triangulation, **kwds): all_lines.append(l) else: interior_lines.append(l) - exterior_lines = [ l for l in all_lines if not l in interior_lines ] + exterior_lines = [l for l in all_lines if l not in interior_lines] plot_interior_lines = sum([ line2d([ coord[l[0]], coord[l[1]] ], zorder=1, rgbcolor=(0,1,0), **kwds) @@ -160,7 +160,7 @@ def triangulation_render_3d(triangulation, **kwds): all_lines.append(l) else: interior_lines.append(l) - exterior_lines = [ l for l in all_lines if not l in interior_lines ] + exterior_lines = [l for l in all_lines if l not in interior_lines] from sage.plot.plot3d.texture import Texture line_int = Texture(color='darkblue', ambient=1, diffuse=0) @@ -190,7 +190,7 @@ def triangulation_render_3d(triangulation, **kwds): all_triangs.append(l) else: interior_triangs.append(l) - exterior_triangs = [ l for l in all_triangs if not l in interior_triangs ] + exterior_triangs = [l for l in all_triangs if l not in interior_triangs] plot_interior_triangs = \ sum([ polygon3d([coord[t[0]], coord[t[1]], coord[t[2]]], diff --git a/src/sage/geometry/triangulation/point_configuration.py b/src/sage/geometry/triangulation/point_configuration.py index 0346c9cdac4..b10fb8cbba6 100644 --- a/src/sage/geometry/triangulation/point_configuration.py +++ b/src/sage/geometry/triangulation/point_configuration.py @@ -1273,8 +1273,8 @@ def exclude_points(self, point_idx_list): sage: p.exclude_points( p.face_interior(codim=1) ).points() (P(-1, 0), P(0, 0), P(1, -1), P(1, 1)) """ - points = [ self.point(i) for i in range(self.n_points()) - if not i in point_idx_list ] + points = [self.point(i) for i in range(self.n_points()) + if i not in point_idx_list] return PointConfiguration(points, projective=False, connected=self._connected, @@ -1282,7 +1282,6 @@ def exclude_points(self, point_idx_list): regular=self._regular, star=self._star) - def volume(self, simplex=None): """ Find n! times the n-volume of a simplex of dimension n. From 16cff67f866c39d01f2038bf59f2a239fa2dfdde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 3 Nov 2021 21:12:59 +0100 Subject: [PATCH 293/378] fix E713 and E714 in dynamics --- .../dynamics/arithmetic_dynamics/affine_ds.py | 4 +- .../endPN_automorphism_group.py | 20 +++++----- .../arithmetic_dynamics/generic_ds.py | 4 +- .../arithmetic_dynamics/projective_ds.py | 38 +++++++++--------- .../dynamics/arithmetic_dynamics/wehlerK3.py | 40 +++++++++---------- 5 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py index 84ddb002252..219a32d4db0 100644 --- a/src/sage/dynamics/arithmetic_dynamics/affine_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/affine_ds.py @@ -980,12 +980,12 @@ def orbit_structure(self, P): orbit = [] index = 1 Q = P - while not Q in orbit: + while Q not in orbit: orbit.append(Q) Q = self(Q) index += 1 I = orbit.index(Q) - return([I, index-I-1]) + return([I, index - I - 1]) def cyclegraph(self): r""" diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index ff2ea05b21c..85536d138fd 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -203,7 +203,8 @@ def automorphism_group_QQ_fixedpoints(rational_function, return_functions=False, psi = phi(phi(z)) f2 = psi.numerator() g2 = psi.denominator() - period2_points = [x for x in (f2 - z*g2).roots(multiplicities=False) if not x in rational_roots] + period2_points = [x for x in (f2 - z*g2).roots(multiplicities=False) + if x not in rational_roots] for S in Subsets(period2_points, 2): zeta = -1 alpha = S[0] @@ -760,8 +761,10 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun return elements else: N = gcd(orderaut + [12]) #all orders of elements divide N - for order in [O for O in divisors(N) \ - if not O in badorders]: #range over all orders + for order in divisors(N): + if order in badorders: + continue + #range over all orders # that are possible over QQ such that we haven't already # found all elements of that order @@ -808,13 +811,12 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun badorders.append(m) #no elements of that order or any order that # is a multiple of it - if len([order for order in divisors(N) \ - if not order in badorders]) == 0: + if all(order in badorders for order in divisors(N)): #found all elements of every possible order if iso_type: - return(elements, which_group(elements)) + return (elements, which_group(elements)) return elements - congruence = congruence*p + congruence = congruence * p p = primes.next(p) @@ -1918,7 +1920,7 @@ def conjugating_set_initializer(f, g): # does find a subset, then the subset will most likely minimize the combinatorics # of checking conjugations tup = greedy_independence_check(P, repeated_mult_L, point_to_mult_L) - if not tup is None: + if tup is not None: more = False source, corresponding = tup @@ -1974,7 +1976,7 @@ def conjugating_set_initializer(f, g): # we again do a greedy check for a subset of n+2 points, of which no n+1 # are linearly dependent tup = greedy_independence_check(P, repeated_mult_L, point_to_mult_L) - if not tup is None: + if tup is not None: more = False source, corresponding = tup if not more: diff --git a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py index 0ad4d747f94..d5c26ac2cf3 100644 --- a/src/sage/dynamics/arithmetic_dynamics/generic_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/generic_ds.py @@ -160,7 +160,7 @@ def __classcall_private__(cls, morphism_or_polys, domain=None, names=None): """ if isinstance(morphism_or_polys, SchemeMorphism_polynomial): domain = morphism_or_polys.domain() - if not domain is None: + if domain is not None: if is_AffineSpace(domain) or isinstance(domain, AlgebraicScheme_subscheme_affine): from sage.dynamics.arithmetic_dynamics.affine_ds import DynamicalSystem_affine return DynamicalSystem_affine(morphism_or_polys, domain) @@ -640,7 +640,7 @@ def field_of_definition_preimage(self, point, n, return_embedding=False, simplif N = K if N.absolute_degree() == 1: if return_embedding: - return (QQ,ds.base_ring().embeddings(QQ)[0]) + return (QQ, ds.base_ring().embeddings(QQ)[0]) else: return QQ else: diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index d4cb66af782..6f4ed4ed35e 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -1747,7 +1747,7 @@ def green_function(self, P, v, **kwds): BR = FractionField(P.codomain().base_ring()) GBR = self.change_ring(BR) #so the heights work - if not BR in NumberFields(): + if BR not in NumberFields(): raise NotImplementedError("must be over a number field or a number field order") if not BR.is_absolute(): raise TypeError("must be an absolute field") @@ -1962,8 +1962,8 @@ def canonical_height(self, P, **kwds): error_bound = kwds.get("error_bound", None) K = FractionField(self.codomain().base_ring()) - if not K in NumberFields(): - if not K is QQbar: + if K not in NumberFields(): + if K is not QQbar: raise NotImplementedError("must be over a number field or a number field order or QQbar") else: #since this an absolute height, we can compute the height of a QQbar point @@ -2014,7 +2014,7 @@ def canonical_height(self, P, **kwds): err = kwds.get('error_bound', None) #computes the error bound as defined in Algorithm 3.1 of [WELLS] if Res > 1: - if not err is None: + if err is not None: err = err / 2 N = ceil((R(Res).log().log() - R(d-1).log() - R(err).log())/(R(d).log())) if N < 1: @@ -2055,7 +2055,7 @@ def canonical_height(self, P, **kwds): emb = K.places(prec=prec) num_places = len(emb) + len(bad_primes) - if not error_bound is None: + if error_bound is not None: error_bound /= num_places R = RealField(prec) h = R.zero() @@ -2138,7 +2138,7 @@ def height_difference_bound(self, prec=None): 3.43967790223022 """ FF = FractionField(self.domain().base_ring()) #lift will only work over fields, so coercing into FF - if not FF in NumberFields(): + if FF not in NumberFields(): if FF == QQbar: #since this is absolute height, we can choose any number field over which the #function is defined. @@ -3950,7 +3950,7 @@ def critical_height(self, **kwds): crit_points = F.critical_points() n = len(crit_points) err_bound = kwds.get("error_bound", None) - if not err_bound is None: + if err_bound is not None: kwds["error_bound"] = err_bound / n ch = 0 for P in crit_points: @@ -5181,7 +5181,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', """ n = ZZ(n) - if not embedding is None: + if embedding is not None: raise ValueError('do not specify an embedding') if n < 1: raise ValueError("period must be a positive integer") @@ -5190,7 +5190,7 @@ def sigma_invariants(self, n, formal=False, embedding=None, type='point', raise NotImplementedError("not implemented for subschemes") if self.degree() <= 1: raise TypeError("must have degree at least 2") - if not type in ['point', 'cycle']: + if type not in ['point', 'cycle']: raise ValueError("type must be either point or cycle") if dom.dimension_relative() > 1 or return_polynomial: if type == 'cycle': @@ -6282,10 +6282,10 @@ def all_periodic_points(self, **kwds): ValueError: algorithm must be 'dynatomic' or 'lifting' """ ring = kwds.pop("R", None) - if not ring is None: - #changes to the new ring + if ring is not None: + # changes to the new ring DS = self.change_ring(ring) - #ensures that the correct method is run, in case user switches to a finite field + # ensures that the correct method is run, in case user switches to a finite field return DS.all_periodic_points(**kwds) else: DS = self @@ -6329,7 +6329,7 @@ def all_periodic_points(self, **kwds): pt.insert(k,1) Q = PS(pt) #for each periodic point get the entire cycle - if not Q in periodic_points: + if Q not in periodic_points: #check periodic not preperiodic and add all points in cycle orb = set([Q]) Q2 = DS(Q) @@ -6347,7 +6347,7 @@ def all_periodic_points(self, **kwds): periods = kwds.pop("periods", None) badprimes = kwds.pop("bad_primes", None) num_cpus = kwds.pop("ncpus", ncpus()) - if not alg is None and alg not in ['dynatomic','lifting']: + if alg is not None and alg not in ['dynatomic', 'lifting']: raise ValueError("algorithm must be 'dynatomic' or 'lifting'") if not isinstance(primebound, (list, tuple)): @@ -6585,7 +6585,7 @@ def all_preperiodic_points(self, **kwds): (1/12*w + 1 : 1)] """ ring = kwds.pop("R",None) - if not ring is None: + if ring is not None: DS = self.change_ring(ring) else: DS = self @@ -6628,7 +6628,7 @@ def all_preperiodic_points(self, **kwds): pt.insert(k,1) Q = PS(pt) #for each preperiodic point get the entire connected component - if not Q in preper: + if Q not in preper: for t in DS.connected_rational_component(Q): preper.add(t) preper = list(preper) @@ -7351,7 +7351,7 @@ def is_polynomial(self): if self.codomain().dimension_relative() != 1: raise NotImplementedError("space must have dimension equal to 1") K = self.base_ring() - if not K in FiniteFields() and (not K in NumberFields() or not K.is_absolute()): + if K not in FiniteFields() and (K not in NumberFields() or not K.is_absolute()): raise NotImplementedError("must be over an absolute number field or finite field") if K in FiniteFields(): q = K.characteristic() @@ -7490,7 +7490,7 @@ def normal_form(self, return_conjugation=False): if self.codomain().dimension_relative() != 1: raise NotImplementedError("space must have dimension equal to 1") K = self.base_ring() - if not K in FiniteFields() and (not K in NumberFields() or not K.is_absolute()): + if K not in FiniteFields() and (K not in NumberFields() or not K.is_absolute()): raise NotImplementedError("must be over an absolute number field or finite field") if K in FiniteFields(): q = K.characteristic() @@ -8079,7 +8079,7 @@ def orbit_structure(self, P): Q.normalize_coordinates() F = copy(self) F.normalize_coordinates() - while not Q in orbit: + while Q not in orbit: orbit.append(Q) Q = F(Q) Q.normalize_coordinates() diff --git a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py index c8ad02059fe..7e4ae461348 100644 --- a/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py +++ b/src/sage/dynamics/arithmetic_dynamics/wehlerK3.py @@ -17,14 +17,13 @@ REFERENCES: [FH2015]_, [CS1996]_, [Weh1998]_, [Hutz2007] """ - -#***************************************************************************** +# **************************************************************************** # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # https://www.gnu.org/licenses/ -#***************************************************************************** +# **************************************************************************** from sage.calculus.functions import jacobian from sage.categories.fields import Fields @@ -83,7 +82,8 @@ def WehlerK3Surface(polys): elif isinstance(R, CommutativeRing): return WehlerK3Surface_ring(polys) else: - raise TypeError("R (= %s) must be a commutative ring"%R) + raise TypeError("R (= %s) must be a commutative ring" % R) + def random_WehlerK3Surface(PP): r""" @@ -267,10 +267,10 @@ def _Lcoeff(self, component, i): sage: X._Lcoeff(1, 0) x0 """ - #Error Checks for Passed in Values - if not component in [0,1]: + # Error Checks for Passed in Values + if component not in [0, 1]: raise ValueError("component can only be 1 or 0") - if not i in [0,1,2]: + if i not in [0, 1, 2]: raise ValueError("index must be 0, 1, or 2") R = self.ambient_space().coordinate_ring() return self.L.coefficient(R.gen(component*3 + i)) @@ -317,11 +317,11 @@ def _Qcoeff(self, component, i, j): sage: X._Qcoeff(1, 1, 0) x0^2 """ - #Check Errors in Passed in Values - if not component in [0,1]: + # Check Errors in Passed in Values + if component not in [0, 1]: raise ValueError("component can only be 1 or 0") - if not (i in [0,1,2]) and not (j in [0,1,2]): + if i not in [0, 1, 2] or j not in [0, 1, 2]: raise ValueError("the two indexes must be either 0, 1, or 2") R = self.ambient_space().coordinate_ring() @@ -355,11 +355,11 @@ def Gpoly(self, component, k): sage: X.Gpoly(1, 0) x0^2*x1^2 + x1^4 - x0*x1^2*x2 + x1^3*x2 + x1^2*x2^2 + x2^4 """ - #Check Errors in passed in values - if not component in [0, 1]: + # Check Errors in passed in values + if component not in [0, 1]: raise ValueError("component can only be 1 or 0") - if not k in [0,1,2]: + if k not in [0, 1, 2]: raise ValueError("index must be either 0, 1, or 2") Indices = [0, 1, 2] @@ -447,7 +447,7 @@ def Lxa(self, a): sage: X.Lxa(T[0]) y0 + y1 """ - if not a in self.ambient_space()[0]: + if a not in self.ambient_space()[0]: raise TypeError("point must be in projective space of dimension 2") AS = self.ambient_space() ASC = AS.coordinate_ring() @@ -484,7 +484,7 @@ def Qxa(self, a): sage: X.Qxa(T[0]) 5*y0^2 + 7*y0*y1 + y1^2 + 11*y1*y2 + y2^2 """ - if not a in self.ambient_space()[0]: + if a not in self.ambient_space()[0]: raise TypeError("point must be in Projective Space of dimension 2") AS = self.ambient_space() ASC = AS.coordinate_ring() @@ -525,7 +525,7 @@ def Sxa(self, a): y0 + y1, 5*y0^2 + 7*y0*y1 + y1^2 + 11*y1*y2 + y2^2 """ - if not a in self.ambient_space()[0]: + if a not in self.ambient_space()[0]: raise TypeError("point must be in projective space of dimension 2") PSY = self.ambient_space()[1] return PSY.subscheme([self.Lxa(a),self.Qxa(a)]) @@ -559,7 +559,7 @@ def Lyb(self, b): sage: X.Lyb(T[1]) x0 """ - if not b in self.ambient_space()[1]: + if b not in self.ambient_space()[1]: raise TypeError("point must be in projective space of dimension 2") AS = self.ambient_space() ASC = AS.coordinate_ring() @@ -596,7 +596,7 @@ def Qyb(self, b): sage: X.Qyb(T[1]) x0^2 + 3*x0*x1 + x1^2 """ - if not b in self.ambient_space()[1]: + if b not in self.ambient_space()[1]: raise TypeError("point must be in projective space of dimension 2") AS = self.ambient_space() ASC = AS.coordinate_ring() @@ -635,7 +635,7 @@ def Syb(self, b): x0^2 + 3*x0*x1 + x1^2 """ - if not b in self.ambient_space()[1]: + if b not in self.ambient_space()[1]: raise TypeError("point must be in projective space of dimension 2") AS = self.ambient_space() PSY = AS[0] @@ -2130,7 +2130,7 @@ def fiber(self, p, component): for x in Points: if (self.L(x) == 0) and (self.Q(x) == 0): Y = self.point(x, False) - if not Y in fiber: + if Y not in fiber: fiber.append(Y) return fiber From 1ce109335091c4c96d1160a6c3512ef8ea36a507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 3 Nov 2021 21:37:41 +0100 Subject: [PATCH 294/378] fix E713 and E714 in interfaces --- src/sage/interfaces/axiom.py | 7 +++---- src/sage/interfaces/expect.py | 6 +++--- src/sage/interfaces/interface.py | 14 +++++++------- src/sage/interfaces/mathics.py | 8 ++++---- src/sage/interfaces/maxima.py | 8 ++++---- src/sage/interfaces/maxima_lib.py | 14 +++++++------- src/sage/interfaces/octave.py | 8 ++++---- src/sage/interfaces/qepcad.py | 3 +-- src/sage/interfaces/sympy.py | 8 +------- 9 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/sage/interfaces/axiom.py b/src/sage/interfaces/axiom.py index d46b67bbb32..8819fd857fe 100644 --- a/src/sage/interfaces/axiom.py +++ b/src/sage/interfaces/axiom.py @@ -702,16 +702,15 @@ def _latex_(self): sage: a = axiom(1/2) #optional - axiom sage: latex(a) #optional - axiom \frac{1}{2} - """ self._check_valid() P = self.parent() - s = P._eval_line('outputAsTex(%s)'%self.name(), reformat=False) - if not '$$' in s: + s = P._eval_line('outputAsTex(%s)' % self.name(), reformat=False) + if '$$' not in s: raise RuntimeError("Error texing axiom object.") i = s.find('$$') j = s.rfind('$$') - s = s[i+2:j] + s = s[i + 2:j] s = multiple_replace({'\r':'', '\n':' ', ' \\sp ':'^', '\\arcsin ':'\\sin^{-1} ', diff --git a/src/sage/interfaces/expect.py b/src/sage/interfaces/expect.py index e619644f0e9..d31668974a1 100644 --- a/src/sage/interfaces/expect.py +++ b/src/sage/interfaces/expect.py @@ -1308,12 +1308,12 @@ def _synchronize(self, cmd='1+%s;\n'): if self._expect is None: return rnd = randrange(2147483647) - s = str(rnd+1) - cmd = cmd%rnd + s = str(rnd + 1) + cmd = cmd % rnd self._sendstr(cmd) try: self._expect_expr(timeout=0.5) - if not s in self._before(): + if s not in self._before(): self._expect_expr(s, timeout=0.5) self._expect_expr(timeout=0.5) except pexpect.TIMEOUT: diff --git a/src/sage/interfaces/interface.py b/src/sage/interfaces/interface.py index 7ace8e6ba03..19c6c7c8aa4 100644 --- a/src/sage/interfaces/interface.py +++ b/src/sage/interfaces/interface.py @@ -734,20 +734,20 @@ def __init__(self, parent, value, is_name=False, name=None): raise TypeError(x) def _latex_(self): -# return "\\begin{verbatim}%s\\end{verbatim}"%self + # return "\\begin{verbatim}%s\\end{verbatim}"%self string = str(self) - if not '|' in string: + if '|' not in string: delim = '|' - elif not '#' in string: + elif '#' not in string: delim = '#' - elif not '@' in string: + elif '@' not in string: delim = '@' - elif not '~' in string: + elif '~' not in string: delim = '~' - return "\\verb%s%s%s"%(delim, string, delim) + return "\\verb%s%s%s" % (delim, string, delim) def __iter__(self): - for i in range(1, len(self)+1): + for i in range(1, len(self) + 1): yield self[i] def __len__(self): diff --git a/src/sage/interfaces/mathics.py b/src/sage/interfaces/mathics.py index 2a81b23fed4..9a938ca759f 100644 --- a/src/sage/interfaces/mathics.py +++ b/src/sage/interfaces/mathics.py @@ -1062,15 +1062,15 @@ def _sage_(self, locals={}): self._check_valid() if self.is_inexact(): m = self.to_mpmath() - if not self is m and not m is None: + if self is not m and m is not None: from sage.libs.mpmath.utils import mpmath_to_sage return mpmath_to_sage(m, self.get_precision()) s = self.to_sympy() - if not self is s and not s is None: + if self is not s and s is not None: if hasattr(s, '_sage_'): return s._sage_() p = self.to_python() - if not self is p and not p is None: + if self is not p and p is not None: def conv(i): return self.parent()(i).sage() if type(p) is list: @@ -1078,7 +1078,7 @@ def conv(i): elif type(p) is tuple: return tuple([conv(i) for i in p]) elif type(p) is dict: - return {conv(k):conv(v) for k, v in p.items()} + return {conv(k): conv(v) for k, v in p.items()} else: return p return s diff --git a/src/sage/interfaces/maxima.py b/src/sage/interfaces/maxima.py index fc7f48bc052..8144d525825 100644 --- a/src/sage/interfaces/maxima.py +++ b/src/sage/interfaces/maxima.py @@ -847,13 +847,13 @@ def _synchronize(self): # The 0; *is* necessary... it comes up in certain rare cases # that are revealed by extensive testing. # Don't delete it. -- william stein - cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r) + cmd = '''0;sconcat("%s",(%s+1));\n''' % (marker, r) self._sendstr(cmd) try: try: self._expect_expr(timeout=0.5) - if not s in self._before(): - self._expect_expr(s,timeout=0.5) + if s not in self._before(): + self._expect_expr(s, timeout=0.5) self._expect_expr(timeout=0.5) except pexpect.TIMEOUT: # Don't call self._interrupt() here, as that might send multiple @@ -944,7 +944,7 @@ def _error_check(self, cmd, out): """ r = self._error_re m = r.search(out) - if not m is None: + if m is not None: self._error_msg(cmd, out) def _error_msg(self, cmd, out): diff --git a/src/sage/interfaces/maxima_lib.py b/src/sage/interfaces/maxima_lib.py index 12005b269e8..e0e07c52c78 100644 --- a/src/sage/interfaces/maxima_lib.py +++ b/src/sage/interfaces/maxima_lib.py @@ -1607,18 +1607,18 @@ def sr_to_max(expr): # This should be safe if we treated all special operators above #furthermore, this should already use any _maxima_ methods on op, so use any #conversion methods that are registered in pynac. - op_max=maxima(op).ecl() + op_max = maxima(op).ecl() if op_max in max_op_dict: raise RuntimeError("Encountered operator mismatch in sr-to-maxima translation") - sage_op_dict[op]=op_max - max_op_dict[op_max]=op + sage_op_dict[op] = op_max + max_op_dict[op_max] = op return EclObject(([sage_op_dict[op]], [sr_to_max(o) for o in expr.operands()])) elif expr.is_symbol() or expr._is_registered_constant_(): - if not expr in sage_sym_dict: - sym_max=maxima(expr).ecl() - sage_sym_dict[expr]=sym_max - max_sym_dict[sym_max]=expr + if expr not in sage_sym_dict: + sym_max = maxima(expr).ecl() + sage_sym_dict[expr] = sym_max + max_sym_dict[sym_max] = expr return sage_sym_dict[expr] else: try: diff --git a/src/sage/interfaces/octave.py b/src/sage/interfaces/octave.py index 845fa0fd264..60daa33dbda 100644 --- a/src/sage/interfaces/octave.py +++ b/src/sage/interfaces/octave.py @@ -322,10 +322,10 @@ def _keyboard_interrupt(self): except pexpect.ExceptionPexpect as msg: raise RuntimeError( "THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg) self._start() - raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)"%self) + raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)" % self) else: - self._expect.send('\003') # control-c - raise KeyboardInterrupt("Ctrl-c pressed while running %s"%self) + self._expect.send('\003') # control-c + raise KeyboardInterrupt("Ctrl-c pressed while running %s" % self) def quit(self, verbose=False): """ @@ -339,7 +339,7 @@ def quit(self, verbose=False): # Don't bother, since it just hangs in some cases, and it # isn't necessary, since octave behaves well with respect # to signals. - if not self._expect is None: + if self._expect is not None: if verbose: print("Exiting spawned %s process." % self) return diff --git a/src/sage/interfaces/qepcad.py b/src/sage/interfaces/qepcad.py index 9fa2451ddd6..38d9c8c646a 100644 --- a/src/sage/interfaces/qepcad.py +++ b/src/sage/interfaces/qepcad.py @@ -1223,7 +1223,6 @@ def make_cells(self, text): return cells - def __getattr__(self, attrname): r""" Return a :class:`QepcadFunction` object for any QEPCAD command. @@ -1236,7 +1235,7 @@ def __getattr__(self, attrname): """ if attrname[:1] == "_": raise AttributeError - if not attrname in self._tab_completion(): + if attrname not in self._tab_completion(): raise AttributeError return QepcadFunction(self, attrname) diff --git a/src/sage/interfaces/sympy.py b/src/sage/interfaces/sympy.py index a16e3ab6aec..8fb6caf0188 100644 --- a/src/sage/interfaces/sympy.py +++ b/src/sage/interfaces/sympy.py @@ -1055,33 +1055,27 @@ def test_basics(): check_expression("x**2+y**3", "x y") check_expression("1/(x+y)**2-x**3/4", "x y") - def test_complex(): check_expression("I", "") check_expression("23+I*4", "x") - def test_complex_fail(): # Sage doesn't properly implement _sympy_ on I check_expression("I*y", "y") check_expression("x+I*y", "x y") - def test_integer(): check_expression("4*x", "x") check_expression("-4*x", "x") - def test_real(): check_expression("1.123*x", "x") check_expression("-18.22*x", "x") - - def test_functions(): # Test at least one Function without own _sage_ method from sympy import factorial - assert not "_sage_" in factorial.__dict__ + assert "_sage_" not in factorial.__dict__ check_expression("factorial(x)", "x") check_expression("sin(x)", "x") check_expression("cos(x)", "x") From 6473c4dea788afa23d886670536f0801cfc53b2a Mon Sep 17 00:00:00 2001 From: Markus Wageringel Date: Wed, 3 Nov 2021 21:54:35 +0100 Subject: [PATCH 295/378] 32824: raise error in non-commutative case --- src/sage/rings/morphism.pyx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sage/rings/morphism.pyx b/src/sage/rings/morphism.pyx index 8cf7181feed..b18409ca88e 100644 --- a/src/sage/rings/morphism.pyx +++ b/src/sage/rings/morphism.pyx @@ -1255,11 +1255,21 @@ cdef class RingHomomorphism(RingMap): Traceback (most recent call last): ... NotImplementedError: base map must be trivial + + Non-commutative rings are not supported (:trac:`32824`):: + + sage: A = GradedCommutativeAlgebra(QQ, 'x,y,z') + sage: A.hom(A.gens(), A).kernel() + Traceback (most recent call last): + ... + NotImplementedError: rings are not commutative """ from .quotient_ring import is_QuotientRing from .ideal import Ideal_generic A = self.domain() B = self.codomain() + if not (A.is_commutative() and B.is_commutative()): + raise NotImplementedError("rings are not commutative") if A.base_ring() != B.base_ring(): raise NotImplementedError("base rings must be equal") try: From 9592ab36cddf75821d8ce82660445d83df24aad2 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Thu, 4 Nov 2021 14:14:54 +0800 Subject: [PATCH 296/378] fix doctest (from patchbot run) --- src/sage/doctest/forker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/doctest/forker.py b/src/sage/doctest/forker.py index 3307d50939e..6690c627e75 100644 --- a/src/sage/doctest/forker.py +++ b/src/sage/doctest/forker.py @@ -1475,7 +1475,7 @@ def report_unexpected_exception(self, out, test, example, exc_info): sage: old_prompt = sage0._prompt sage: sage0._prompt = r"\(Pdb\) " sage: sage0.eval("DTR.run(DT, clear_globs=False)") # indirect doctest - '... ArithmeticError("invariants " + str(ainvs) + " define a singular curve")' + '... ArithmeticError(self._equation_string() + " defines a singular curve")' sage: sage0.eval("l") '...if self.discriminant() == 0:...raise ArithmeticError...' sage: sage0.eval("u") From 5d9414ddc4ec72d6b32ac88e9aa94a0fe2433dab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 11:28:44 +0100 Subject: [PATCH 297/378] 32650: .. note -> .. NOTE --- src/sage/plot/animate.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/plot/animate.py b/src/sage/plot/animate.py index 96388659111..e3557569e78 100644 --- a/src/sage/plot/animate.py +++ b/src/sage/plot/animate.py @@ -565,7 +565,7 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False, sage: a.gif(savefile=td + 'my_animation_2.gif', show_path=True, use_ffmpeg=True) # optional -- ffmpeg Animation saved to .../my_animation_2.gif. - .. note:: + .. NOTE:: If neither ffmpeg nor ImageMagick is installed, you will get an error message like this:: @@ -634,7 +634,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False, sage: td = tmp_dir() sage: a._gif_from_imagemagick(savefile=td + 'new.gif') # optional -- imagemagick - .. note:: + .. NOTE:: If imagemagick is not installed, you will get an error message like this:: @@ -760,7 +760,7 @@ def show(self, delay=None, iterations=None, **kwds): This method does not return anything. Use :meth:`save` if you want to save the figure as an image. - .. note:: + .. NOTE:: Currently this is done using an animated gif, though this could change in the future. This requires that either @@ -806,7 +806,7 @@ def show(self, delay=None, iterations=None, **kwds): sage: a.show(50, 3) # optional -- ImageMagick - .. note:: + .. NOTE:: If you don't have ffmpeg or ImageMagick installed, you will get an error message like this:: @@ -892,7 +892,7 @@ def ffmpeg(self, savefile=None, show_path=False, output_format=None, sage: a.ffmpeg(savefile=td + 'new.mpg', show_path=True) # optional -- ffmpeg Animation saved to .../new.mpg. - .. note:: + .. NOTE:: If ffmpeg is not installed, you will get an error message like this:: From a0c3b9d19282a5467d6d73ed61644f5a6be6cbba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Thu, 4 Nov 2021 11:50:33 +0100 Subject: [PATCH 298/378] =?UTF-8?q?cosm=C3=A9tique=20de=20l'espace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../arithmetic_dynamics/endPN_automorphism_group.py | 6 +++--- src/sage/dynamics/arithmetic_dynamics/projective_ds.py | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py index 85536d138fd..a2cf0fc198e 100644 --- a/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py +++ b/src/sage/dynamics/arithmetic_dynamics/endPN_automorphism_group.py @@ -760,11 +760,11 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun return(elements, which_group(elements)) return elements else: - N = gcd(orderaut + [12]) #all orders of elements divide N + N = gcd(orderaut + [12]) # all orders of elements divide N for order in divisors(N): if order in badorders: continue - #range over all orders + # range over all orders # that are possible over QQ such that we haven't already # found all elements of that order @@ -775,7 +775,7 @@ def automorphism_group_QQ_CRT(rational_function, prime_lower_bound=4, return_fun numelts = min(numeltsoffixedorder) # Have some elts of fixed order mod p for each p if numelts != 0: - #CRT order d elements together and check if + # CRT order d elements together and check if # they are an automorphism autos, M = CRT_automorphisms(automorphisms, orderelts, order, primepowers) diff --git a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py index 6f4ed4ed35e..2f3eeb90ab4 100644 --- a/src/sage/dynamics/arithmetic_dynamics/projective_ds.py +++ b/src/sage/dynamics/arithmetic_dynamics/projective_ds.py @@ -1332,7 +1332,7 @@ def orbit(self, P, N, **kwds): return [] R = self.domain()(P) - if R in self.domain(): #Check whether R is a zero-dimensional point + if R in self.domain(): # Check whether R is a zero-dimensional point Q = R else: Q = P @@ -1776,7 +1776,7 @@ def green_function(self, P, v, **kwds): #if doing error estimates, compute needed number of iterates D = (dim + 1) * (d - 1) + 1 - #compute upper bound + # compute upper bound if isinstance(v, RingHomomorphism_im_gens): #archimedean vindex = BR.places(prec=prec).index(v) U = GBR.local_height_arch(vindex, prec=prec) + R(binomial(dim + d, d)).log() @@ -2012,7 +2012,7 @@ def canonical_height(self, P, **kwds): R = RealField(prec) N = kwds.get('N', 10) err = kwds.get('error_bound', None) - #computes the error bound as defined in Algorithm 3.1 of [WELLS] + # computes the error bound as defined in Algorithm 3.1 of [WELLS] if Res > 1: if err is not None: err = err / 2 @@ -6328,7 +6328,7 @@ def all_periodic_points(self, **kwds): pt = [sum([P[i]*w**i for i in range(d)])] pt.insert(k,1) Q = PS(pt) - #for each periodic point get the entire cycle + # for each periodic point get the entire cycle if Q not in periodic_points: #check periodic not preperiodic and add all points in cycle orb = set([Q]) @@ -6627,7 +6627,7 @@ def all_preperiodic_points(self, **kwds): pt = [sum([P[i]*w**i for i in range(d)])] pt.insert(k,1) Q = PS(pt) - #for each preperiodic point get the entire connected component + # for each preperiodic point get the entire connected component if Q not in preper: for t in DS.connected_rational_component(Q): preper.add(t) From 345c760b9e2e31829b995ddbb7b58bb7ce531624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 22:03:25 +0100 Subject: [PATCH 299/378] 32650: using features in has_latex method of doctest/external.py --- src/sage/doctest/external.py | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 11270d32128..e74b3554e50 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -49,7 +49,7 @@ def has_internet(): EXAMPLES:: sage: from sage.doctest.external import has_internet - sage: has_internet() # random, optional -- internet + sage: has_internet() # random, optional -- internet FeatureTestResult('internet', True) """ from sage.features.internet import Internet @@ -62,20 +62,11 @@ def has_latex(): EXAMPLES:: sage: from sage.doctest.external import has_latex - sage: has_latex() # random, optional - latex - True + sage: has_latex() # optional - latex + FeatureTestResult('latex', True) """ - from sage.misc.latex import _run_latex_, _latex_file_ - from sage.misc.temporary_file import tmp_filename - try: - f = tmp_filename(ext='.tex') - O = open(f, 'w') - O.write(_latex_file_('2+3')) - O.close() - _run_latex_(f) - return True - except Exception: - return False + from sage.features.latex import latex + return latex().is_present() def has_xelatex(): """ @@ -84,7 +75,7 @@ def has_xelatex(): EXAMPLES:: sage: from sage.doctest.external import has_xelatex - sage: has_xelatex() # optional -- xelatex + sage: has_xelatex() # optional - xelatex FeatureTestResult('xelatex', True) """ from sage.features.latex import xelatex @@ -97,7 +88,7 @@ def has_pdflatex(): EXAMPLES:: sage: from sage.doctest.external import has_pdflatex - sage: has_pdflatex() # optional -- pdflatex + sage: has_pdflatex() # optional - pdflatex FeatureTestResult('pdflatex', True) """ from sage.features.latex import pdflatex @@ -110,7 +101,7 @@ def has_lualatex(): EXAMPLES:: sage: from sage.doctest.external import has_lualatex - sage: has_lualatex() # optional -- lualatex + sage: has_lualatex() # optional - lualatex FeatureTestResult('lualatex', True) """ from sage.features.latex import lualatex From 6c6b3325a0927ae00b773b34c63cd7db9c7589f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 22:24:18 +0100 Subject: [PATCH 300/378] 32650: independent and improved method latex().is_functional() --- src/sage/features/latex.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/sage/features/latex.py b/src/sage/features/latex.py index 8352e031ca9..a0f0d6f4096 100644 --- a/src/sage/features/latex.py +++ b/src/sage/features/latex.py @@ -45,17 +45,34 @@ def is_functional(self): sage: latex().is_functional() # optional: latex FeatureTestResult('latex', True) """ - from sage.misc.latex import _run_latex_, _latex_file_ + lines = [] + lines.append(r"\documentclass{article}") + lines.append(r"\begin{document}") + lines.append(r"$\alpha+2$") + lines.append(r"\end{document}") + content = '\n'.join(lines) + + # create a simple tex file with the content from sage.misc.temporary_file import tmp_filename - try: - f = tmp_filename(ext='.tex') - O = open(f, 'w') - O.write(_latex_file_('2+3')) - O.close() - _run_latex_(f) + base_filename_tex = tmp_filename(ext='.tex') + with open(base_filename_tex, 'w') as f: + f.write(content) + import os + base, filename_tex = os.path.split(base_filename_tex) + + # running latex + from subprocess import run + cmd = ['latex', '-interaction=nonstopmode', filename_tex] + cmd = ' '.join(cmd) + result = run(cmd, shell=True, cwd=base, capture_output=True, text=True) + + # return + if result.returncode == 0: return FeatureTestResult(self, True) - except Exception: - return FeatureTestResult(self, False, reason="Running latex on a sample file raised an exception") + else: + return FeatureTestResult(self, False, reason="Running latex on " + "a sample file returned non-zero " + "exit status {}".format(result.returncode)) class pdflatex(Executable): r""" From 63555d2ee5280e83f14cd207a5d20d4fff3abc5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 22:39:40 +0100 Subject: [PATCH 301/378] 32650: adding spkg pdf2svg in build/pkgs --- build/pkgs/pdf2svg/SPKG.rst | 19 +++++++++++++++++++ build/pkgs/pdf2svg/distros/alpine.txt | 1 + build/pkgs/pdf2svg/distros/arch.txt | 1 + build/pkgs/pdf2svg/distros/conda.txt | 1 + build/pkgs/pdf2svg/distros/cygwin.txt | 1 + build/pkgs/pdf2svg/distros/debian.txt | 1 + build/pkgs/pdf2svg/distros/fedora.txt | 1 + build/pkgs/pdf2svg/distros/freebsd.txt | 1 + build/pkgs/pdf2svg/distros/homebrew.txt | 1 + build/pkgs/pdf2svg/distros/macports.txt | 1 + build/pkgs/pdf2svg/distros/nix.txt | 1 + build/pkgs/pdf2svg/distros/opensuse.txt | 1 + build/pkgs/pdf2svg/distros/repology.txt | 1 + build/pkgs/pdf2svg/distros/void.txt | 1 + build/pkgs/pdf2svg/spkg-configure.m4 | 5 +++++ build/pkgs/pdf2svg/type | 1 + 16 files changed, 38 insertions(+) create mode 100644 build/pkgs/pdf2svg/SPKG.rst create mode 100644 build/pkgs/pdf2svg/distros/alpine.txt create mode 100644 build/pkgs/pdf2svg/distros/arch.txt create mode 100644 build/pkgs/pdf2svg/distros/conda.txt create mode 100644 build/pkgs/pdf2svg/distros/cygwin.txt create mode 100644 build/pkgs/pdf2svg/distros/debian.txt create mode 100644 build/pkgs/pdf2svg/distros/fedora.txt create mode 100644 build/pkgs/pdf2svg/distros/freebsd.txt create mode 100644 build/pkgs/pdf2svg/distros/homebrew.txt create mode 100644 build/pkgs/pdf2svg/distros/macports.txt create mode 100644 build/pkgs/pdf2svg/distros/nix.txt create mode 100644 build/pkgs/pdf2svg/distros/opensuse.txt create mode 100644 build/pkgs/pdf2svg/distros/repology.txt create mode 100644 build/pkgs/pdf2svg/distros/void.txt create mode 100644 build/pkgs/pdf2svg/spkg-configure.m4 create mode 100644 build/pkgs/pdf2svg/type diff --git a/build/pkgs/pdf2svg/SPKG.rst b/build/pkgs/pdf2svg/SPKG.rst new file mode 100644 index 00000000000..2a87b276be0 --- /dev/null +++ b/build/pkgs/pdf2svg/SPKG.rst @@ -0,0 +1,19 @@ +pdf2svg - PDF to SVG convertor +============================== + +Description +----------- + +pdf2svg is a tiny command-line utility using Cairo and Poppler to convert PDF +documents into SVG files. Multi-page PDF can be split up to one SVG per page by +passing a file naming specification. + +License +------- + +GPL + +Upstream Contact +---------------- + +http://cityinthesky.co.uk/opensource/pdf2svg/ diff --git a/build/pkgs/pdf2svg/distros/alpine.txt b/build/pkgs/pdf2svg/distros/alpine.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/alpine.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/arch.txt b/build/pkgs/pdf2svg/distros/arch.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/arch.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/conda.txt b/build/pkgs/pdf2svg/distros/conda.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/conda.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/cygwin.txt b/build/pkgs/pdf2svg/distros/cygwin.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/cygwin.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/debian.txt b/build/pkgs/pdf2svg/distros/debian.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/debian.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/fedora.txt b/build/pkgs/pdf2svg/distros/fedora.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/fedora.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/freebsd.txt b/build/pkgs/pdf2svg/distros/freebsd.txt new file mode 100644 index 00000000000..225444481b8 --- /dev/null +++ b/build/pkgs/pdf2svg/distros/freebsd.txt @@ -0,0 +1 @@ +graphics/pdf2svg diff --git a/build/pkgs/pdf2svg/distros/homebrew.txt b/build/pkgs/pdf2svg/distros/homebrew.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/homebrew.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/macports.txt b/build/pkgs/pdf2svg/distros/macports.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/macports.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/nix.txt b/build/pkgs/pdf2svg/distros/nix.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/nix.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/opensuse.txt b/build/pkgs/pdf2svg/distros/opensuse.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/opensuse.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/repology.txt b/build/pkgs/pdf2svg/distros/repology.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/repology.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/distros/void.txt b/build/pkgs/pdf2svg/distros/void.txt new file mode 100644 index 00000000000..52c66a99cbf --- /dev/null +++ b/build/pkgs/pdf2svg/distros/void.txt @@ -0,0 +1 @@ +pdf2svg diff --git a/build/pkgs/pdf2svg/spkg-configure.m4 b/build/pkgs/pdf2svg/spkg-configure.m4 new file mode 100644 index 00000000000..88eedf2ec02 --- /dev/null +++ b/build/pkgs/pdf2svg/spkg-configure.m4 @@ -0,0 +1,5 @@ +SAGE_SPKG_CONFIGURE([pdf2svg], [ + AC_PATH_PROG([PDF2SVG], [pdf2svg]) + AS_IF([test -z "$ac_cv_path_PDF2SVG"], [sage_spkg_install_pdf2svg=yes]) +]) + diff --git a/build/pkgs/pdf2svg/type b/build/pkgs/pdf2svg/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/pdf2svg/type @@ -0,0 +1 @@ +optional From c8330fe39151df1bed83de2bfdb3376e419efc30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 22:41:46 +0100 Subject: [PATCH 302/378] 32650: linking pdf2svg feature to spkg pdf2svg --- src/sage/features/pdf2svg.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sage/features/pdf2svg.py b/src/sage/features/pdf2svg.py index 1176706f127..f0b634f5ff4 100644 --- a/src/sage/features/pdf2svg.py +++ b/src/sage/features/pdf2svg.py @@ -33,4 +33,5 @@ def __init__(self): True """ Executable.__init__(self, "pdf2svg", executable="pdf2svg", + spkg='pdf2svg', url="http://www.cityinthesky.co.uk/opensource/pdf2svg/") From 2ea4d9eaa99477cc248fd10bb049925d32806c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Labb=C3=A9?= Date: Thu, 4 Nov 2021 22:55:51 +0100 Subject: [PATCH 303/378] 32650: fixing two doctests now that we latex().require() it when we use it --- src/sage/misc/latex.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/latex.py b/src/sage/misc/latex.py index 2c41565519a..5d5ac4e6fb3 100644 --- a/src/sage/misc/latex.py +++ b/src/sage/misc/latex.py @@ -707,7 +707,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i sage: file = os.path.join(SAGE_TMP, "temp.tex") sage: with open(file, 'w') as O: ....: _ = O.write(_latex_file_([ZZ['x'], RR])) - sage: _run_latex_(file) # random - depends on whether latex is installed + sage: _run_latex_(file) # random, optional - latex 'dvi' """ if engine is None: @@ -1965,7 +1965,7 @@ def png(x, filename, density=150, debug=False, EXAMPLES:: sage: from sage.misc.latex import png - sage: png(ZZ[x], os.path.join(SAGE_TMP, "zz.png")) # random - error if no latex + sage: png(ZZ[x], os.path.join(SAGE_TMP, "zz.png")) # random, optional - latex """ if not pdflatex: engine = "latex" From ae5ec64919e91486c7be530f7d1ab767454e62ed Mon Sep 17 00:00:00 2001 From: LLewark Date: Fri, 5 Nov 2021 11:05:24 +0100 Subject: [PATCH 304/378] Added Cromwell's book 'Knots and links' as reference for the definition of the determinant for multi-component links. --- src/doc/en/reference/references/index.rst | 3 +++ src/sage/knots/link.py | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/doc/en/reference/references/index.rst b/src/doc/en/reference/references/index.rst index 8a7e133e0ae..981d1454c9f 100644 --- a/src/doc/en/reference/references/index.rst +++ b/src/doc/en/reference/references/index.rst @@ -1716,6 +1716,9 @@ REFERENCES: C. R. Acad. Sci. Paris Sér. I Math. 296 (1983) 14 781--784. +.. [Cro2004] Peter R. Cromwell, *Knots and links*, Cambridge University Press (2004). + :doi:`10.1017/CBO9780511809767` + .. [CRS2016] Dean Crnković, Sanja Rukavina, and Andrea Švob. *Strongly regular graphs from orthogonal groups* `O^+(6,2)` *and* `O^-(6,2)`. :arxiv:`1609.07133` diff --git a/src/sage/knots/link.py b/src/sage/knots/link.py index ec8ad1399c1..d8c114b54fe 100644 --- a/src/sage/knots/link.py +++ b/src/sage/knots/link.py @@ -1935,6 +1935,10 @@ def determinant(self): sage: B = BraidGroup(3) sage: Link(B([1, 2, 1, -2, -1])).determinant() 0 + + REFERENCES: + + - Definition 6.6.3 in [Cro2004]_ """ V = self.seifert_matrix() m = V + V.transpose() From d7085db4ea6679d185d34ad1a64054a6da91f844 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Thu, 4 Nov 2021 15:13:29 +0900 Subject: [PATCH 305/378] Move package docstrings out of __init__.py --- src/doc/en/reference/categories/index.rst | 8 ++ src/doc/en/reference/combinat/index.rst | 1 - src/doc/en/reference/combinat/module_list.rst | 15 +-- src/sage/categories/__init__.py | 29 ----- src/sage/categories/all.py | 29 +++++ src/sage/combinat/__init__.py | 49 ------- src/sage/combinat/algebraic_combinatorics.py | 16 +-- src/sage/combinat/all.py | 50 ++++++- src/sage/combinat/catalog_partitions.py | 1 - src/sage/combinat/chas/__init__.py | 12 -- src/sage/combinat/chas/all.py | 16 ++- .../cluster_algebra_quiver/__init__.py | 10 -- .../combinat/cluster_algebra_quiver/all.py | 15 ++- src/sage/combinat/crystals/__init__.py | 29 ----- src/sage/combinat/crystals/all.py | 28 +++- src/sage/combinat/designs/__init__.py | 37 ------ src/sage/combinat/designs/all.py | 42 +++++- src/sage/combinat/enumerated_sets.py | 3 +- src/sage/combinat/finite_state_machine.py | 2 +- src/sage/combinat/integer_lists/__init__.py | 1 - src/sage/combinat/matrices/__init__.py | 9 -- src/sage/combinat/matrices/all.py | 12 +- src/sage/combinat/ncsf_qsym/__init__.py | 10 -- src/sage/combinat/ncsf_qsym/all.py | 13 +- src/sage/combinat/ncsym/__init__.py | 10 -- src/sage/combinat/ncsym/all.py | 14 +- src/sage/combinat/path_tableaux/__init__.py | 10 -- src/sage/combinat/path_tableaux/all.py | 11 +- src/sage/combinat/posets/__init__.py | 35 ----- src/sage/combinat/posets/all.py | 36 +++++- src/sage/combinat/quickref.py | 1 - .../rigged_configurations/__init__.py | 36 ------ .../combinat/rigged_configurations/all.py | 37 +++++- src/sage/combinat/root_system/__init__.py | 118 ----------------- src/sage/combinat/root_system/all.py | 122 +++++++++++++++++- src/sage/combinat/sf/__init__.py | 30 ----- src/sage/combinat/sf/all.py | 32 ++++- src/sage/combinat/species/__init__.py | 50 ------- src/sage/combinat/species/all.py | 52 +++++++- src/sage/combinat/words/__init__.py | 41 ------ src/sage/combinat/words/all.py | 43 +++++- src/sage/misc/namespace_package.py | 20 +++ src/sage/misc/sagedoc.py | 5 - 43 files changed, 565 insertions(+), 575 deletions(-) create mode 100644 src/sage/misc/namespace_package.py diff --git a/src/doc/en/reference/categories/index.rst b/src/doc/en/reference/categories/index.rst index ab6cb1dbbab..534a0fdee43 100644 --- a/src/doc/en/reference/categories/index.rst +++ b/src/doc/en/reference/categories/index.rst @@ -1,6 +1,14 @@ Category Framework ================== +Introduction +------------ + +.. toctree:: + :maxdepth: 2 + + sage/categories + The Sage Category Framework --------------------------- diff --git a/src/doc/en/reference/combinat/index.rst b/src/doc/en/reference/combinat/index.rst index 1066b9a34f3..4470e97836d 100644 --- a/src/doc/en/reference/combinat/index.rst +++ b/src/doc/en/reference/combinat/index.rst @@ -3,7 +3,6 @@ Combinatorics .. automodule:: sage.combinat - Comprehensive Module List ------------------------- diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 529ff3f41a7..1807a13c9b3 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -15,7 +15,6 @@ Comprehensive Module list .. toctree:: :maxdepth: 1 - sage/combinat/__init__ sage/combinat/abstract_tree sage/combinat/affine_permutation sage/combinat/algebraic_combinatorics @@ -28,10 +27,9 @@ Comprehensive Module list sage/combinat/blob_algebra sage/combinat/cartesian_product sage/combinat/catalog_partitions - sage/combinat/chas/__init__ + sage/combinat/chas/all sage/combinat/chas/fsym sage/combinat/chas/wqsym - sage/combinat/cluster_algebra_quiver/__init__ sage/combinat/cluster_algebra_quiver/all sage/combinat/cluster_algebra_quiver/cluster_seed sage/combinat/cluster_algebra_quiver/mutation_class @@ -50,7 +48,6 @@ Comprehensive Module list sage/combinat/constellation sage/combinat/core sage/combinat/counting - sage/combinat/crystals/__init__ sage/combinat/crystals/affine sage/combinat/crystals/affine_factorization sage/combinat/crystals/affinization @@ -90,7 +87,6 @@ Comprehensive Module list sage/combinat/degree_sequences sage/combinat/derangements sage/combinat/descent_algebra - sage/combinat/designs/__init__ sage/combinat/designs/all sage/combinat/designs/bibd sage/combinat/designs/resolvable_bibd @@ -149,7 +145,6 @@ Comprehensive Module list sage/combinat/k_tableau sage/combinat/kazhdan_lusztig sage/combinat/knutson_tao_puzzles - sage/combinat/matrices/__init__ sage/combinat/matrices/all sage/combinat/matrices/dancing_links sage/combinat/matrices/dlxcpp @@ -157,14 +152,12 @@ Comprehensive Module list sage/combinat/matrices/latin sage/combinat/misc sage/combinat/multiset_partition_into_sets_ordered - sage/combinat/ncsf_qsym/__init__ sage/combinat/ncsf_qsym/all sage/combinat/ncsf_qsym/combinatorics sage/combinat/ncsf_qsym/generic_basis_code sage/combinat/ncsf_qsym/ncsf sage/combinat/ncsf_qsym/qsym sage/combinat/ncsf_qsym/tutorial - sage/combinat/ncsym/__init__ sage/combinat/ncsym/all sage/combinat/ncsym/bases sage/combinat/ncsym/dual @@ -190,7 +183,6 @@ Comprehensive Module list sage/combinat/perfect_matching sage/combinat/permutation sage/combinat/permutation_cython - sage/combinat/posets/__init__ sage/combinat/posets/all sage/combinat/posets/cartesian_product sage/combinat/posets/d_complete @@ -213,7 +205,6 @@ Comprehensive Module list sage/combinat/ribbon sage/combinat/ribbon_shaped_tableau sage/combinat/ribbon_tableau - sage/combinat/rigged_configurations/__init__ sage/combinat/rigged_configurations/all sage/combinat/rigged_configurations/bij_abstract_class sage/combinat/rigged_configurations/bij_infinity @@ -236,7 +227,6 @@ Comprehensive Module list sage/combinat/rigged_configurations/rigged_partition sage/combinat/rigged_configurations/tensor_product_kr_tableaux sage/combinat/rigged_configurations/tensor_product_kr_tableaux_element - sage/combinat/root_system/__init__ sage/combinat/root_system/all sage/combinat/root_system/ambient_space sage/combinat/root_system/associahedron @@ -298,7 +288,6 @@ Comprehensive Module list sage/combinat/schubert_polynomial sage/combinat/set_partition sage/combinat/set_partition_ordered - sage/combinat/sf/__init__ sage/combinat/sf/all sage/combinat/sf/character sage/combinat/sf/classical @@ -334,7 +323,6 @@ Comprehensive Module list sage/combinat/skew_partition sage/combinat/skew_tableau sage/combinat/sloane_functions - sage/combinat/species/__init__ sage/combinat/species/all sage/combinat/species/characteristic_species sage/combinat/species/composition_species @@ -375,7 +363,6 @@ Comprehensive Module list sage/combinat/tuple sage/combinat/tutorial sage/combinat/vector_partition - sage/combinat/words/__init__ sage/combinat/words/abstract_word sage/combinat/words/all sage/combinat/words/alphabet diff --git a/src/sage/categories/__init__.py b/src/sage/categories/__init__.py index 11af5bbf980..e69de29bb2d 100644 --- a/src/sage/categories/__init__.py +++ b/src/sage/categories/__init__.py @@ -1,29 +0,0 @@ -r""" -Sage categories quickref ------------------------- - -- sage.categories.primer? A primer on Elements, Parents, and Categories -- sage.categories.tutorial? A tutorial on Elements, Parents, and Categories -- Category? Technical background on categories -- Sets() Semigroups() Algebras(QQ) Some categories -- SemiGroups().example()?? Sample implementation of a semigroup -- Hom(A, B), End(A, Algebras()) Homomorphisms sets -- tensor, cartesian_product Functorial constructions - -Module layout: - -- sage.categories.basic: the basic categories -- sage.categories.all: all categories -- sage.categories.semigroups: the Semigroups() category -- sage.categories.examples.semigroups the example of Semigroups() -- sage.categories.homset, map, - morphism, functors: morphisms, ... -- sage.categories.cartesian_product, tensor, - dual: functorial constructions - - -Todo: put the quickref in quickref.py, and only some pointers here? - -""" - -from . import primer diff --git a/src/sage/categories/all.py b/src/sage/categories/all.py index 053fd577d24..cc38c442873 100644 --- a/src/sage/categories/all.py +++ b/src/sage/categories/all.py @@ -1,3 +1,32 @@ +r""" +Sage categories quickref + +- ``sage.categories.primer?`` a primer on Elements, Parents, and Categories +- ``sage.categories.tutorial?`` a tutorial on Elements, Parents, and Categories +- ``Category?`` technical background on categories +- ``Sets()``, ``Semigroups()``, ``Algebras(QQ)`` some categories +- ``SemiGroups().example()??`` sample implementation of a semigroup +- ``Hom(A, B)``, ``End(A, Algebras())`` homomorphisms sets +- ``tensor``, ``cartesian_product`` functorial constructions + +Module layout: + +- :mod:`sage.categories.basic` the basic categories +- :mod:`sage.categories.all` all categories +- :mod:`sage.categories.semigroups` the ``Semigroups()`` category +- :mod:`sage.categories.examples.semigroups` the example of ``Semigroups()`` +- :mod:`sage.categories.homset` morphisms, ... +- :mod:`sage.categories.map` +- :mod:`sage.categories.morphism` +- :mod:`sage.categories.functors` +- :mod:`sage.categories.cartesian_product` functorial constructions +- :mod:`sage.categories.tensor` +- :mod:`sage.categories.dual` +""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import from .category import Category diff --git a/src/sage/combinat/__init__.py b/src/sage/combinat/__init__.py index d7d8e22b536..e69de29bb2d 100644 --- a/src/sage/combinat/__init__.py +++ b/src/sage/combinat/__init__.py @@ -1,49 +0,0 @@ -r""" -Combinatorics -============= - -Introductory material ---------------------- - -- :ref:`sage.combinat.quickref` -- :ref:`sage.combinat.tutorial` - -Thematic indexes ----------------- - -- :ref:`sage.combinat.algebraic_combinatorics` - - - :ref:`sage.combinat.chas` - - :ref:`sage.combinat.cluster_algebra_quiver` - - :ref:`sage.combinat.crystals` - - :ref:`sage.combinat.root_system` - - :ref:`sage.combinat.sf` - - :class:`~sage.combinat.fully_commutative_elements.FullyCommutativeElements` - -- :ref:`sage.combinat.counting` -- :ref:`sage.combinat.enumerated_sets` -- :ref:`sage.combinat.catalog_partitions` -- :ref:`sage.combinat.finite_state_machine` -- :ref:`sage.combinat.species` -- :ref:`sage.combinat.designs` -- :ref:`sage.combinat.posets` -- :ref:`sage.combinat.words` - -Utilities ---------- - -- :ref:`sage.combinat.output` -- :ref:`sage.combinat.ranker` -- :func:`Combinatorial maps ` -- :ref:`sage.combinat.misc` - -Related topics --------------- - -- :ref:`sage.coding` -- :ref:`sage.dynamics` -- :ref:`sage.graphs` - -""" -from . import quickref -from . import tutorial diff --git a/src/sage/combinat/algebraic_combinatorics.py b/src/sage/combinat/algebraic_combinatorics.py index 599913ffdb8..b8f01700156 100644 --- a/src/sage/combinat/algebraic_combinatorics.py +++ b/src/sage/combinat/algebraic_combinatorics.py @@ -1,17 +1,9 @@ r""" Algebraic combinatorics -======================= - -Quickref --------- - -.. TODO:: write it! Thematic tutorials ------------------ -.. TODO:: get Sphinx to create those cross links properly - - `Algebraic Combinatorics in Sage <../../../../thematic_tutorials/algebraic_combinatorics.html>`_ - `Lie Methods and Related Combinatorics in Sage <../../../../thematic_tutorials/lie.html>`_ - `Linear Programming (Mixed Integer) <../../../../thematic_tutorials/linear_programming.html>`_ @@ -41,10 +33,10 @@ Combinatorial Representation Theory ----------------------------------- -- :ref:`sage.combinat.root_system` -- :ref:`sage.combinat.crystals` -- :ref:`sage.combinat.rigged_configurations` -- :ref:`sage.combinat.cluster_algebra_quiver` +- :ref:`sage.combinat.root_system.all` +- :ref:`sage.combinat.crystals.all` +- :ref:`sage.combinat.rigged_configurations.all` +- :ref:`sage.combinat.cluster_algebra_quiver.all` - :class:`~sage.combinat.kazhdan_lusztig.KazhdanLusztigPolynomial` - :class:`~sage.combinat.symmetric_group_representations.SymmetricGroupRepresentation` - :ref:`sage.combinat.yang_baxter_graph` diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index cc23f903efd..1f0997be887 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -1,6 +1,52 @@ +r""" +Combinatorics + +Introductory material +--------------------- + +- :ref:`sage.combinat.quickref` +- :ref:`sage.combinat.tutorial` + +Thematic indexes +---------------- + +- :ref:`sage.combinat.algebraic_combinatorics` + + - :ref:`sage.combinat.chas.all` + - :ref:`sage.combinat.cluster_algebra_quiver.all` + - :ref:`sage.combinat.crystals.all` + - :ref:`sage.combinat.root_system.all` + - :ref:`sage.combinat.sf.all` + - :class:`~sage.combinat.fully_commutative_elements.FullyCommutativeElements` + +- :ref:`sage.combinat.counting` +- :ref:`sage.combinat.enumerated_sets` +- :ref:`sage.combinat.catalog_partitions` +- :ref:`sage.combinat.finite_state_machine` +- :ref:`sage.combinat.species.all` +- :ref:`sage.combinat.designs.all` +- :ref:`sage.combinat.posets.all` +- :ref:`sage.combinat.words.all` + +Utilities +--------- + +- :ref:`sage.combinat.output` +- :ref:`sage.combinat.ranker` +- :func:`Combinatorial maps ` +- :ref:`sage.combinat.misc` + +Related topics +-------------- + +- :ref:`sage.coding` +- :ref:`sage.dynamics` +- :ref:`sage.graphs` + """ -Combinatorics features that are imported by default in the interpreter namespace -""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/catalog_partitions.py b/src/sage/combinat/catalog_partitions.py index 2ff59c6017c..ca143fa540c 100644 --- a/src/sage/combinat/catalog_partitions.py +++ b/src/sage/combinat/catalog_partitions.py @@ -1,6 +1,5 @@ r""" Enumerated sets of partitions, tableaux, ... -============================================ Partitions ---------- diff --git a/src/sage/combinat/chas/__init__.py b/src/sage/combinat/chas/__init__.py index 41b823ca81e..8b137891791 100644 --- a/src/sage/combinat/chas/__init__.py +++ b/src/sage/combinat/chas/__init__.py @@ -1,13 +1 @@ -""" -Combinatorial Hopf algebras -=========================== -- :ref:`sage.combinat.sf` -- :ref:`sage.combinat.ncsf_qsym` -- :ref:`sage.combinat.ncsym` -- :ref:`sage.combinat.schubert_polynomial` -- :ref:`sage.combinat.chas.fsym` -- :ref:`sage.combinat.fqsym` -- :ref:`sage.combinat.grossman_larson_algebras` -- :ref:`sage.combinat.chas.wqsym` -""" diff --git a/src/sage/combinat/chas/all.py b/src/sage/combinat/chas/all.py index ecb6f2f0c77..899155c0385 100644 --- a/src/sage/combinat/chas/all.py +++ b/src/sage/combinat/chas/all.py @@ -1,7 +1,21 @@ """ -Combinatorial Hopf Algebras +Combinatorial Hopf algebras + +- :ref:`sage.combinat.sf.all` +- :ref:`sage.combinat.ncsf_qsym.all` +- :ref:`sage.combinat.ncsym.all` +- :ref:`sage.combinat.schubert_polynomial` +- :ref:`sage.combinat.chas.fsym` +- :ref:`sage.combinat.fqsym` +- :ref:`sage.combinat.grossman_larson_algebras` +- :ref:`sage.combinat.chas.wqsym` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.chas.fsym', ['FreeSymmetricFunctions']) lazy_import('sage.combinat.chas.wqsym', ['WordQuasiSymmetricFunctions']) + diff --git a/src/sage/combinat/cluster_algebra_quiver/__init__.py b/src/sage/combinat/cluster_algebra_quiver/__init__.py index 314a35ef7ef..e69de29bb2d 100644 --- a/src/sage/combinat/cluster_algebra_quiver/__init__.py +++ b/src/sage/combinat/cluster_algebra_quiver/__init__.py @@ -1,10 +0,0 @@ -r""" -Cluster Algebras and Quivers -============================ - -- A compendium on the cluster algebra and quiver package in Sage [MS2011]_ - -- :ref:`sage.combinat.cluster_algebra_quiver.quiver_mutation_type` -- :ref:`sage.combinat.cluster_algebra_quiver.quiver` -- :ref:`sage.combinat.cluster_algebra_quiver.cluster_seed` -""" diff --git a/src/sage/combinat/cluster_algebra_quiver/all.py b/src/sage/combinat/cluster_algebra_quiver/all.py index 44060e2b3cb..61fec4fde04 100644 --- a/src/sage/combinat/cluster_algebra_quiver/all.py +++ b/src/sage/combinat/cluster_algebra_quiver/all.py @@ -1,7 +1,18 @@ +r""" +Cluster algebras and quivers + +- A compendium on the cluster algebra and quiver package in Sage [MS2011]_ + +- :ref:`sage.combinat.cluster_algebra_quiver.quiver_mutation_type` +- :ref:`sage.combinat.cluster_algebra_quiver.quiver` +- :ref:`sage.combinat.cluster_algebra_quiver.cluster_seed` """ -Cluster algebra and quivers features that are imported by default in the interpreter namespace -""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import lazy_import("sage.combinat.cluster_algebra_quiver.quiver_mutation_type", "QuiverMutationType") lazy_import("sage.combinat.cluster_algebra_quiver.quiver", "ClusterQuiver") lazy_import("sage.combinat.cluster_algebra_quiver.cluster_seed", "ClusterSeed") + diff --git a/src/sage/combinat/crystals/__init__.py b/src/sage/combinat/crystals/__init__.py index 63719c0d2f9..e69de29bb2d 100644 --- a/src/sage/combinat/crystals/__init__.py +++ b/src/sage/combinat/crystals/__init__.py @@ -1,29 +0,0 @@ -r""" -Crystals -======== - -Quickref --------- - -.. TODO:: Write it! - -Introductory material ---------------------- - -- :ref:`sage.combinat.crystals.crystals` -- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial - -Catalogs of crystals --------------------- - -- :ref:`sage.combinat.crystals.catalog` - -See also --------- - -- The categories for crystals: :class:`Crystals`, :class:`HighestWeightCrystals`, - :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals`, - :class:`~sage.categories.regular_supercrystals.RegularSuperCrystals` - -- The categories for crystals -- :ref:`sage.combinat.root_system` -""" diff --git a/src/sage/combinat/crystals/all.py b/src/sage/combinat/crystals/all.py index 3c4d599224f..67730a507a1 100644 --- a/src/sage/combinat/crystals/all.py +++ b/src/sage/combinat/crystals/all.py @@ -1,7 +1,31 @@ +r""" +Crystals + +Introductory material +--------------------- + +- :ref:`sage.combinat.crystals.crystals` +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial + +Catalogs of crystals +-------------------- + +- :ref:`sage.combinat.crystals.catalog` + +See also +-------- + +- The categories for crystals: :class:`Crystals`, :class:`HighestWeightCrystals`, + :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals`, + :class:`~sage.categories.regular_supercrystals.RegularSuperCrystals` + -- The categories for crystals +- :ref:`sage.combinat.root_system` """ -Crystal features that are imported by default in the interpreter namespace -""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.crystals', 'catalog', 'crystals') + diff --git a/src/sage/combinat/designs/__init__.py b/src/sage/combinat/designs/__init__.py index 4808cf1a552..8b137891791 100644 --- a/src/sage/combinat/designs/__init__.py +++ b/src/sage/combinat/designs/__init__.py @@ -1,38 +1 @@ -r""" -Combinatorial Designs and Incidence Structures -============================================== -All designs can be accessed by ``designs.`` and are listed in the -design catalog: - -- :ref:`sage.combinat.designs.design_catalog` - -**Design-related classes** - -- :ref:`sage.combinat.designs.incidence_structures` -- :ref:`sage.combinat.designs.covering_design` - -**Constructions** - -- :ref:`sage.combinat.designs.block_design` -- :ref:`sage.combinat.designs.bibd` -- :ref:`sage.combinat.designs.resolvable_bibd` -- :ref:`sage.combinat.designs.group_divisible_designs` -- :ref:`sage.combinat.designs.latin_squares` -- :ref:`sage.combinat.designs.orthogonal_arrays` -- :ref:`sage.combinat.designs.orthogonal_arrays_build_recursive` -- :ref:`sage.combinat.designs.orthogonal_arrays_find_recursive` -- :ref:`sage.combinat.designs.difference_family` -- :ref:`sage.combinat.designs.difference_matrices` -- :ref:`sage.combinat.designs.steiner_quadruple_systems` -- :ref:`sage.combinat.designs.twographs` -- :ref:`sage.combinat.designs.database` -- :ref:`sage.combinat.designs.gen_quadrangles_with_spread` - -**Technical things** - -- :ref:`sage.combinat.designs.ext_rep` -- :ref:`sage.combinat.designs.designs_pyx` -- :ref:`sage.combinat.designs.subhypergraph_search` -- :ref:`sage.combinat.designs.evenly_distributed_sets` -""" diff --git a/src/sage/combinat/designs/all.py b/src/sage/combinat/designs/all.py index 81210cf3b7f..0948c6fa281 100644 --- a/src/sage/combinat/designs/all.py +++ b/src/sage/combinat/designs/all.py @@ -1,6 +1,44 @@ +r""" +Combinatorial designs and incidence structures + +All designs can be accessed by ``designs.`` and are listed in the +design catalog: + +- :ref:`sage.combinat.designs.design_catalog` + +**Design-related classes** + +- :ref:`sage.combinat.designs.incidence_structures` +- :ref:`sage.combinat.designs.covering_design` + +**Constructions** + +- :ref:`sage.combinat.designs.block_design` +- :ref:`sage.combinat.designs.bibd` +- :ref:`sage.combinat.designs.resolvable_bibd` +- :ref:`sage.combinat.designs.group_divisible_designs` +- :ref:`sage.combinat.designs.latin_squares` +- :ref:`sage.combinat.designs.orthogonal_arrays` +- :ref:`sage.combinat.designs.orthogonal_arrays_build_recursive` +- :ref:`sage.combinat.designs.orthogonal_arrays_find_recursive` +- :ref:`sage.combinat.designs.difference_family` +- :ref:`sage.combinat.designs.difference_matrices` +- :ref:`sage.combinat.designs.steiner_quadruple_systems` +- :ref:`sage.combinat.designs.twographs` +- :ref:`sage.combinat.designs.database` +- :ref:`sage.combinat.designs.gen_quadrangles_with_spread` + +**Technical things** + +- :ref:`sage.combinat.designs.ext_rep` +- :ref:`sage.combinat.designs.designs_pyx` +- :ref:`sage.combinat.designs.subhypergraph_search` +- :ref:`sage.combinat.designs.evenly_distributed_sets` """ -Combinatorial design features that are imported by default in the interpreter namespace -""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/enumerated_sets.py b/src/sage/combinat/enumerated_sets.py index 1c8350bfea4..f529886da82 100644 --- a/src/sage/combinat/enumerated_sets.py +++ b/src/sage/combinat/enumerated_sets.py @@ -1,6 +1,5 @@ """ Enumerated sets and combinatorial objects -========================================= .. TODO:: Proofread / point to the main classes rather than the modules @@ -132,7 +131,7 @@ - :ref:`sage.combinat.tiling` - :ref:`sage.combinat.dlx` - :ref:`sage.combinat.matrices.dlxcpp` -- :ref:`sage.combinat.species` +- :ref:`sage.combinat.species.all` - :class:`~sage.combinat.integer_lists.IntegerListsLex` - :class:`~sage.combinat.integer_vectors_mod_permgroup.IntegerVectorsModPermutationGroup` diff --git a/src/sage/combinat/finite_state_machine.py b/src/sage/combinat/finite_state_machine.py index 2cdd4045c02..bf3ddb74d45 100644 --- a/src/sage/combinat/finite_state_machine.py +++ b/src/sage/combinat/finite_state_machine.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- r""" -Finite State Machines, Automata, Transducers +Finite state machines, automata, transducers This module adds support for finite state machines, automata and transducers. diff --git a/src/sage/combinat/integer_lists/__init__.py b/src/sage/combinat/integer_lists/__init__.py index 6664a99ead2..4e0c59ff8a6 100644 --- a/src/sage/combinat/integer_lists/__init__.py +++ b/src/sage/combinat/integer_lists/__init__.py @@ -1,4 +1,3 @@ - from .base import IntegerListsBackend, Envelope from .lists import IntegerLists from .invlex import IntegerListsLex diff --git a/src/sage/combinat/matrices/__init__.py b/src/sage/combinat/matrices/__init__.py index aa4264e01af..e69de29bb2d 100644 --- a/src/sage/combinat/matrices/__init__.py +++ b/src/sage/combinat/matrices/__init__.py @@ -1,9 +0,0 @@ -r""" -Combinatorics on matrices -========================= - -- :ref:`sage.combinat.matrices.dancing_links` -- :ref:`sage.combinat.matrices.dlxcpp` -- :ref:`sage.combinat.matrices.hadamard_matrix` -- :ref:`sage.combinat.matrices.latin` -""" diff --git a/src/sage/combinat/matrices/all.py b/src/sage/combinat/matrices/all.py index 67793f125e7..baa34da139a 100644 --- a/src/sage/combinat/matrices/all.py +++ b/src/sage/combinat/matrices/all.py @@ -1,6 +1,15 @@ r""" -Combinatorics on matrix features that are imported by default in the interpreter namespace +Combinatorics on matrices + +- :ref:`sage.combinat.matrices.dancing_links` +- :ref:`sage.combinat.matrices.dlxcpp` +- :ref:`sage.combinat.matrices.hadamard_matrix` +- :ref:`sage.combinat.matrices.latin` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import lazy_import('sage.combinat.matrices.latin', @@ -8,3 +17,4 @@ lazy_import('sage.combinat.matrices.dlxcpp', 'DLXCPP') lazy_import('sage.combinat.matrices.hadamard_matrix', ['hadamard_matrix', 'hadamard_matrix_www']) + diff --git a/src/sage/combinat/ncsf_qsym/__init__.py b/src/sage/combinat/ncsf_qsym/__init__.py index 97f41285b1a..8b137891791 100644 --- a/src/sage/combinat/ncsf_qsym/__init__.py +++ b/src/sage/combinat/ncsf_qsym/__init__.py @@ -1,11 +1 @@ -r""" -Non-Commutative Symmetric Functions and Quasi-Symmetric Functions -================================================================= -- :ref:`sage.combinat.ncsf_qsym.tutorial` - -- :ref:`Non-Commutative Symmetric Functions (NCSF) ` -- :ref:`Quasi-Symmetric Functions (QSym) ` -- :ref:`sage.combinat.ncsf_qsym.generic_basis_code` - -""" diff --git a/src/sage/combinat/ncsf_qsym/all.py b/src/sage/combinat/ncsf_qsym/all.py index 9156bd0f05c..212da647869 100644 --- a/src/sage/combinat/ncsf_qsym/all.py +++ b/src/sage/combinat/ncsf_qsym/all.py @@ -1,6 +1,17 @@ r""" -Features that are imported by default in the interpreter namespace +Non-commutative symmetric functions and quasi-symmetric functions + +- :ref:`sage.combinat.ncsf_qsym.tutorial` + +- :ref:`Non-Commutative Symmetric Functions (NCSF) ` +- :ref:`Quasi-Symmetric Functions (QSym) ` +- :ref:`sage.combinat.ncsf_qsym.generic_basis_code` + """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from .qsym import QuasiSymmetricFunctions from .ncsf import NonCommutativeSymmetricFunctions + diff --git a/src/sage/combinat/ncsym/__init__.py b/src/sage/combinat/ncsym/__init__.py index 5717495170c..e69de29bb2d 100644 --- a/src/sage/combinat/ncsym/__init__.py +++ b/src/sage/combinat/ncsym/__init__.py @@ -1,10 +0,0 @@ -r""" -Symmetric Functions in Non-Commuting Variables -============================================== - -- :class:`Introduction to Symmetric Functions in Non-Commuting Variables ` - -- :ref:`sage.combinat.ncsym.bases` -- :ref:`sage.combinat.ncsym.dual` -- :ref:`sage.combinat.ncsym.ncsym` -""" diff --git a/src/sage/combinat/ncsym/all.py b/src/sage/combinat/ncsym/all.py index 72da0443b27..7a174e45ccf 100644 --- a/src/sage/combinat/ncsym/all.py +++ b/src/sage/combinat/ncsym/all.py @@ -1,7 +1,15 @@ +r""" +Symmetric functions in non-commuting variables + +- :class:`Introduction to Symmetric Functions in Non-Commuting Variables ` + +- :ref:`sage.combinat.ncsym.bases` +- :ref:`sage.combinat.ncsym.dual` +- :ref:`sage.combinat.ncsym.ncsym` """ -Features that are imported by default in the interpreter namespace -""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from .ncsym import SymmetricFunctionsNonCommutingVariables from .dual import SymmetricFunctionsNonCommutingVariablesDual - diff --git a/src/sage/combinat/path_tableaux/__init__.py b/src/sage/combinat/path_tableaux/__init__.py index 564cfb994c4..8b137891791 100644 --- a/src/sage/combinat/path_tableaux/__init__.py +++ b/src/sage/combinat/path_tableaux/__init__.py @@ -1,11 +1 @@ -r""" -Path Tableaux -============= - -- :ref:`sage.combinat.path_tableaux.path_tableau` -- :ref:`sage.combinat.path_tableaux.dyck_path` -- :ref:`sage.combinat.path_tableaux.frieze` -- :ref:`sage.combinat.path_tableaux.semistandard` - -""" diff --git a/src/sage/combinat/path_tableaux/all.py b/src/sage/combinat/path_tableaux/all.py index 9ae4469b28d..42a2e8ca4a5 100644 --- a/src/sage/combinat/path_tableaux/all.py +++ b/src/sage/combinat/path_tableaux/all.py @@ -1,3 +1,12 @@ r""" -PathTableaux +Path tableaux + +- :ref:`sage.combinat.path_tableaux.path_tableau` +- :ref:`sage.combinat.path_tableaux.dyck_path` +- :ref:`sage.combinat.path_tableaux.frieze` +- :ref:`sage.combinat.path_tableaux.semistandard` + """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) diff --git a/src/sage/combinat/posets/__init__.py b/src/sage/combinat/posets/__init__.py index 0ef76a3374b..e69de29bb2d 100644 --- a/src/sage/combinat/posets/__init__.py +++ b/src/sage/combinat/posets/__init__.py @@ -1,35 +0,0 @@ -r""" -Posets - -Common posets can be accessed through ``posets.`` and are listed in the -posets catalog: - -- :ref:`Catalog of posets and lattices ` - -Poset-related classes: - -- :ref:`sage.combinat.posets.posets` -- :ref:`sage.combinat.posets.lattices` - -- :ref:`sage.combinat.posets.linear_extensions` -- :ref:`sage.combinat.posets.d_complete` -- :ref:`sage.combinat.posets.forest` -- :ref:`sage.combinat.posets.mobile` -- :ref:`sage.combinat.posets.incidence_algebras` - -- :ref:`sage.combinat.posets.cartesian_product` - -- :ref:`sage.combinat.posets.moebius_algebra` - -- :ref:`sage.combinat.tamari_lattices` -- :ref:`sage.combinat.interval_posets` -- :ref:`sage.combinat.shard_order` - -If you are looking for Poset-related :mod:`categories -`, see -:class:`~sage.categories.posets.Posets`, -:class:`~sage.categories.finite_posets.FinitePosets`, -:class:`~sage.categories.lattice_posets.LatticePosets` and -:class:`~sage.categories.finite_lattice_posets.FiniteLatticePosets`. -""" - diff --git a/src/sage/combinat/posets/all.py b/src/sage/combinat/posets/all.py index e47f6e93060..f7f8bdcc7fc 100644 --- a/src/sage/combinat/posets/all.py +++ b/src/sage/combinat/posets/all.py @@ -1,6 +1,40 @@ r""" -Poset features that are imported by default in the interpreter namespace +Posets + +Common posets can be accessed through ``posets.`` and are listed in the +posets catalog: + +- :ref:`Catalog of posets and lattices ` + +Poset-related classes: + +- :ref:`sage.combinat.posets.posets` +- :ref:`sage.combinat.posets.lattices` + +- :ref:`sage.combinat.posets.linear_extensions` +- :ref:`sage.combinat.posets.d_complete` +- :ref:`sage.combinat.posets.forest` +- :ref:`sage.combinat.posets.mobile` +- :ref:`sage.combinat.posets.incidence_algebras` + +- :ref:`sage.combinat.posets.cartesian_product` + +- :ref:`sage.combinat.posets.moebius_algebra` + +- :ref:`sage.combinat.tamari_lattices` +- :ref:`sage.combinat.interval_posets` +- :ref:`sage.combinat.shard_order` + +If you are looking for Poset-related :mod:`categories +`, see +:class:`~sage.categories.posets.Posets`, +:class:`~sage.categories.finite_posets.FinitePosets`, +:class:`~sage.categories.lattice_posets.LatticePosets` and +:class:`~sage.categories.finite_lattice_posets.FiniteLatticePosets`. """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from .posets import Poset diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index a62944138ad..f55089e5a28 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -1,6 +1,5 @@ r""" Combinatorics quickref ----------------------- Integer Sequences:: diff --git a/src/sage/combinat/rigged_configurations/__init__.py b/src/sage/combinat/rigged_configurations/__init__.py index ccecaeed2f2..e69de29bb2d 100644 --- a/src/sage/combinat/rigged_configurations/__init__.py +++ b/src/sage/combinat/rigged_configurations/__init__.py @@ -1,36 +0,0 @@ -r""" -Rigged Configurations -===================== - -.. TODO:: Proofread / point to the main classes rather than the modules? - -- :ref:`sage.combinat.rigged_configurations.rc_crystal` -- :ref:`sage.combinat.rigged_configurations.rc_infinity` - -- :ref:`sage.combinat.rigged_configurations.rigged_configurations` -- :ref:`sage.combinat.rigged_configurations.rigged_configuration_element` - -- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux` -- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element` -- :ref:`sage.combinat.rigged_configurations.kr_tableaux` - -- :ref:`sage.combinat.rigged_configurations.kleber_tree` - -- :ref:`sage.combinat.rigged_configurations.rigged_partition` - -Bijections ----------- - -- :ref:`sage.combinat.rigged_configurations.bijection` -- :ref:`sage.combinat.rigged_configurations.bij_abstract_class` -- :ref:`sage.combinat.rigged_configurations.bij_type_A` -- :ref:`sage.combinat.rigged_configurations.bij_type_B` -- :ref:`sage.combinat.rigged_configurations.bij_type_C` -- :ref:`sage.combinat.rigged_configurations.bij_type_D` -- :ref:`sage.combinat.rigged_configurations.bij_type_A2_odd` -- :ref:`sage.combinat.rigged_configurations.bij_type_A2_even` -- :ref:`sage.combinat.rigged_configurations.bij_type_A2_dual` -- :ref:`sage.combinat.rigged_configurations.bij_type_D_twisted` -- :ref:`sage.combinat.rigged_configurations.bij_type_D_tri` -- :ref:`sage.combinat.rigged_configurations.bij_infinity` -""" diff --git a/src/sage/combinat/rigged_configurations/all.py b/src/sage/combinat/rigged_configurations/all.py index 440eed6fdbc..36a10774a89 100644 --- a/src/sage/combinat/rigged_configurations/all.py +++ b/src/sage/combinat/rigged_configurations/all.py @@ -1,6 +1,41 @@ r""" -Features that are imported by default in the interpreter namespace +Rigged configurations + +.. TODO:: Proofread / point to the main classes rather than the modules? + +- :ref:`sage.combinat.rigged_configurations.rc_crystal` +- :ref:`sage.combinat.rigged_configurations.rc_infinity` + +- :ref:`sage.combinat.rigged_configurations.rigged_configurations` +- :ref:`sage.combinat.rigged_configurations.rigged_configuration_element` + +- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux` +- :ref:`sage.combinat.rigged_configurations.tensor_product_kr_tableaux_element` +- :ref:`sage.combinat.rigged_configurations.kr_tableaux` + +- :ref:`sage.combinat.rigged_configurations.kleber_tree` + +- :ref:`sage.combinat.rigged_configurations.rigged_partition` + +Bijections +---------- + +- :ref:`sage.combinat.rigged_configurations.bijection` +- :ref:`sage.combinat.rigged_configurations.bij_abstract_class` +- :ref:`sage.combinat.rigged_configurations.bij_type_A` +- :ref:`sage.combinat.rigged_configurations.bij_type_B` +- :ref:`sage.combinat.rigged_configurations.bij_type_C` +- :ref:`sage.combinat.rigged_configurations.bij_type_D` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_odd` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_even` +- :ref:`sage.combinat.rigged_configurations.bij_type_A2_dual` +- :ref:`sage.combinat.rigged_configurations.bij_type_D_twisted` +- :ref:`sage.combinat.rigged_configurations.bij_type_D_tri` +- :ref:`sage.combinat.rigged_configurations.bij_infinity` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index b04c503fad1..bc24bff5c96 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -1,121 +1,3 @@ -""" -Root Systems -============ - -Quickref --------- - -- ``T = CartanType(["A", 3]), T.is_finite()`` -- Cartan types -- ``T.dynkin_diagram(), DynkinDiagram(["G",2])`` -- Dynkin diagrams -- ``T.cartan_matrix(), CartanMatrix(["F",4])`` -- Cartan matrices -- ``RootSystem(T).weight_lattice()`` -- Root systems -- ``WeylGroup(["B", 6, 1]).simple_reflections()`` -- Affine Weyl groups -- ``WeylCharacterRing(["D", 4])`` -- Weyl character rings - -Introductory material ---------------------- - -- :ref:`sage.combinat.root_system` -- This overview -- :class:`CartanType` -- An introduction to Cartan types -- :class:`RootSystem` -- An introduction to root systems -- :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial - -- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial - - -Related material ----------------- - -- :ref:`sage.combinat.crystals` -- Crystals - -Cartan datum ------------- - -- :ref:`sage.combinat.root_system.cartan_type` -- :ref:`sage.combinat.root_system.dynkin_diagram` -- :ref:`sage.combinat.root_system.cartan_matrix` -- :ref:`sage.combinat.root_system.coxeter_matrix` -- :ref:`sage.combinat.root_system.coxeter_type` - -Root systems ------------- - -- :ref:`sage.combinat.root_system.root_system` -- :ref:`sage.combinat.root_system.plot` -- :ref:`sage.combinat.root_system.root_lattice_realizations` -- :ref:`sage.combinat.root_system.root_lattice_realization_algebras` -- :ref:`sage.combinat.root_system.weight_lattice_realizations` -- :ref:`sage.combinat.root_system.root_space` -- :ref:`sage.combinat.root_system.weight_space` -- :ref:`sage.combinat.root_system.ambient_space` - -Coxeter groups --------------- - -- :ref:`sage.combinat.root_system.coxeter_group` -- :ref:`sage.combinat.root_system.weyl_group` -- :ref:`sage.combinat.root_system.extended_affine_weyl_group` -- :ref:`sage.combinat.root_system.fundamental_group` -- :ref:`sage.combinat.root_system.braid_move_calculator` -- :ref:`sage.combinat.root_system.braid_orbit` - -.. SEEALSO:: - - The categories :class:`CoxeterGroups` and :class:`WeylGroups` - -Finite reflection groups ------------------------- - -- :ref:`sage.combinat.root_system.reflection_group_complex` -- :ref:`sage.combinat.root_system.reflection_group_real` - -.. SEEALSO:: - - The category :class:`~sage.categories.complex_reflection_groups.ComplexReflectionGroups` - -Representation theory ---------------------- - -- :ref:`sage.combinat.root_system.weyl_characters` -- :ref:`sage.combinat.root_system.fusion_ring` -- :ref:`sage.combinat.root_system.integrable_representations` -- :ref:`sage.combinat.root_system.branching_rules` -- :ref:`sage.combinat.root_system.hecke_algebra_representation` -- :ref:`sage.combinat.root_system.non_symmetric_macdonald_polynomials` - -Root system data and code for specific families of Cartan types ---------------------------------------------------------------- - -- :ref:`sage.combinat.root_system.type_affine` -- :ref:`sage.combinat.root_system.type_dual` -- :ref:`sage.combinat.root_system.type_folded` -- :ref:`sage.combinat.root_system.type_reducible` -- :ref:`sage.combinat.root_system.type_relabel` -- :ref:`sage.combinat.root_system.type_marked` - -Root system data and code for specific Cartan types ---------------------------------------------------- - -- :ref:`sage.combinat.root_system.type_A` -- :ref:`sage.combinat.root_system.type_B` -- :ref:`sage.combinat.root_system.type_C` -- :ref:`sage.combinat.root_system.type_D` -- :ref:`sage.combinat.root_system.type_E` -- :ref:`sage.combinat.root_system.type_F` -- :ref:`sage.combinat.root_system.type_G` -- :ref:`sage.combinat.root_system.type_H` -- :ref:`sage.combinat.root_system.type_I` -- :ref:`sage.combinat.root_system.type_A_affine` -- :ref:`sage.combinat.root_system.type_B_affine` -- :ref:`sage.combinat.root_system.type_C_affine` -- :ref:`sage.combinat.root_system.type_D_affine` -- :ref:`sage.combinat.root_system.type_E_affine` -- :ref:`sage.combinat.root_system.type_F_affine` -- :ref:`sage.combinat.root_system.type_G_affine` -- :ref:`sage.combinat.root_system.type_BC_affine` -- :ref:`sage.combinat.root_system.type_super_A` -- :ref:`sage.combinat.root_system.type_A_infinity` -""" # currently needed to activate the backward compatibility # register_unpickle_override from . import type_A diff --git a/src/sage/combinat/root_system/all.py b/src/sage/combinat/root_system/all.py index dfd959e9697..d9008e6550c 100644 --- a/src/sage/combinat/root_system/all.py +++ b/src/sage/combinat/root_system/all.py @@ -1,5 +1,119 @@ -r""" -Root system features that are imported by default in the interpreter namespace +""" +Root Systems + +Quickref +-------- + +- ``T = CartanType(["A", 3]), T.is_finite()`` -- Cartan types +- ``T.dynkin_diagram(), DynkinDiagram(["G",2])`` -- Dynkin diagrams +- ``T.cartan_matrix(), CartanMatrix(["F",4])`` -- Cartan matrices +- ``RootSystem(T).weight_lattice()`` -- Root systems +- ``WeylGroup(["B", 6, 1]).simple_reflections()`` -- Affine Weyl groups +- ``WeylCharacterRing(["D", 4])`` -- Weyl character rings + +Introductory material +--------------------- + +- :ref:`sage.combinat.root_system` -- This overview +- :class:`CartanType` -- An introduction to Cartan types +- :class:`RootSystem` -- An introduction to root systems +- :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial + +- The `Lie Methods and Related Combinatorics <../../../../../thematic_tutorials/lie.html>`_ thematic tutorial + + +Related material +---------------- + +- :ref:`sage.combinat.crystals` -- Crystals + +Cartan datum +------------ + +- :ref:`sage.combinat.root_system.cartan_type` +- :ref:`sage.combinat.root_system.dynkin_diagram` +- :ref:`sage.combinat.root_system.cartan_matrix` +- :ref:`sage.combinat.root_system.coxeter_matrix` +- :ref:`sage.combinat.root_system.coxeter_type` + +Root systems +------------ + +- :ref:`sage.combinat.root_system.root_system` +- :ref:`sage.combinat.root_system.plot` +- :ref:`sage.combinat.root_system.root_lattice_realizations` +- :ref:`sage.combinat.root_system.root_lattice_realization_algebras` +- :ref:`sage.combinat.root_system.weight_lattice_realizations` +- :ref:`sage.combinat.root_system.root_space` +- :ref:`sage.combinat.root_system.weight_space` +- :ref:`sage.combinat.root_system.ambient_space` + +Coxeter groups +-------------- + +- :ref:`sage.combinat.root_system.coxeter_group` +- :ref:`sage.combinat.root_system.weyl_group` +- :ref:`sage.combinat.root_system.extended_affine_weyl_group` +- :ref:`sage.combinat.root_system.fundamental_group` +- :ref:`sage.combinat.root_system.braid_move_calculator` +- :ref:`sage.combinat.root_system.braid_orbit` + +.. SEEALSO:: + + The categories :class:`CoxeterGroups` and :class:`WeylGroups` + +Finite reflection groups +------------------------ + +- :ref:`sage.combinat.root_system.reflection_group_complex` +- :ref:`sage.combinat.root_system.reflection_group_real` + +.. SEEALSO:: + + The category :class:`~sage.categories.complex_reflection_groups.ComplexReflectionGroups` + +Representation theory +--------------------- + +- :ref:`sage.combinat.root_system.weyl_characters` +- :ref:`sage.combinat.root_system.fusion_ring` +- :ref:`sage.combinat.root_system.integrable_representations` +- :ref:`sage.combinat.root_system.branching_rules` +- :ref:`sage.combinat.root_system.hecke_algebra_representation` +- :ref:`sage.combinat.root_system.non_symmetric_macdonald_polynomials` + +Root system data and code for specific families of Cartan types +--------------------------------------------------------------- + +- :ref:`sage.combinat.root_system.type_affine` +- :ref:`sage.combinat.root_system.type_dual` +- :ref:`sage.combinat.root_system.type_folded` +- :ref:`sage.combinat.root_system.type_reducible` +- :ref:`sage.combinat.root_system.type_relabel` +- :ref:`sage.combinat.root_system.type_marked` + +Root system data and code for specific Cartan types +--------------------------------------------------- + +- :ref:`sage.combinat.root_system.type_A` +- :ref:`sage.combinat.root_system.type_B` +- :ref:`sage.combinat.root_system.type_C` +- :ref:`sage.combinat.root_system.type_D` +- :ref:`sage.combinat.root_system.type_E` +- :ref:`sage.combinat.root_system.type_F` +- :ref:`sage.combinat.root_system.type_G` +- :ref:`sage.combinat.root_system.type_H` +- :ref:`sage.combinat.root_system.type_I` +- :ref:`sage.combinat.root_system.type_A_affine` +- :ref:`sage.combinat.root_system.type_B_affine` +- :ref:`sage.combinat.root_system.type_C_affine` +- :ref:`sage.combinat.root_system.type_D_affine` +- :ref:`sage.combinat.root_system.type_E_affine` +- :ref:`sage.combinat.root_system.type_F_affine` +- :ref:`sage.combinat.root_system.type_G_affine` +- :ref:`sage.combinat.root_system.type_BC_affine` +- :ref:`sage.combinat.root_system.type_super_A` +- :ref:`sage.combinat.root_system.type_A_infinity` """ from sage.misc.lazy_import import lazy_import @@ -24,3 +138,7 @@ lazy_import('sage.combinat.root_system.non_symmetric_macdonald_polynomials', 'NonSymmetricMacdonaldPolynomials') lazy_import('sage.combinat.root_system.integrable_representations', 'IntegrableRepresentation') + +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) diff --git a/src/sage/combinat/sf/__init__.py b/src/sage/combinat/sf/__init__.py index c12aa69ef92..8b137891791 100644 --- a/src/sage/combinat/sf/__init__.py +++ b/src/sage/combinat/sf/__init__.py @@ -1,31 +1 @@ -r""" -Symmetric Functions -=================== -- :class:`Introduction to Symmetric Functions ` - -- :ref:`sage.combinat.sf.sfa` -- :ref:`sage.combinat.sf.sf` -- :ref:`sage.combinat.sf.classical` -- :ref:`sage.combinat.sf.schur` -- :ref:`sage.combinat.sf.monomial` -- :ref:`sage.combinat.sf.multiplicative` -- :ref:`sage.combinat.sf.elementary` -- :ref:`sage.combinat.sf.homogeneous` -- :ref:`sage.combinat.sf.powersum` -- :ref:`sage.combinat.sf.character` -- :ref:`sage.combinat.sf.orthogonal` -- :ref:`sage.combinat.sf.symplectic` -- :ref:`sage.combinat.sf.dual` -- :ref:`sage.combinat.sf.orthotriang` -- :ref:`sage.combinat.sf.kfpoly` -- :ref:`sage.combinat.sf.hall_littlewood` -- :ref:`sage.combinat.sf.hecke` -- :ref:`sage.combinat.sf.jack` -- :ref:`k-Schur Functions ` -- :ref:`sage.combinat.sf.k_dual` -- :ref:`sage.combinat.sf.llt` -- :ref:`sage.combinat.sf.macdonald` -- :ref:`sage.combinat.sf.ns_macdonald` -- :ref:`sage.combinat.sf.witt` -""" diff --git a/src/sage/combinat/sf/all.py b/src/sage/combinat/sf/all.py index cc892e10e03..00f8e4f2bdf 100644 --- a/src/sage/combinat/sf/all.py +++ b/src/sage/combinat/sf/all.py @@ -1,6 +1,36 @@ r""" -Symmetric function features that are imported by default in the interpreter namespace +Symmetric Functions + +- :class:`Introduction to Symmetric Functions ` + +- :ref:`sage.combinat.sf.sfa` +- :ref:`sage.combinat.sf.sf` +- :ref:`sage.combinat.sf.classical` +- :ref:`sage.combinat.sf.schur` +- :ref:`sage.combinat.sf.monomial` +- :ref:`sage.combinat.sf.multiplicative` +- :ref:`sage.combinat.sf.elementary` +- :ref:`sage.combinat.sf.homogeneous` +- :ref:`sage.combinat.sf.powersum` +- :ref:`sage.combinat.sf.character` +- :ref:`sage.combinat.sf.orthogonal` +- :ref:`sage.combinat.sf.symplectic` +- :ref:`sage.combinat.sf.dual` +- :ref:`sage.combinat.sf.orthotriang` +- :ref:`sage.combinat.sf.kfpoly` +- :ref:`sage.combinat.sf.hall_littlewood` +- :ref:`sage.combinat.sf.hecke` +- :ref:`sage.combinat.sf.jack` +- :ref:`k-Schur Functions ` +- :ref:`sage.combinat.sf.k_dual` +- :ref:`sage.combinat.sf.llt` +- :ref:`sage.combinat.sf.macdonald` +- :ref:`sage.combinat.sf.ns_macdonald` +- :ref:`sage.combinat.sf.witt` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import diff --git a/src/sage/combinat/species/__init__.py b/src/sage/combinat/species/__init__.py index fcd4cab28c1..8b137891791 100644 --- a/src/sage/combinat/species/__init__.py +++ b/src/sage/combinat/species/__init__.py @@ -1,51 +1 @@ -r""" -Combinatorial Species -===================== -.. TODO:: Short blurb about species - -.. TODO:: Proofread / point to the main classes rather than the modules? - -Introductory material ---------------------- - -- :ref:`section-examples-catalan` -- :ref:`section-generic-species` - -Lazy Power Series ------------------ - -- :ref:`sage.combinat.species.stream` -- :ref:`sage.combinat.species.series_order` -- :ref:`sage.combinat.species.series` -- :ref:`sage.combinat.species.generating_series` - -Basic Species -------------- - -- :ref:`sage.combinat.species.species` -- :ref:`sage.combinat.species.empty_species` -- :ref:`sage.combinat.species.recursive_species` -- :ref:`sage.combinat.species.characteristic_species` -- :ref:`sage.combinat.species.cycle_species` -- :ref:`sage.combinat.species.partition_species` -- :ref:`sage.combinat.species.permutation_species` -- :ref:`sage.combinat.species.linear_order_species` -- :ref:`sage.combinat.species.set_species` -- :ref:`sage.combinat.species.subset_species` -- :ref:`sage.combinat.species.library` - -Operations on Species ---------------------- - -- :ref:`sage.combinat.species.sum_species` -- :ref:`sage.combinat.species.product_species` -- :ref:`sage.combinat.species.composition_species` -- :ref:`sage.combinat.species.functorial_composition_species` - -Miscellaneous -------------- - -- :ref:`sage.combinat.species.structure` -- :ref:`sage.combinat.species.misc` -""" diff --git a/src/sage/combinat/species/all.py b/src/sage/combinat/species/all.py index 8f2a6ede59e..65e18ade5d2 100644 --- a/src/sage/combinat/species/all.py +++ b/src/sage/combinat/species/all.py @@ -1,6 +1,56 @@ r""" -Combinatorial species features that are imported by default in the interpreter namespace +Combinatorial species + +.. TODO:: Short blurb about species + +.. TODO:: Proofread / point to the main classes rather than the modules? + +Introductory material +--------------------- + +- :ref:`section-examples-catalan` +- :ref:`section-generic-species` + +Lazy Power Series +----------------- + +- :ref:`sage.combinat.species.stream` +- :ref:`sage.combinat.species.series_order` +- :ref:`sage.combinat.species.series` +- :ref:`sage.combinat.species.generating_series` + +Basic Species +------------- + +- :ref:`sage.combinat.species.species` +- :ref:`sage.combinat.species.empty_species` +- :ref:`sage.combinat.species.recursive_species` +- :ref:`sage.combinat.species.characteristic_species` +- :ref:`sage.combinat.species.cycle_species` +- :ref:`sage.combinat.species.partition_species` +- :ref:`sage.combinat.species.permutation_species` +- :ref:`sage.combinat.species.linear_order_species` +- :ref:`sage.combinat.species.set_species` +- :ref:`sage.combinat.species.subset_species` +- :ref:`sage.combinat.species.library` + +Operations on Species +--------------------- + +- :ref:`sage.combinat.species.sum_species` +- :ref:`sage.combinat.species.product_species` +- :ref:`sage.combinat.species.composition_species` +- :ref:`sage.combinat.species.functorial_composition_species` + +Miscellaneous +------------- + +- :ref:`sage.combinat.species.structure` +- :ref:`sage.combinat.species.misc` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from .series import LazyPowerSeriesRing from .recursive_species import CombinatorialSpecies diff --git a/src/sage/combinat/words/__init__.py b/src/sage/combinat/words/__init__.py index 519fa41b0db..8b137891791 100644 --- a/src/sage/combinat/words/__init__.py +++ b/src/sage/combinat/words/__init__.py @@ -1,42 +1 @@ -r""" -Combinatorics on Words -====================== -**Main modules and their methods:** - -- :ref:`sage.combinat.words.abstract_word` -- :ref:`sage.combinat.words.finite_word` -- :ref:`sage.combinat.words.infinite_word` -- :ref:`sage.combinat.words.alphabet` -- :ref:`sage.combinat.words.words` -- :ref:`sage.combinat.words.paths` -- :ref:`sage.combinat.words.morphism` -- :ref:`sage.combinat.words.shuffle_product` -- :ref:`sage.combinat.words.suffix_trees` - -Main classes and functions meant to be used by the user: - - :func:`~sage.combinat.words.word.Word`, - :class:`~sage.combinat.words.words.FiniteWords`, - :class:`~sage.combinat.words.words.InfiniteWords`, - :func:`~sage.combinat.words.words.Words`, - :func:`~sage.combinat.words.alphabet.Alphabet`, - :class:`~sage.combinat.words.morphism.WordMorphism`, - :class:`~sage.combinat.words.paths.WordPaths`. - -A list of common words can be accessed through ``words.`` and are listed in -the :ref:`words catalog `. - -**Internal representation of words:** - -- :ref:`sage.combinat.words.word` -- :ref:`sage.combinat.words.word_char` -- :ref:`sage.combinat.words.word_datatypes` -- :ref:`sage.combinat.words.word_infinite_datatypes` - -**Options:** - -- :ref:`sage.combinat.words.word_options` - -See :func:`~sage.combinat.words.word_options.WordOptions`. -""" diff --git a/src/sage/combinat/words/all.py b/src/sage/combinat/words/all.py index 1b23256de90..687b572c8e5 100644 --- a/src/sage/combinat/words/all.py +++ b/src/sage/combinat/words/all.py @@ -1,6 +1,47 @@ r""" -Word features that are imported by default in the interpreter namespace +Combinatorics on words + +**Main modules and their methods:** + +- :ref:`sage.combinat.words.abstract_word` +- :ref:`sage.combinat.words.finite_word` +- :ref:`sage.combinat.words.infinite_word` +- :ref:`sage.combinat.words.alphabet` +- :ref:`sage.combinat.words.words` +- :ref:`sage.combinat.words.paths` +- :ref:`sage.combinat.words.morphism` +- :ref:`sage.combinat.words.shuffle_product` +- :ref:`sage.combinat.words.suffix_trees` + +Main classes and functions meant to be used by the user: + + :func:`~sage.combinat.words.word.Word`, + :class:`~sage.combinat.words.words.FiniteWords`, + :class:`~sage.combinat.words.words.InfiniteWords`, + :func:`~sage.combinat.words.words.Words`, + :func:`~sage.combinat.words.alphabet.Alphabet`, + :class:`~sage.combinat.words.morphism.WordMorphism`, + :class:`~sage.combinat.words.paths.WordPaths`. + +A list of common words can be accessed through ``words.`` and are listed in +the :ref:`words catalog `. + +**Internal representation of words:** + +- :ref:`sage.combinat.words.word` +- :ref:`sage.combinat.words.word_char` +- :ref:`sage.combinat.words.word_datatypes` +- :ref:`sage.combinat.words.word_infinite_datatypes` + +**Options:** + +- :ref:`sage.combinat.words.word_options` + +See :func:`~sage.combinat.words.word_options.WordOptions`. """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from .alphabet import Alphabet, build_alphabet from .morphism import WordMorphism diff --git a/src/sage/misc/namespace_package.py b/src/sage/misc/namespace_package.py new file mode 100644 index 00000000000..75d9f1d8dcc --- /dev/null +++ b/src/sage/misc/namespace_package.py @@ -0,0 +1,20 @@ +""" +Utility functions for namespace packages in Sage +""" +from importlib import import_module + +def install_doc(package, doc): + """ + Install the docstring ``doc`` to the package. + + TESTS: + + sage: from sage.misc.namespace_package import install_doc + sage: install_doc('sage', 'hello') + sage: from inspect import getdoc + sage: getdoc(sage) + 'hello' + """ + pkg = import_module(package) + pkg.__doc__ = doc # enable sage.package? + pkg.getdoc = lambda: doc # enable help(sage.package) diff --git a/src/sage/misc/sagedoc.py b/src/sage/misc/sagedoc.py index e3821e84e76..e6f4ccfb514 100644 --- a/src/sage/misc/sagedoc.py +++ b/src/sage/misc/sagedoc.py @@ -571,7 +571,6 @@ def process_mathtt(s): s = s[:start] + s[start+8:end] + s[end+1:] return s - def format(s, embedded=False): r"""noreplace Format Sage documentation ``s`` for viewing with IPython. @@ -747,7 +746,6 @@ def format(s, embedded=False): s = detex(s, embedded=embedded) return s - def format_src(s): """ Format Sage source code ``s`` for viewing with IPython. @@ -959,7 +957,6 @@ def _search_src_or_doc(what, string, extra1='', extra2='', extra3='', # formatted for Jupyter use }) - def search_src(string, extra1='', extra2='', extra3='', extra4='', extra5='', **kwds): r""" @@ -1136,7 +1133,6 @@ def search_src(string, extra1='', extra2='', extra3='', extra4='', extra3=extra3, extra4=extra4, extra5=extra5, **kwds) - def search_doc(string, extra1='', extra2='', extra3='', extra4='', extra5='', **kwds): r""" @@ -1306,7 +1302,6 @@ def format_search_as_html(what, results, search): return ''.join(s) - ####################################### ## Add detex'ing of documentation ####################################### From 188ff58679bde8818e4e2cd0a5e149f8e95a978c Mon Sep 17 00:00:00 2001 From: Travis Scrimshaw Date: Sat, 6 Nov 2021 11:08:06 +0900 Subject: [PATCH 306/378] Putting the docstring first in eps_monom(). --- src/sage/groups/braid.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sage/groups/braid.py b/src/sage/groups/braid.py index a6e53f2e1a1..688ec825893 100644 --- a/src/sage/groups/braid.py +++ b/src/sage/groups/braid.py @@ -2141,8 +2141,10 @@ def eps(self, N): in parallel. """ def eps_monom(q_tuple): + r""" + Evaluate the map `\mathcal{E}_N` for a single mononial. + """ q = self.q - r"""Evaluate the map $\mathcal{E}_N$ for a single mononial.""" ret_q = q**sum((N - 1 - q_tuple[3*i + 2])*q_tuple[3*i + 1] for i in range(self._minus_begin//3)) ret_q *= q**sum((N - 1)*(-q_tuple[rj]) From 2f5f1957034aee0d9b130dae3f4e52f0e855986e Mon Sep 17 00:00:00 2001 From: Volker Braun Date: Sat, 6 Nov 2021 13:06:26 +0100 Subject: [PATCH 307/378] Add upstream fix for segfault in factorize https://github.com/xianyi/OpenBLAS/issues/3421 https://trac.sagemath.org/ticket/32424 --- .../patches/trsv-fix-from-pr-3422.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 build/pkgs/openblas/patches/trsv-fix-from-pr-3422.patch diff --git a/build/pkgs/openblas/patches/trsv-fix-from-pr-3422.patch b/build/pkgs/openblas/patches/trsv-fix-from-pr-3422.patch new file mode 100644 index 00000000000..0694caf4bf2 --- /dev/null +++ b/build/pkgs/openblas/patches/trsv-fix-from-pr-3422.patch @@ -0,0 +1,26 @@ +From 4b3769823ac865e66eafe7724f95873cca236751 Mon Sep 17 00:00:00 2001 +From: Martin Kroeker +Date: Sun, 24 Oct 2021 23:57:06 +0200 +Subject: [PATCH] Revert #3252 + +--- + interface/trsv.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/interface/trsv.c b/interface/trsv.c +index 6a6e8f8bab..a054d8eeb6 100644 +--- a/interface/trsv.c ++++ b/interface/trsv.c +@@ -188,12 +188,6 @@ void CNAME(enum CBLAS_ORDER order, enum CBLAS_UPLO Uplo, + + if (n == 0) return; + +- if (incx == 1 && trans == 0 && n < 50) { +- buffer = NULL; +- (trsv[(trans<<2) | (uplo<<1) | unit])(n, a, lda, x, incx, buffer); +- return; +- } +- + IDEBUG_START; + + FUNCTION_PROFILE_START(); \ No newline at end of file From 734d3a168e5abf27f0ff3daa55c00059fa1565fa Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sat, 6 Nov 2021 12:25:39 -0400 Subject: [PATCH 308/378] Trac #32061: fix gengetopt's test suite in the absence of makeinfo. We already have a workaround for this problem in spkg-build.in, but we need it in spkg-check.in, too. --- build/pkgs/gengetopt/spkg-check.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build/pkgs/gengetopt/spkg-check.in b/build/pkgs/gengetopt/spkg-check.in index 45b317a382c..34e6fa5ab77 100644 --- a/build/pkgs/gengetopt/spkg-check.in +++ b/build/pkgs/gengetopt/spkg-check.in @@ -1,2 +1,8 @@ cd src + +# See spkg-build.in for an explanation of this hack. +cd src +sdh_make_check +cd ../tests sdh_make_check +cd .. From 66f5f81737d8b3dbbd50ae0d14f7acb7aced89e7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 6 Nov 2021 12:54:02 -0700 Subject: [PATCH 309/378] build/pkgs/numpy: Update to 1.21.4 --- build/pkgs/numpy/checksums.ini | 6 +++--- build/pkgs/numpy/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/numpy/checksums.ini b/build/pkgs/numpy/checksums.ini index b306701d888..f4013779be9 100644 --- a/build/pkgs/numpy/checksums.ini +++ b/build/pkgs/numpy/checksums.ini @@ -1,5 +1,5 @@ tarball=numpy-VERSION.zip -sha1=c7eb91a2232f7843301c355795860baaa0280909 -md5=5638d5dae3ca387be562912312db842e -cksum=2204147896 +sha1=91a1faeb617601453ebf6e2855e5ce6bf94d3588 +md5=b3c4477a027d5b6fba5e1065064fd076 +cksum=1917168823 upstream_url=https://pypi.io/packages/source/n/numpy/numpy-VERSION.zip diff --git a/build/pkgs/numpy/package-version.txt b/build/pkgs/numpy/package-version.txt index 0369d0b1e93..20a1265cf39 100644 --- a/build/pkgs/numpy/package-version.txt +++ b/build/pkgs/numpy/package-version.txt @@ -1 +1 @@ -1.21.2 +1.21.4 From e2ad5ae07c49c8f1af0ced1226cb45d17346ef65 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 6 Nov 2021 12:55:09 -0700 Subject: [PATCH 310/378] build/pkgs/networkx: Update to 2.6.3 --- build/pkgs/networkx/checksums.ini | 6 +++--- build/pkgs/networkx/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/networkx/checksums.ini b/build/pkgs/networkx/checksums.ini index b71ff5f1866..075e0c74047 100644 --- a/build/pkgs/networkx/checksums.ini +++ b/build/pkgs/networkx/checksums.ini @@ -1,5 +1,5 @@ tarball=networkx-VERSION.tar.gz -sha1=5a39af7b0b6a6180b733c280b0ee70b9868a8566 -md5=ac9cf192fc525bb877a042a684091d72 -cksum=1918700937 +sha1=659f640c03fe52c98fa7a1d03fe3a6f6bbce2015 +md5=407eb28c54e08725559754ca7ab185e0 +cksum=3378468789 upstream_url=https://pypi.io/packages/source/n/networkx/networkx-VERSION.tar.gz diff --git a/build/pkgs/networkx/package-version.txt b/build/pkgs/networkx/package-version.txt index 097a15a2af3..ec1cf33c3f6 100644 --- a/build/pkgs/networkx/package-version.txt +++ b/build/pkgs/networkx/package-version.txt @@ -1 +1 @@ -2.6.2 +2.6.3 From 0e5702be09d2cc1b617aa33c6512e09e534547a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 6 Nov 2021 21:33:53 +0100 Subject: [PATCH 311/378] use libgap in coding/ --- src/sage/coding/databases.py | 58 +++++++++++++----------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index c2b1a2a9e23..87e0e41bb4e 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -2,19 +2,19 @@ r""" Access functions to online databases for coding theory """ - -from sage.interfaces.all import gap +from sage.libs.gap.libgap import libgap from sage.features.gap import GapPackage -# Don't put any global imports here since this module is accessible as +# Do not put any global imports here since this module is accessible as # sage.codes.databases. + def best_linear_code_in_guava(n, k, F): r""" - Returns the linear code of length ``n``, dimension ``k`` over field ``F`` + Return the linear code of length ``n``, dimension ``k`` over field ``F`` with the maximal minimum distance which is known to the GAP package GUAVA. - The function uses the tables described in ``bounds_on_minimum_distance_in_guava`` to + The function uses the tables described in :func:`bounds_on_minimum_distance_in_guava` to construct this code. This requires the optional GAP package GUAVA. INPUT: @@ -27,7 +27,7 @@ def best_linear_code_in_guava(n, k, F): OUTPUT: - - A :class:`LinearCode` which is a best linear code of the given parameters known to GUAVA. + A :class:`LinearCode` which is a best linear code of the given parameters known to GUAVA. EXAMPLES:: @@ -41,22 +41,22 @@ def best_linear_code_in_guava(n, k, F): between 2 and 4. Use ``bounds_on_minimum_distance_in_guava(10,5,GF(2))`` for further details. """ - GapPackage("guava", spkg="gap_packages").require() - gap.load_package("guava") - q = F.order() - C = gap("BestKnownLinearCode(%s,%s,GF(%s))"%(n,k,q)) from .linear_code import LinearCode + GapPackage("guava", spkg="gap_packages").require() + libgap.load_package("guava") + C = libgap.BestKnownLinearCode(n, k, F) return LinearCode(C.GeneratorMat()._matrix_(F)) + def bounds_on_minimum_distance_in_guava(n, k, F): r""" - Computes a lower and upper bound on the greatest minimum distance of a + Compute a lower and upper bound on the greatest minimum distance of a `[n,k]` linear code over the field ``F``. This function requires the optional GAP package GUAVA. The function returns a GAP record with the two bounds and an explanation for - each bound. The function Display can be used to show the explanations. + each bound. The method ``Display`` can be used to show the explanations. The values for the lower and upper bound are obtained from a table constructed by Cen Tjhai for GUAVA, derived from the table of @@ -81,21 +81,9 @@ def bounds_on_minimum_distance_in_guava(n, k, F): EXAMPLES:: sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2)) # optional - gap_packages (Guava package) - sage: print(gap_rec) # optional - gap_packages (Guava package) + sage: gap_rec.Display() # optional - gap_packages (Guava package) rec( - construction := - [ , - [ - [ , - [ - [ , - [ [ , [ 8, 2 ] ] ] ], - [ , - [ - [ , - [ [ , [ 4, 2 ] ] ] ] - , [ , [ 4, 2 ] ] ] ] - ] ], [ 1, 2, 3, 4, 5, 6 ] ] ], + construction := [ , [ [ , [ [ , [ [ , [ 8, 2 ] ] ] ], [ , [ [ , [ [ , [ 4, 2 ] ] ] ], [ , [ 4, 2 ] ] ] ] ] ], [ 1, 2, 3, 4, 5, 6 ] ] ], k := 5, lowerBound := 4, lowerBoundExplanation := ... @@ -107,11 +95,9 @@ def bounds_on_minimum_distance_in_guava(n, k, F): upperBoundExplanation := ... ) """ GapPackage("guava", spkg="gap_packages").require() - gap.load_package("guava") - q = F.order() - gap.eval("data := BoundsMinimumDistance(%s,%s,GF(%s))"%(n,k,q)) - Ldata = gap.eval("Display(data)") - return Ldata + libgap.load_package("guava") + return libgap.BoundsMinimumDistance(n, k, F) + def best_linear_code_in_codetables_dot_de(n, k, F, verbose=False): r""" @@ -275,8 +261,6 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, from sage.rings.finite_rings.finite_field_constructor import FiniteField from sage.matrix.constructor import Matrix - - d=int(b) if d!=b or d%2==1 or d <= 0: raise ValueError("b (%s) must be a positive even integer."%b) @@ -285,11 +269,11 @@ def self_orthogonal_binary_codes(n, k, b=2, parent=None, BC=None, equal=False, if k < 1 or n < 2: return if equal: - in_test = lambda M : (M.ncols() - M.nrows()) <= (n-k) - out_test = lambda C : (C.dimension() == k) and (C.length() == n) + in_test = lambda M: (M.ncols() - M.nrows()) <= (n-k) + out_test = lambda C: (C.dimension() == k) and (C.length() == n) else: - in_test = lambda M : True - out_test = lambda C : True + in_test = lambda M: True + out_test = lambda C: True if BC is None: BC = BinaryCodeClassifier() if parent is None: From 24cb6f04e41eecc6f130bf725440700d233eef59 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sat, 6 Nov 2021 23:27:27 +0100 Subject: [PATCH 312/378] trac #32831: correct default setting of multiedges --- src/sage/graphs/base/c_graph.pyx | 2 +- src/sage/graphs/graph_input.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sage/graphs/base/c_graph.pyx b/src/sage/graphs/base/c_graph.pyx index 515ca3076ff..8901ddbc536 100644 --- a/src/sage/graphs/base/c_graph.pyx +++ b/src/sage/graphs/base/c_graph.pyx @@ -1597,7 +1597,7 @@ cdef class CGraphBackend(GenericGraphBackend): The bug in :trac:`14967` and :trac:`14853` is fixed:: sage: DiGraph({0: {}, 1/2: {}}) - Multi-digraph on 2 vertices + Digraph on 2 vertices sage: A = Set([RDF.random_element(min=0, max=10) for k in range(10)]) sage: G = Graph() sage: G.add_vertices(A) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 77f93b96bf4..0caf56efd29 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -453,6 +453,13 @@ def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, conv sage: from_dict_of_dicts(g, graphs.PetersenGraph().to_dictionary(edge_labels=True)) sage: g.is_isomorphic(graphs.PetersenGraph()) True + + TESTS: + + :trac:`32831 is fixed: + + sage: DiGraph({0: {}, 1: {}, 2: {}, 3: {}, 4: {}}) + Digraph on 5 vertices """ if any(not isinstance(M[u], dict) for u in M): raise ValueError("input dict must be a consistent format") @@ -467,6 +474,7 @@ def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, conv loops = False if weighted is None: G._weighted = False + input_multiedges = multiedges if multiedges is not False: if not all(isinstance(M[u][v], list) for u in M for v in M[u]): if multiedges: @@ -501,6 +509,8 @@ def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, conv for u in M: for v in M[u]: G._backend.add_edge(u, v, relabel(M[u][v]), is_directed) + if not G.size() and input_multiedges is not True: + G.allow_multiple_edges(False, check=False) def from_dict_of_lists(G, D, loops=False, multiedges=False, weighted=False): r""" From 1735e775eb4dd3aa25948edeb2b8ac3c36531672 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 7 Nov 2021 09:38:28 +0100 Subject: [PATCH 313/378] trac #32831: fix block --- src/sage/graphs/graph_input.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/graphs/graph_input.py b/src/sage/graphs/graph_input.py index 0caf56efd29..2eb298a06a4 100644 --- a/src/sage/graphs/graph_input.py +++ b/src/sage/graphs/graph_input.py @@ -456,7 +456,7 @@ def from_dict_of_dicts(G, M, loops=False, multiedges=False, weighted=False, conv TESTS: - :trac:`32831 is fixed: + :trac:`32831` is fixed:: sage: DiGraph({0: {}, 1: {}, 2: {}, 3: {}, 4: {}}) Digraph on 5 vertices From 3c9efd2470843c3669c35cdc3d00f8c986d9957e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 6 Nov 2021 09:12:00 +0100 Subject: [PATCH 314/378] subgroup of finite matrix group is finite --- src/sage/groups/cubic_braid.py | 34 +++++++++---------- .../groups/matrix_gps/finitely_generated.py | 7 ++-- src/sage/groups/matrix_gps/matrix_group.py | 32 +++++++++++++---- 3 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/sage/groups/cubic_braid.py b/src/sage/groups/cubic_braid.py index 2d2b5f393be..db110b57e95 100644 --- a/src/sage/groups/cubic_braid.py +++ b/src/sage/groups/cubic_braid.py @@ -76,7 +76,7 @@ # https://www.gnu.org/licenses/ # **************************************************************************** - +from sage.categories.groups import Groups from sage.misc.cachefunc import cached_method from sage.libs.gap.element import GapElement from sage.groups.free_group import FreeGroup @@ -102,12 +102,12 @@ def _reduce_tietze(tietze_list): easily possible using the second braid relation and degree reduction. EXAMPLES:: - + sage: from sage.groups.cubic_braid import _reduce_tietze sage: _reduce_tietze((2, 2, -3, 5, 3, 1, 1, 5)) [-2, -5, -1] """ - def eleminate_item(tietze_list): + def eliminate_item(tietze_list): """ this sub method searches for an item in the Tietze expression such that it together with the first entry gives a pair which can be @@ -118,14 +118,14 @@ def eleminate_item(tietze_list): l = len(tietze_list) if l < 2: return None - first = tietze_list[0] + first = tietze_list[0] second = None for i in range(1,l): if tietze_list[i] in (first, -first): if i == 1: second = tietze_list[i] break - if min(abs(abs(tietze_list[j])-abs(first)) for j in range(1, i)) > 1: + if all(abs(abs(tietze_list[j])-abs(first)) > 1 for j in range(1, i)): # the entry on position i can be moved right to the first entry # by the second braid relation second = tietze_list[i] @@ -143,7 +143,7 @@ def eleminate_item(tietze_list): l = len(tietze_list) for i in range(l): end = tietze_list[i:l] - tietze_list_red = eleminate_item(end) + tietze_list_red = eliminate_item(end) if tietze_list_red is not None: start = tietze_list[:i] return start + _reduce_tietze(tietze_list_red) @@ -788,7 +788,11 @@ def __init__(self, names, cbg_type=None): elif cbg_type == CubicBraidGroup.type.AssionS: rels.append(b[i+2]*b[i]*t[i+1]*b[i]*ti[i+1]*t[i+2]*t[i+1]*b[i]*ti[i+1]*ti[i+2]) - FinitelyPresentedGroup.__init__(self, free_group, tuple(rels)) + if self._nstrands <= 5 or cbg_type != CubicBraidGroup.type.Coxeter: + cat = Groups().Finite() + else: + cat = Groups().Infinite() + FinitelyPresentedGroup.__init__(self, free_group, tuple(rels), category=cat) self._free_group = free_group # ------------------------------------------------------------------------------------------------ @@ -1458,16 +1462,14 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' ... ValueError: Burau representation does not factor through the relations """ - # ------------------------------------------------------------------------------- + # ------------------------------------------------------------------ # define matrix group by generators using the Burau representation - # ------------------------------------------------------------------------------- - + # ------------------------------------------------------------------ unitary = False if isinstance(reduced, str): if reduced == 'unitary': unitary = True - - gen_list =[] + gen_list = [] for braid_gen in self.gens(): bur_mat = braid_gen.burau_matrix(root_bur=root_bur, domain=domain, characteristic=characteristic, var=var, reduced=reduced) @@ -1482,7 +1484,7 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' if unitary and herm_form.is_singular(): unitary = False # since a degenerated hermitian form doesn't define a unitary group if self._classical_invariant_form is None: - self._classical_invariant_form = herm_form + self._classical_invariant_form = herm_form if unitary: from sage.rings.finite_rings.finite_field_base import is_FiniteField @@ -1496,7 +1498,7 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' matrix_group = base_group.subgroup(gen_list) else: from sage.groups.matrix_gps.finitely_generated import MatrixGroup - matrix_group = MatrixGroup(gen_list) + matrix_group = MatrixGroup(gen_list, category=self.category()) # ------------------------------------------------------------------------------- # check if there is a well defined group homomorphism to matrix_group @@ -1505,7 +1507,7 @@ def as_matrix_group(self, root_bur=None, domain=None, characteristic=None, var=' # here. # ------------------------------------------------------------------------------- hom_to_mat = self.hom(matrix_group.gens(), check=False) - if not all( hom_to_mat(rel).is_one() for rel in self.relations()): + if not all(hom_to_mat(rel).is_one() for rel in self.relations()): raise ValueError("Burau representation does not factor through the relations") matrix_group.register_conversion(hom_to_mat) return matrix_group @@ -1539,7 +1541,6 @@ def as_permutation_group(self, use_classical=True): sage: C3 = CubicBraidGroup(3) sage: PC3 = C3.as_permutation_group() sage: C3.is_isomorphic(PC3) - #I Forcing finiteness test True sage: PC3.degree() 8 @@ -1937,7 +1938,6 @@ def is_finite(self): from sage.rings.infinity import infinity return not self.order() is infinity - # ---------------------------------------------------------------------------------- # creating a CubicBraidGroup as subgroup of self on less strands # ---------------------------------------------------------------------------------- diff --git a/src/sage/groups/matrix_gps/finitely_generated.py b/src/sage/groups/matrix_gps/finitely_generated.py index cef211ea07c..2a0f9580360 100644 --- a/src/sage/groups/matrix_gps/finitely_generated.py +++ b/src/sage/groups/matrix_gps/finitely_generated.py @@ -294,12 +294,15 @@ def MatrixGroup(*gens, **kwds): base_ring = MS.base_ring() degree = ZZ(MS.ncols()) # == MS.nrows() from sage.libs.gap.libgap import libgap + category = kwds.get('category', None) try: gap_gens = [libgap(matrix_gen) for matrix_gen in gens] gap_group = libgap.Group(gap_gens) - return FinitelyGeneratedMatrixGroup_gap(degree, base_ring, gap_group) + return FinitelyGeneratedMatrixGroup_gap(degree, base_ring, gap_group, + category=category) except (TypeError, ValueError): - return FinitelyGeneratedMatrixGroup_generic(degree, base_ring, gens) + return FinitelyGeneratedMatrixGroup_generic(degree, base_ring, gens, + category=category) ################################################################### # diff --git a/src/sage/groups/matrix_gps/matrix_group.py b/src/sage/groups/matrix_gps/matrix_group.py index e82abf76246..f2ce966c9ed 100644 --- a/src/sage/groups/matrix_gps/matrix_group.py +++ b/src/sage/groups/matrix_gps/matrix_group.py @@ -212,7 +212,24 @@ def subgroup(self, generators, check=True): sage: TestSuite(G).run() sage: TestSuite(S).run() + + sage: W = CoxeterGroup(['I',7]) + sage: s = W.simple_reflections() + sage: G = W.subgroup([s[1]]) + sage: G.category() + Category of finite groups + + sage: W = WeylGroup(['A',2]) + sage: s = W.simple_reflections() + sage: G = W.subgroup([s[1]]) + sage: G.category() + Category of finite groups """ + try: + test = self.is_finite() + except NotImplementedError: + test = self in Groups().Finite() + cat = Groups().Finite() if test else Groups() # this method enlarges the method with same name of # ParentLibGAP to cases where the ambient group is not # inherited from ParentLibGAP. @@ -224,7 +241,7 @@ def subgroup(self, generators, check=True): raise ValueError("generator %s is not in the group" % (g)) from sage.groups.matrix_gps.finitely_generated import MatrixGroup - subgroup = MatrixGroup(generators, check=check) + subgroup = MatrixGroup(generators, check=check, category=cat) subgroup._ambient = self return subgroup @@ -409,12 +426,11 @@ def __init__(self, degree, base_ring, category=None): if self._deg <= 0: raise ValueError('the degree must be at least 1') - if category is None: - category = Groups() + cat = Groups() if category is None else category if base_ring in Rings().Finite(): - category = category.Finite() + cat = cat.Finite() super(MatrixGroup_generic, self).__init__(base=base_ring, - category=category) + category=cat) def degree(self): """ @@ -759,8 +775,12 @@ def _subgroup_constructor(self, libgap_subgroup): sage: G.ambient() is SL2Z True """ + cat = Groups() + if self in Groups().Finite(): + cat = cat.Finite() from sage.groups.matrix_gps.finitely_generated import FinitelyGeneratedMatrixGroup_gap return FinitelyGeneratedMatrixGroup_gap(self.degree(), self.base_ring(), - libgap_subgroup, ambient=self) + libgap_subgroup, ambient=self, + category=cat) from sage.groups.generic import structure_description From a1095a39122b34a01959ac738832ee5a037205e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 7 Nov 2021 11:22:06 +0100 Subject: [PATCH 315/378] indent doctest --- src/sage/coding/databases.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sage/coding/databases.py b/src/sage/coding/databases.py index 87e0e41bb4e..2fe3a632e2d 100644 --- a/src/sage/coding/databases.py +++ b/src/sage/coding/databases.py @@ -83,7 +83,14 @@ def bounds_on_minimum_distance_in_guava(n, k, F): sage: gap_rec = codes.databases.bounds_on_minimum_distance_in_guava(10,5,GF(2)) # optional - gap_packages (Guava package) sage: gap_rec.Display() # optional - gap_packages (Guava package) rec( - construction := [ , [ [ , [ [ , [ [ , [ 8, 2 ] ] ] ], [ , [ [ , [ [ , [ 4, 2 ] ] ] ], [ , [ 4, 2 ] ] ] ] ] ], [ 1, 2, 3, 4, 5, 6 ] ] ], + construction := [ , + [ [ , + [ [ , + [ [ , [ 8, 2 ] ] ] ], + [ , [ [ , + [ [ , [ 4, 2 ] ] ] ], + [ , [ 4, 2 ] ] ] ] ] ], + [ 1, 2, 3, 4, 5, 6 ] ] ], k := 5, lowerBound := 4, lowerBoundExplanation := ... From 2704119820efc54ae4069ebeefb0ab74f91b0e08 Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 7 Nov 2021 17:50:32 +0100 Subject: [PATCH 316/378] Fix creating polynomial from strings in the case of field with several generators --- .../polynomial/multi_polynomial_libsingular.pyx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index ff7f4180f24..f2bdea65896 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -770,6 +770,16 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): sage: S(f) (2*abar)*y + Check that creating element from strings works for transcendental extensions:: + + sage: T. = QQ[] + sage: F = FractionField(T) + sage: R. = F[] + sage: R('d*z+x^2*y') + x^2*y + d*z + + + """ cdef poly *_p cdef poly *mon @@ -962,7 +972,11 @@ cdef class MPolynomialRing_libsingular(MPolynomialRing_base): # let python do the parsing d = self.gens_dict() if self.base_ring().gen() != 1: - d[str(self.base_ring().gen())]=self.base_ring().gen() + if hasattr(self.base_ring(), 'gens'): + for gen in self.base_ring().gens(): + d[str(gen)] = gen + else: + d[str(self.base_ring().gen())] = self.base_ring_gen() try: if '/' in element: element = sage_eval(element,d) From 84a04d125051e2c04e39ad7ed0d7db53cee9772d Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 7 Nov 2021 18:00:36 +0100 Subject: [PATCH 317/378] Fix variable indices in doctest --- .../non_symmetric_macdonald_polynomials.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py index 5d406c1dd44..482f7bb9215 100644 --- a/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py +++ b/src/sage/combinat/root_system/non_symmetric_macdonald_polynomials.py @@ -940,28 +940,28 @@ class NonSymmetricMacdonaldPolynomials(CherednikOperatorsEigenvectors): sage: E = NonSymmetricMacdonaldPolynomials(KL,q, t, -1) sage: L0 = E.keys() sage: omega = L0.fundamental_weights() - sage: P = K['x1,x2,x3'] + sage: P = K['x0,x1,x2'] sage: def EE(weight): return E[L0(weight)].expand(P.gens()) sage: EE([0,0,0]) 1 sage: EE([1,0,0]) - x1 + x0 sage: EE([0,1,0]) - (t - 1)/(q*t^2 - 1)*x1 + x2 + (t - 1)/(q*t^2 - 1)*x0 + x1 sage: EE([0,0,1]) - (t - 1)/(q*t - 1)*x1 + (t - 1)/(q*t - 1)*x2 + x3 + (t - 1)/(q*t - 1)*x0 + (t - 1)/(q*t - 1)*x1 + x2 sage: EE([1,1,0]) - x1*x2 + x0*x1 sage: EE([1,0,1]) - (t - 1)/(q*t^2 - 1)*x1*x2 + x1*x3 + (t - 1)/(q*t^2 - 1)*x0*x1 + x0*x2 sage: EE([0,1,1]) - (t - 1)/(q*t - 1)*x1*x2 + (t - 1)/(q*t - 1)*x1*x3 + x2*x3 + (t - 1)/(q*t - 1)*x0*x1 + (t - 1)/(q*t - 1)*x0*x2 + x1*x2 sage: EE([2,0,0]) - x1^2 + (q*t - q)/(q*t - 1)*x1*x2 + (q*t - q)/(q*t - 1)*x1*x3 + x0^2 + (q*t - q)/(q*t - 1)*x0*x1 + (q*t - q)/(q*t - 1)*x0*x2 sage: EE([0,2,0]) - (t - 1)/(q^2*t^2 - 1)*x1^2 + (q^2*t^3 - q^2*t^2 + q*t^2 - 2*q*t + q - t + 1)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x1*x2 + x2^2 + (q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x1*x3 + (q*t - q)/(q*t - 1)*x2*x3 + (t - 1)/(q^2*t^2 - 1)*x0^2 + (q^2*t^3 - q^2*t^2 + q*t^2 - 2*q*t + q - t + 1)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x0*x1 + x1^2 + (q*t^2 - 2*q*t + q)/(q^3*t^3 - q^2*t^2 - q*t + 1)*x0*x2 + (q*t - q)/(q*t - 1)*x1*x2 Systematic checks with Sage's implementation of [HHL06]_:: From d412c7745d70cb9bb7b40e56eafd3ebb73d3692b Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sun, 7 Nov 2021 18:42:42 +0100 Subject: [PATCH 318/378] Fix crash in .subs() --- src/sage/libs/singular/polynomial.pyx | 5 +++-- .../polynomial/multi_polynomial_libsingular.pyx | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/sage/libs/singular/polynomial.pyx b/src/sage/libs/singular/polynomial.pyx index eed1967ca9e..f6d244e79fa 100644 --- a/src/sage/libs/singular/polynomial.pyx +++ b/src/sage/libs/singular/polynomial.pyx @@ -621,6 +621,9 @@ cdef int singular_polynomial_subst(poly **p, int var_index, poly *value, ring *r - ``r`` - a ring """ + if r != currRing: + rChangeCurrRing(r) + if p_IsConstant(value, r): p[0] = pSubst(p[0], var_index+1, value) return 0 @@ -628,8 +631,6 @@ cdef int singular_polynomial_subst(poly **p, int var_index, poly *value, ring *r cdef unsigned long exp = p_GetExp(p[0], var_index+1, r) * p_GetMaxExp(value, r) overflow_check(exp, r) - if r != currRing: - rChangeCurrRing(r) cdef int count = singular_polynomial_length_bounded(p[0], 15) if unlikely(count >= 15 or exp > 15): sig_on() diff --git a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx index f2bdea65896..5d34e62d04c 100644 --- a/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx +++ b/src/sage/rings/polynomial/multi_polynomial_libsingular.pyx @@ -3519,6 +3519,19 @@ cdef class MPolynomial_libsingular(MPolynomial): ....: assert y.subs(d) == y.subs(**ds) == vy ....: assert z.subs(d) == z.subs(**ds) == vz ....: assert (x+y).subs(d) == (x+y).subs(**ds) == vx+vy + + Check that substitution doesn't crash in transcendental extensions:: + + sage: F = PolynomialRing(QQ,'c,d').fraction_field() + sage: F.inject_variables() + Defining c, d + sage: R. = F[] + sage: f = R(d*z^2 + c*y*z^2) + sage: f.subs({x:z^2,y:1}) + (c + d)*z^2 + sage: f.subs({z:x+1}) + c*x^2*y + d*x^2 + (2*c)*x*y + (2*d)*x + c*y + d + """ cdef int mi, i, need_map, try_symbolic From 48b79271d3b1b2566e55cb6efa5e7184e1fe14cb Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 7 Nov 2021 11:52:45 -0800 Subject: [PATCH 319/378] build/bin/sage-bootstrap-python: Prefer a Python that provides ssl with SNI --- build/bin/sage-bootstrap-python | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/build/bin/sage-bootstrap-python b/build/bin/sage-bootstrap-python index faee444e8dc..5c5cd1cc097 100755 --- a/build/bin/sage-bootstrap-python +++ b/build/bin/sage-bootstrap-python @@ -40,7 +40,19 @@ if [ "$LC_ALL" = "C" -o "$LANG" = "C" -o "$LC_CTYPE" = "C" ]; then export LANG fi -PYTHONS="python python3 python3.8 python3.7 python2.7 python3.6 python2" +PYTHONS="python python3 python3.10 python3.9 python3.8 python3.7 python2.7 python3.6 python2" +# Trac #32405: Prefer a Python that provides ssl with SNI, which allows developers +# to download from upstream URLs (configure --enable-download-from-upstream-url), +# in particular from PyPI, which requires SNI. +for PY in $PYTHONS; do + PYTHON="$(PATH="$SAGE_ORIG_PATH" command -v $PY)" + if [ -n "$PYTHON" ]; then + if "$PYTHON" -c "import argparse; import urllib; from hashlib import sha1; from ssl import HAS_SNI; assert HAS_SNI; from os import listdir; listdir(\"$(pwd)\");" 2>/dev/null; then + exec "$PYTHON" "$@" + fi + fi +done +# Second round, no ssl/SNI test. for PY in $PYTHONS; do PYTHON="$(PATH="$SAGE_ORIG_PATH" command -v $PY)" if [ -n "$PYTHON" ]; then From 5871cabb741cafd01023e08d7cc1f3e95f60884a Mon Sep 17 00:00:00 2001 From: dcoudert Date: Sun, 7 Nov 2021 21:09:31 +0100 Subject: [PATCH 320/378] trac #32831: fix doctest in src/sage/combinat/crystals/induced_structure.py --- src/sage/combinat/crystals/induced_structure.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/combinat/crystals/induced_structure.py b/src/sage/combinat/crystals/induced_structure.py index ec01e07b651..0cf36648bba 100644 --- a/src/sage/combinat/crystals/induced_structure.py +++ b/src/sage/combinat/crystals/induced_structure.py @@ -89,7 +89,7 @@ class InducedCrystal(UniqueRepresentation, Parent): True sage: I = crystals.Induced(P, phi, phi_inv) sage: I.digraph() - Multi-digraph on 24 vertices + Digraph on 24 vertices We construct an example without a specified inverse map:: From b7d2be9dad402978af44d657fa1c75139c6c0fa3 Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 8 Nov 2021 10:27:45 +0900 Subject: [PATCH 321/378] More refactoring of __init__ files --- src/doc/en/reference/combinat/module_list.rst | 4 +- src/sage/categories/all.py | 2 + src/sage/combinat/all.py | 4 +- src/sage/combinat/crystals/all.py | 2 +- src/sage/combinat/root_system/all.py | 12 ++--- src/sage/combinat/words/__init__.py | 40 +++++++++++++++++ src/sage/combinat/words/all.py | 45 ------------------- src/sage/dynamics/__init__.py | 3 -- src/sage/dynamics/all.py | 6 +++ src/sage/matroids/all.py | 7 +++ 10 files changed, 67 insertions(+), 58 deletions(-) diff --git a/src/doc/en/reference/combinat/module_list.rst b/src/doc/en/reference/combinat/module_list.rst index 1807a13c9b3..d1da854a364 100644 --- a/src/doc/en/reference/combinat/module_list.rst +++ b/src/doc/en/reference/combinat/module_list.rst @@ -1,4 +1,4 @@ -Comprehensive Module list +Comprehensive Module List ========================= .. NOTE:: @@ -364,7 +364,7 @@ Comprehensive Module list sage/combinat/tutorial sage/combinat/vector_partition sage/combinat/words/abstract_word - sage/combinat/words/all + sage/combinat/words sage/combinat/words/alphabet sage/combinat/words/finite_word sage/combinat/words/infinite_word diff --git a/src/sage/categories/all.py b/src/sage/categories/all.py index cc38c442873..f7a1c3620c2 100644 --- a/src/sage/categories/all.py +++ b/src/sage/categories/all.py @@ -27,6 +27,8 @@ from sage.misc.namespace_package import install_doc install_doc(__package__, __doc__) +from . import primer + from sage.misc.lazy_import import lazy_import from .category import Category diff --git a/src/sage/combinat/all.py b/src/sage/combinat/all.py index 1f0997be887..729aa6cab95 100644 --- a/src/sage/combinat/all.py +++ b/src/sage/combinat/all.py @@ -26,7 +26,7 @@ - :ref:`sage.combinat.species.all` - :ref:`sage.combinat.designs.all` - :ref:`sage.combinat.posets.all` -- :ref:`sage.combinat.words.all` +- :ref:`sage.combinat.words` Utilities --------- @@ -48,6 +48,8 @@ from sage.misc.namespace_package import install_doc install_doc(__package__, __doc__) +from . import quickref, tutorial + from sage.misc.lazy_import import lazy_import from .combinat import bell_number, catalan_number, euler_number, fibonacci, \ diff --git a/src/sage/combinat/crystals/all.py b/src/sage/combinat/crystals/all.py index 67730a507a1..23955e34465 100644 --- a/src/sage/combinat/crystals/all.py +++ b/src/sage/combinat/crystals/all.py @@ -19,7 +19,7 @@ :class:`FiniteCrystals`, :class:`ClassicalCrystals`, :class:`RegularCrystals`, :class:`~sage.categories.regular_supercrystals.RegularSuperCrystals` -- The categories for crystals -- :ref:`sage.combinat.root_system` +- :ref:`sage.combinat.root_system.all` """ # install the docstring of this module to the containing package from sage.misc.namespace_package import install_doc diff --git a/src/sage/combinat/root_system/all.py b/src/sage/combinat/root_system/all.py index d9008e6550c..622eb87b309 100644 --- a/src/sage/combinat/root_system/all.py +++ b/src/sage/combinat/root_system/all.py @@ -14,7 +14,7 @@ Introductory material --------------------- -- :ref:`sage.combinat.root_system` -- This overview +- :ref:`sage.combinat.root_system.all` -- This overview - :class:`CartanType` -- An introduction to Cartan types - :class:`RootSystem` -- An introduction to root systems - :ref:`sage.combinat.root_system.plot` -- A root system visualization tutorial @@ -25,7 +25,7 @@ Related material ---------------- -- :ref:`sage.combinat.crystals` -- Crystals +- :ref:`sage.combinat.crystals.all` -- Crystals Cartan datum ------------ @@ -39,7 +39,7 @@ Root systems ------------ -- :ref:`sage.combinat.root_system.root_system` +- :ref:`sage.combinat.root_system.all` - :ref:`sage.combinat.root_system.plot` - :ref:`sage.combinat.root_system.root_lattice_realizations` - :ref:`sage.combinat.root_system.root_lattice_realization_algebras` @@ -115,6 +115,9 @@ - :ref:`sage.combinat.root_system.type_super_A` - :ref:`sage.combinat.root_system.type_A_infinity` """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) from sage.misc.lazy_import import lazy_import @@ -139,6 +142,3 @@ lazy_import('sage.combinat.root_system.non_symmetric_macdonald_polynomials', 'NonSymmetricMacdonaldPolynomials') lazy_import('sage.combinat.root_system.integrable_representations', 'IntegrableRepresentation') -# install the docstring of this module to the containing package -from sage.misc.namespace_package import install_doc -install_doc(__package__, __doc__) diff --git a/src/sage/combinat/words/__init__.py b/src/sage/combinat/words/__init__.py index 8b137891791..4dc6dd45dba 100644 --- a/src/sage/combinat/words/__init__.py +++ b/src/sage/combinat/words/__init__.py @@ -1 +1,41 @@ +r""" +Combinatorics on words +**Main modules and their methods:** + +- :ref:`sage.combinat.words.abstract_word` +- :ref:`sage.combinat.words.finite_word` +- :ref:`sage.combinat.words.infinite_word` +- :ref:`sage.combinat.words.alphabet` +- :ref:`sage.combinat.words.words` +- :ref:`sage.combinat.words.paths` +- :ref:`sage.combinat.words.morphism` +- :ref:`sage.combinat.words.shuffle_product` +- :ref:`sage.combinat.words.suffix_trees` + +Main classes and functions meant to be used by the user: + + :func:`~sage.combinat.words.word.Word`, + :class:`~sage.combinat.words.words.FiniteWords`, + :class:`~sage.combinat.words.words.InfiniteWords`, + :func:`~sage.combinat.words.words.Words`, + :func:`~sage.combinat.words.alphabet.Alphabet`, + :class:`~sage.combinat.words.morphism.WordMorphism`, + :class:`~sage.combinat.words.paths.WordPaths`. + +A list of common words can be accessed through ``words.`` and are listed in +the :ref:`words catalog `. + +**Internal representation of words:** + +- :ref:`sage.combinat.words.word` +- :ref:`sage.combinat.words.word_char` +- :ref:`sage.combinat.words.word_datatypes` +- :ref:`sage.combinat.words.word_infinite_datatypes` + +**Options:** + +- :ref:`sage.combinat.words.word_options` + +See :func:`~sage.combinat.words.word_options.WordOptions`. +""" diff --git a/src/sage/combinat/words/all.py b/src/sage/combinat/words/all.py index 687b572c8e5..078ca4e48ab 100644 --- a/src/sage/combinat/words/all.py +++ b/src/sage/combinat/words/all.py @@ -1,48 +1,3 @@ -r""" -Combinatorics on words - -**Main modules and their methods:** - -- :ref:`sage.combinat.words.abstract_word` -- :ref:`sage.combinat.words.finite_word` -- :ref:`sage.combinat.words.infinite_word` -- :ref:`sage.combinat.words.alphabet` -- :ref:`sage.combinat.words.words` -- :ref:`sage.combinat.words.paths` -- :ref:`sage.combinat.words.morphism` -- :ref:`sage.combinat.words.shuffle_product` -- :ref:`sage.combinat.words.suffix_trees` - -Main classes and functions meant to be used by the user: - - :func:`~sage.combinat.words.word.Word`, - :class:`~sage.combinat.words.words.FiniteWords`, - :class:`~sage.combinat.words.words.InfiniteWords`, - :func:`~sage.combinat.words.words.Words`, - :func:`~sage.combinat.words.alphabet.Alphabet`, - :class:`~sage.combinat.words.morphism.WordMorphism`, - :class:`~sage.combinat.words.paths.WordPaths`. - -A list of common words can be accessed through ``words.`` and are listed in -the :ref:`words catalog `. - -**Internal representation of words:** - -- :ref:`sage.combinat.words.word` -- :ref:`sage.combinat.words.word_char` -- :ref:`sage.combinat.words.word_datatypes` -- :ref:`sage.combinat.words.word_infinite_datatypes` - -**Options:** - -- :ref:`sage.combinat.words.word_options` - -See :func:`~sage.combinat.words.word_options.WordOptions`. -""" -# install the docstring of this module to the containing package -from sage.misc.namespace_package import install_doc -install_doc(__package__, __doc__) - from .alphabet import Alphabet, build_alphabet from .morphism import WordMorphism from .paths import WordPaths diff --git a/src/sage/dynamics/__init__.py b/src/sage/dynamics/__init__.py index dd754fe4154..e69de29bb2d 100644 --- a/src/sage/dynamics/__init__.py +++ b/src/sage/dynamics/__init__.py @@ -1,3 +0,0 @@ -r""" -Flat surfaces -""" diff --git a/src/sage/dynamics/all.py b/src/sage/dynamics/all.py index 3751de55e67..e5c553a3d54 100644 --- a/src/sage/dynamics/all.py +++ b/src/sage/dynamics/all.py @@ -1,4 +1,6 @@ """ +Flat surfaces + Some code about flat surfaces and interval exchanges has been removed from Sage. The package ``surface_dynamics`` contains all that code and much more. For more information, see @@ -14,6 +16,10 @@ sage -pip install surface_dynamics --user """ +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import from sage.dynamics.arithmetic_dynamics.all import * diff --git a/src/sage/matroids/all.py b/src/sage/matroids/all.py index 27576e6889e..e647629c988 100644 --- a/src/sage/matroids/all.py +++ b/src/sage/matroids/all.py @@ -1,3 +1,10 @@ +""" +Matroids +""" +# install the docstring of this module to the containing package +from sage.misc.namespace_package import install_doc +install_doc(__package__, __doc__) + from sage.misc.lazy_import import lazy_import # from constructor import Matroid # import matroids_catalog as matroids From ee4367df90299b3a77e944c5b8daaaae91c40c1c Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Mon, 8 Nov 2021 13:13:03 +0900 Subject: [PATCH 322/378] Fixes for doctest failures --- src/sage/combinat/crystals/crystals.py | 2 +- src/sage/combinat/quickref.py | 6 +++--- src/sage/combinat/root_system/root_system.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sage/combinat/crystals/crystals.py b/src/sage/combinat/crystals/crystals.py index f31a3ac0811..b7288753fba 100644 --- a/src/sage/combinat/crystals/crystals.py +++ b/src/sage/combinat/crystals/crystals.py @@ -121,7 +121,7 @@ For rank two crystals, there is an alternative method of getting metapost pictures. For more information see ``C.metapost?``. -.. SEEALSO:: :ref:`The overview of crystal features in Sage` +.. SEEALSO:: :ref:`The overview of crystal features in Sage` .. TODO:: diff --git a/src/sage/combinat/quickref.py b/src/sage/combinat/quickref.py index f55089e5a28..ea2aba8915a 100644 --- a/src/sage/combinat/quickref.py +++ b/src/sage/combinat/quickref.py @@ -48,13 +48,13 @@ sage: L = LatticePolytope(points) sage: L.npoints(); L.plot3d() # random -:ref:`Root systems, Coxeter and Weyl groups `:: +:ref:`Root systems, Coxeter and Weyl groups `:: sage: WeylGroup(["B",3]).bruhat_poset() Finite poset containing 48 elements sage: RootSystem(["A",2,1]).weight_lattice().plot() # not tested -:ref:`Crystals `:: +:ref:`Crystals `:: sage: CrystalOfTableaux(["A",3], shape = [3,2]).some_flashy_feature() # not tested @@ -71,7 +71,7 @@ sage: M.an_element() * S.an_element() x0 -Graph theory, posets, lattices (:ref:`sage.graphs`, :ref:`sage.combinat.posets`):: +Graph theory, posets, lattices (:ref:`sage.graphs`, :ref:`sage.combinat.posets.all`):: sage: Poset({1: [2,3], 2: [4], 3: [4]}).linear_extensions().cardinality() 2 diff --git a/src/sage/combinat/root_system/root_system.py b/src/sage/combinat/root_system/root_system.py index 9285d9b958b..a10c57e5cf6 100644 --- a/src/sage/combinat/root_system/root_system.py +++ b/src/sage/combinat/root_system/root_system.py @@ -2,7 +2,7 @@ Root systems ============ -See :ref:`sage.combinat.root_system` for an overview. +See :ref:`sage.combinat.root_system.all` for an overview. """ #***************************************************************************** # Copyright (C) 2007 Mike Hansen , From d410caa35701cc6093739f85dcce31c47911f7e2 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Mon, 8 Nov 2021 16:28:35 +0100 Subject: [PATCH 323/378] trac #30566: cleaner use of weights --- src/sage/graphs/spanning_tree.pyx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index f50dea6b086..9cad7642635 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -796,7 +796,7 @@ cpdef boruvka(G, wfunction=None, bint check=False, bint by_weight=True): return T -def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_function=None): +def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_function=None, check_weight=True): r""" Return a random spanning tree of the graph. @@ -829,6 +829,9 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct transform the label into a weight (note that, if the weight returned is not convertible to a float, an error is raised) + - ``check_weight`` -- boolean (default: ``True``); whether to check that + the ``weight_function`` outputs a number for each edge. + .. SEEALSO:: :meth:`~sage.graphs.generic_graph.GenericGraph.spanning_trees_count` @@ -911,14 +914,11 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct return G.copy() return list(G.edge_iterator(label=False)) - if weight_function is not None: - by_weight = True + by_weight, weight_function = G._get_weight_function(by_weight=by_weight, + weight_function=weight_function, + check_weight=check_weight) if by_weight: - if weight_function is None: - def weight_function(e): - return 1 if e[2] is None else e[2] - def next_neighbor(s): p = random() * sum(weight_function(e) for e in G.edge_iterator(s, sort_vertices=False)) @@ -927,7 +927,6 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct if p <= 0: break return e[1] if e[0] == s else e[0] - else: def next_neighbor(s): return G.neighbors(s)[randint(0, G.degree(s) - 1)] From 8e26780afcbe40662f27b96b7dbd563843d08452 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 16:54:52 -0700 Subject: [PATCH 324/378] build/pkgs/sagemath_doc_{html,pdf}: New; delegate to them from targets doc-html etc. --- build/make/Makefile.in | 38 ++++++++++++----------- build/pkgs/sagemath_doc_html/dependencies | 5 +++ build/pkgs/sagemath_doc_html/spkg-install | 3 ++ build/pkgs/sagemath_doc_html/trees.txt | 1 + build/pkgs/sagemath_doc_html/type | 1 + build/pkgs/sagemath_doc_pdf/dependencies | 1 + build/pkgs/sagemath_doc_pdf/spkg-install | 3 ++ build/pkgs/sagemath_doc_pdf/trees.txt | 1 + build/pkgs/sagemath_doc_pdf/type | 1 + 9 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 build/pkgs/sagemath_doc_html/dependencies create mode 100755 build/pkgs/sagemath_doc_html/spkg-install create mode 100644 build/pkgs/sagemath_doc_html/trees.txt create mode 100644 build/pkgs/sagemath_doc_html/type create mode 120000 build/pkgs/sagemath_doc_pdf/dependencies create mode 100755 build/pkgs/sagemath_doc_pdf/spkg-install create mode 100644 build/pkgs/sagemath_doc_pdf/trees.txt create mode 100644 build/pkgs/sagemath_doc_pdf/type diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 1972e1a14ce..241bfae009a 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -52,6 +52,10 @@ SAGE_SPKG = sage-spkg # These are added to SAGE_SPKG in the call SAGE_SPKG_OPTIONS = @SAGE_SPKG_OPTIONS@ +# Where the Sage distribution installs documentation. +# set to empty if --disable-doc is used +SAGE_DOCS = $(SAGE_LOCAL) + # Where the Sage distribution installs Python packages. # This can be overridden by 'make SAGE_VENV=/some/venv'. SAGE_VENV = @SAGE_VENV@ @@ -142,7 +146,7 @@ SCRIPT_PACKAGES = @SAGE_SCRIPT_PACKAGES@ # inst_git = $(INST)/.dummy $(foreach pkgname,$(BUILT_PACKAGES),\ - $(eval inst_$(pkgname) = $(foreach tree, $(trees_$(pkgname)), $($(tree))/$(SPKG_INST_RELDIR)/$(pkgname)-$(vers_$(pkgname))))) + $(eval inst_$(pkgname) = $(foreach tree, $(trees_$(pkgname)), $(and $($(tree)), $($(tree))/$(SPKG_INST_RELDIR)/$(pkgname)-$(vers_$(pkgname)))))) $(foreach pkgname,$(DUMMY_PACKAGES),\ $(eval inst_$(pkgname) = $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/.dummy)) @@ -157,7 +161,7 @@ $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/.dummy: # Filtered by installation tree -$(foreach tree,SAGE_LOCAL SAGE_VENV, \ +$(foreach tree,SAGE_LOCAL SAGE_VENV SAGE_DOC_PREFIX, \ $(eval $(tree)_INSTALLED_PACKAGE_INSTS = \ $(foreach pkgname,$(INSTALLED_PACKAGES), \ $(if $(findstring $(tree),$(trees_$(pkgname))), \ @@ -245,6 +249,11 @@ all-build-venv: toolchain-deps all-sage-venv: $(SAGE_VENV_INSTALLED_PACKAGE_INSTS) $(SAGE_VENV_UNINSTALLED_PACKAGES_CLEANS) +all-build-docs: toolchain-deps + +$(MAKE_REC) all-sage-docs + +all-sage-docs: $(SAGE_DOCS_INSTALLED_PACKAGE_INSTS) $(SAGE_DOCS_UNINSTALLED_PACKAGES_CLEANS) + # Download all packages which should be inside an sdist tarball (the -B # option to make forces all targets to be built unconditionally) download-for-sdist: @@ -316,35 +325,28 @@ base: $(inst_patch) $(inst_pkgconf) # # $ ./sage --docbuild -H -# Building the documentation has many dependencies, because all -# documented modules are imported and because we use matplotlib to -# produce plots. -DOC_DEPENDENCIES = sagelib sage_docbuild $(inst_sphinx) \ - | $(SAGERUNTIME) $(inst_maxima) $(inst_networkx) $(inst_scipy) $(inst_sympy) \ - $(inst_matplotlib) $(inst_pillow) $(inst_mathjax) $(inst_mpmath) \ - $(inst_ipykernel) $(inst_jupyter_client) $(inst_conway_polynomials) \ - $(inst_tachyon) $(inst_jmol) $(inst_thebe) $(inst_ipywidgets) - -doc: doc-html +doc: $(SAGE_DOCS_INSTALLED_PACKAGE_INSTS) $(SAGE_DOCS_UNINSTALLED_PACKAGES_CLEANS) -doc-html: $(DOC_DEPENDENCIES) - $(AM_V_at)cd "$(SAGE_SRC)/doc" && sage-logger -p "$(MAKE) doc-html" $(SAGE_ROOT)/logs/dochtml.log +# All doc-building is delegated to the script packages +# sagemath_doc_html, sagemath_doc_pdf +doc-html: sagemath_doc_html # 'doc-html-no-plot': build docs without building the graphics coming # from the '.. plot' directive, in case you want to save a few # megabytes of disk space. 'doc-clean' is a prerequisite because the # presence of graphics is cached in src/doc/output. doc-html-no-plot: doc-clean - $(AM_V_at)sage-logger -p "$(MAKE) SAGE_DOCBUILD_OPTS=\"$(SAGE_DOCBUILD_OPTS) --no-plot\" doc-html" $(SAGE_ROOT)/logs/dochtml.log + +$(MAKE_REC) SAGE_SKIP_PLOT_DIRECTIVE=yes doc-html +# Using mathjax is actually the default, but this target can be used +# to override an environment setting of SAGE_DOC_MATHJAX=no doc-html-mathjax: - $(AM_V_at)sage-logger -p "$(MAKE) SAGE_DOCBUILD_OPTS=\"$(SAGE_DOCBUILD_OPTS) -j\" doc-html" $(SAGE_ROOT)/logs/dochtml.log + +$(MAKE_REC) SAGE_DOC_MATHJAX=yes doc-html # Keep target 'doc-html-jsmath' for backwards compatibility. doc-html-jsmath: doc-html-mathjax -doc-pdf: $(DOC_DEPENDENCIES) - $(AM_V_at)cd "$(SAGE_SRC)/doc" && sage-logger -p "$(MAKE) doc-pdf" $(SAGE_ROOT)/logs/docpdf.log +doc-pdf: sagemath_doc_pdf doc-clean: doc-src-clean doc-output-clean diff --git a/build/pkgs/sagemath_doc_html/dependencies b/build/pkgs/sagemath_doc_html/dependencies new file mode 100644 index 00000000000..8d37b42880c --- /dev/null +++ b/build/pkgs/sagemath_doc_html/dependencies @@ -0,0 +1,5 @@ +sagelib sphinx | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol thebe ipywidgets + +# Building the documentation has many dependencies, because all +# documented modules are imported and because we use matplotlib to +# produce plots. diff --git a/build/pkgs/sagemath_doc_html/spkg-install b/build/pkgs/sagemath_doc_html/spkg-install new file mode 100755 index 00000000000..801aa7769fe --- /dev/null +++ b/build/pkgs/sagemath_doc_html/spkg-install @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +cd $SAGE_ROOT/src/doc +$MAKE doc-html diff --git a/build/pkgs/sagemath_doc_html/trees.txt b/build/pkgs/sagemath_doc_html/trees.txt new file mode 100644 index 00000000000..77be9495f24 --- /dev/null +++ b/build/pkgs/sagemath_doc_html/trees.txt @@ -0,0 +1 @@ +SAGE_DOCS diff --git a/build/pkgs/sagemath_doc_html/type b/build/pkgs/sagemath_doc_html/type new file mode 100644 index 00000000000..a6a7b9cd726 --- /dev/null +++ b/build/pkgs/sagemath_doc_html/type @@ -0,0 +1 @@ +standard diff --git a/build/pkgs/sagemath_doc_pdf/dependencies b/build/pkgs/sagemath_doc_pdf/dependencies new file mode 120000 index 00000000000..5bad6e468d6 --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/dependencies @@ -0,0 +1 @@ +../sagemath_doc_html/dependencies \ No newline at end of file diff --git a/build/pkgs/sagemath_doc_pdf/spkg-install b/build/pkgs/sagemath_doc_pdf/spkg-install new file mode 100755 index 00000000000..f04f4b75d9a --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/spkg-install @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +cd $SAGE_ROOT/src/doc +$MAKE doc-pdf diff --git a/build/pkgs/sagemath_doc_pdf/trees.txt b/build/pkgs/sagemath_doc_pdf/trees.txt new file mode 100644 index 00000000000..77be9495f24 --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/trees.txt @@ -0,0 +1 @@ +SAGE_DOCS diff --git a/build/pkgs/sagemath_doc_pdf/type b/build/pkgs/sagemath_doc_pdf/type new file mode 100644 index 00000000000..134d9bc32d5 --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/type @@ -0,0 +1 @@ +optional From eeb8777b0c31bbf15f0d97171c3eccce119cffac Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 29 Oct 2021 21:18:55 -0700 Subject: [PATCH 325/378] m4/sage_spkg_collect.m4: Determine install tree for python3 via new trees.txt mechanism --- build/pkgs/python3/trees.txt | 1 + m4/sage_spkg_collect.m4 | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 build/pkgs/python3/trees.txt diff --git a/build/pkgs/python3/trees.txt b/build/pkgs/python3/trees.txt new file mode 100644 index 00000000000..f01330b2fe5 --- /dev/null +++ b/build/pkgs/python3/trees.txt @@ -0,0 +1 @@ +SAGE_VENV diff --git a/m4/sage_spkg_collect.m4 b/m4/sage_spkg_collect.m4 index e6dcecdd24c..90f10986f78 100644 --- a/m4/sage_spkg_collect.m4 +++ b/m4/sage_spkg_collect.m4 @@ -181,10 +181,14 @@ for DIR in $SAGE_ROOT/build/pkgs/*; do dnl trees. For example, if we decide to create a separate tree for a venv with the dnl Jupyter notebook, then packages such as jupyter_core would have to be installed into dnl two trees. - SPKG_TREE_VAR=SAGE_LOCAL - if test -f "$DIR/requirements.txt" -o -f "$DIR/install-requires.txt" -o "$SPKG_NAME" = python3; then - dnl A Python package or spkg installation of python3 itself - SPKG_TREE_VAR=SAGE_VENV + if test -f "$DIR/trees.txt"; then + SPKG_TREE_VAR="$(sed "s/#.*//;" "$DIR/trees.txt")" + else + SPKG_TREE_VAR=SAGE_LOCAL + if test -f "$DIR/requirements.txt" -o -f "$DIR/install-requires.txt"; then + dnl A Python package + SPKG_TREE_VAR=SAGE_VENV + fi fi SAGE_PACKAGE_TREES="${SAGE_PACKAGE_TREES}$(printf '\ntrees_')${SPKG_NAME} = ${SPKG_TREE_VAR}" From c8e19a07dd6039be28f17e67e9fd2e693f14a52b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 8 Nov 2021 16:26:47 -0800 Subject: [PATCH 326/378] fixup --- build/make/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 241bfae009a..94e307a40fe 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -161,7 +161,7 @@ $(SAGE_LOCAL)/$(SPKG_INST_RELDIR)/.dummy: # Filtered by installation tree -$(foreach tree,SAGE_LOCAL SAGE_VENV SAGE_DOC_PREFIX, \ +$(foreach tree,SAGE_LOCAL SAGE_VENV SAGE_DOCS, \ $(eval $(tree)_INSTALLED_PACKAGE_INSTS = \ $(foreach pkgname,$(INSTALLED_PACKAGES), \ $(if $(findstring $(tree),$(trees_$(pkgname))), \ From 5a4424b3fa0c546bc05aef5320429749f1b143e9 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 8 Nov 2021 17:24:43 -0800 Subject: [PATCH 327/378] build/make/Makefile.in (all-sage): Do not include packages installed in SAGE_DOCS --- build/make/Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 94e307a40fe..4b9abbbcdb5 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -232,11 +232,11 @@ build-start: all-build base-toolchain: _clean-broken-gcc base +$(MAKE_REC) toolchain -# All targets except for the base packages +# All targets except for the base packages and except the documentation all-sage: \ sagelib \ - $(INSTALLED_PACKAGE_INSTS) \ - $(UNINSTALLED_PACKAGES_CLEANS) + $(SAGE_LOCAL_INSTALLED_PACKAGE_INSTS) $(SAGE_LOCAL_UNINSTALLED_PACKAGES_CLEANS) \ + $(SAGE_VENV_INSTALLED_PACKAGE_INSTS) $(SAGE_VENV_UNINSTALLED_PACKAGES_CLEANS) # Same but filtered by installation trees: all-build-local: toolchain-deps From 10f0aaeb89df624c5a0b1a5cbbe7d2d71cfb766d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 8 Nov 2021 20:56:13 -0800 Subject: [PATCH 328/378] src/sage/combinat/root_system/__init__.py: Remove imports that ensured register_unpickle_override calls are run on startup --- src/sage/combinat/root_system/__init__.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/sage/combinat/root_system/__init__.py b/src/sage/combinat/root_system/__init__.py index bc24bff5c96..e69de29bb2d 100644 --- a/src/sage/combinat/root_system/__init__.py +++ b/src/sage/combinat/root_system/__init__.py @@ -1,9 +0,0 @@ -# currently needed to activate the backward compatibility -# register_unpickle_override -from . import type_A -from . import type_B -from . import type_C -from . import type_D -from . import type_E -from . import type_F -from . import type_G From 0496bdaab2de3b36af013fa47c7f12195e6a5eff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 8 Nov 2021 21:03:30 -0800 Subject: [PATCH 329/378] sage.misc.persist.unpickle_global: Check unpickle_override again after importing --- src/sage/misc/persist.pyx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/sage/misc/persist.pyx b/src/sage/misc/persist.pyx index e19dba5db83..2a3a61fdce0 100644 --- a/src/sage/misc/persist.pyx +++ b/src/sage/misc/persist.pyx @@ -562,6 +562,14 @@ def unpickle_global(module, name): ImportError: cannot import some_old_class from sage.some_old_module, call register_unpickle_override('sage.some_old_module', 'some_old_class', ...) to fix this + + TESTS: + + Test that :func:`register_unpickle_override` calls in lazily imported modules + are respected:: + + sage: unpickle_global('sage.combinat.root_system.type_A', 'ambient_space') + """ unpickler = unpickle_override.get((module, name)) if unpickler is not None: @@ -582,6 +590,12 @@ def unpickle_global(module, name): __import__(module) except ImportError: error() + + # Importing the module may have run register_unpickle_override. + unpickler = unpickle_override.get((module, name)) + if unpickler is not None: + return unpickler[0] + mod = sys.modules[module] return getattr(mod, name) From cb7874121095397431952b039fb10a03c538b734 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 8 Nov 2021 21:59:55 -0800 Subject: [PATCH 330/378] src/doc/en/developer/packaging.rst: Exlpain trees.txt --- src/doc/en/developer/packaging.rst | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 498825377c5..9bdab77e80d 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -171,7 +171,8 @@ The following are some additional files which can be added: | `-- baz.patch |-- spkg-check.in |-- spkg-configure.m4 - `-- spkg-src + |-- spkg-src + `-- trees.txt We discuss the individual files in the following sections. @@ -717,6 +718,28 @@ packages and optional packages should only depend on standard or optional packages. +.. _section-dependencies: + +Where packages are installed +---------------------------- + +The Sage distribution has the notion of several installation trees. + +- ``$SAGE_VENV`` is the default installation tree for all Python packages, i.e., + normal packages with an ``install-requires.txt`` and pip packages + with a ``requirements.txt``. + +- ``$SAGE_LOCAL`` is the default installation tree for all non-Python packages. + +- ``$SAGE_DOCS`` (only set at build time) is an installation tree for the + HTML and PDF documentation. + +By placing a file ``trees.txt`` in the package directory, the installation tree +can be overridden. For example, ``build/pkgs/python3/trees.txt`` contains the +word ``SAGE_VENV``, and ``build/pkgs/sagemath_doc_html/trees.txt`` contains the +word ``SAGE_DOCS``. + + .. _section-spkg-patching: Patching Sources From 9e8aa5c51838aabac16368da91404aa76c37ca68 Mon Sep 17 00:00:00 2001 From: sheerluck Date: Mon, 8 Nov 2021 13:20:01 +0300 Subject: [PATCH 331/378] tox.ini: Add gentoo-python3.10 --- .github/workflows/tox-experimental.yml | 2 +- .github/workflows/tox-optional.yml | 2 +- .github/workflows/tox.yml | 2 +- tox.ini | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tox-experimental.yml b/.github/workflows/tox-experimental.yml index 554a058cdb9..54c8373a362 100644 --- a/.github/workflows/tox-experimental.yml +++ b/.github/workflows/tox-experimental.yml @@ -41,7 +41,7 @@ jobs: # This list is different from the one in tox.yml: # Trac #31526 switches gcc 4.x-based distributions to using the gcc_spkg configuration factor # Trac #32281 removes gcc 4.x-based distributions whose binutils are unusable - tox_system_factor: [ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, debian-jessie-gcc_spkg, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, centos-7-gcc_spkg, centos-8, gentoo, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386-gcc_spkg] + tox_system_factor: [ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, debian-jessie-gcc_spkg, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, centos-7-gcc_spkg, centos-8, gentoo-python3.9, gentoo-python3.10, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386-gcc_spkg] tox_packages_factor: [maximal] targets_pattern: [0-g, h-o, p, q-z] env: diff --git a/.github/workflows/tox-optional.yml b/.github/workflows/tox-optional.yml index be97ecd37a8..bcdf349bee7 100644 --- a/.github/workflows/tox-optional.yml +++ b/.github/workflows/tox-optional.yml @@ -41,7 +41,7 @@ jobs: # This list is different from the one in tox.yml: # Trac #31526 switches gcc 4.x-based distributions to using the gcc_spkg configuration factor # Trac #32281 removes gcc 4.x-based distributions whose binutils are unusable - tox_system_factor: [ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, debian-jessie-gcc_spkg, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, centos-7-gcc_spkg, centos-8, gentoo, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386-gcc_spkg] + tox_system_factor: [ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, debian-jessie-gcc_spkg, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, centos-7-gcc_spkg, centos-8, gentoo-python3.9, gentoo-python3.10, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386-gcc_spkg] tox_packages_factor: [maximal] targets_pattern: [0-g, h-o, p, q-z] env: diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 68d5661c5bb..493e8342920 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -38,7 +38,7 @@ jobs: fail-fast: false max-parallel: 20 matrix: - tox_system_factor: [ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, ubuntu-impish, debian-jessie, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, linuxmint-20.2, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, fedora-35, centos-7, centos-8, gentoo, gentoo-python3.7, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386] + tox_system_factor: [ubuntu-trusty, ubuntu-xenial, ubuntu-bionic, ubuntu-focal, ubuntu-groovy, ubuntu-hirsute, ubuntu-impish, debian-jessie, debian-stretch, debian-buster, debian-bullseye, debian-sid, linuxmint-17, linuxmint-18, linuxmint-19, linuxmint-19.3, linuxmint-20.1, linuxmint-20.2, fedora-26, fedora-27, fedora-28, fedora-29, fedora-30, fedora-31, fedora-32, fedora-33, fedora-34, fedora-35, centos-7, centos-8, gentoo-python3.9, gentoo-python3.10, archlinux-latest, opensuse-15, opensuse-15.3, opensuse-tumbleweed, slackware-14.2, conda-forge, ubuntu-bionic-i386, manylinux-2_24-i686, debian-buster-i386, centos-7-i386] tox_packages_factor: [minimal, standard] env: TOX_ENV: docker-${{ matrix.tox_system_factor }}-${{ matrix.tox_packages_factor }} diff --git a/tox.ini b/tox.ini index 8c5301eb28e..3fae601230e 100644 --- a/tox.ini +++ b/tox.ini @@ -246,6 +246,7 @@ setenv = gentoo: BASE_IMAGE=sheerluck/sage-on-gentoo-stage4 gentoo-python3.7: BASE_TAG=latest-py37 gentoo-python3.9: BASE_TAG=latest-py39 + gentoo-python3.10: BASE_TAG=latest-py10 gentoo: IGNORE_MISSING_SYSTEM_PACKAGES=no # # https://hub.docker.com/_/archlinux/ From 22235afa31d10b17c2c05276b6ca573e4d53a04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Tue, 9 Nov 2021 20:44:16 +0100 Subject: [PATCH 332/378] fix some lgtm and pep details in sloane_functions.py --- src/sage/combinat/sloane_functions.py | 178 +++++++++++++------------- 1 file changed, 88 insertions(+), 90 deletions(-) diff --git a/src/sage/combinat/sloane_functions.py b/src/sage/combinat/sloane_functions.py index 4307051be34..be0f54cd8b3 100644 --- a/src/sage/combinat/sloane_functions.py +++ b/src/sage/combinat/sloane_functions.py @@ -125,11 +125,18 @@ # just used for handy .load, .save, etc. import sys import inspect + from sage.structure.sage_object import SageObject from sage.arith.srange import srange from sage.rings.integer_ring import ZZ from sage.functions.all import prime_pi from sage.rings.integer import Integer as Integer_class +# You may have to import more here when defining new sequences +import sage.arith.all as arith +from sage.matrix.matrix_space import MatrixSpace +from sage.rings.rational_field import QQ +from sage.combinat import combinat +from sage.misc.misc_c import prod class SloaneSequence(SageObject): @@ -307,22 +314,16 @@ def __getitem__(self, n): return self(n) LENGTH = 100000 - (start, stop, step) = n.indices(2*LENGTH) + (start, stop, step) = n.indices(2 * LENGTH) if abs(stop - start) > LENGTH: - raise IndexError("slice (=%s) too long"%n) + raise IndexError("slice (=%s) too long" % n) return [self(i) for i in range(start, stop, step) if i >= self.offset] + ######################################################################## # II. Actual implementations of Sloane sequences. ######################################################################## -# You may have to import more here when defining new sequences -import sage.arith.all as arith -from sage.matrix.matrix_space import MatrixSpace -from sage.rings.rational_field import QQ -from sage.combinat import combinat -from sage.misc.misc_c import prod - # This one should be here! class A000001(SloaneSequence): @@ -638,7 +639,7 @@ def __init__(self): - Jaap Spies (2007-01-30) """ SloaneSequence.__init__(self, offset=0) - self._b=[] + self._b = [] self._precompute(2) def _repr_(self): @@ -770,7 +771,7 @@ def pi(self): d, d1 = a//b, a1//b1 while d == d1: yield d - a, a1 = 10*(a%b), 10*(a1%b1) + a, a1 = 10*(a % b), 10*(a1 % b1) d, d1 = a//b, a1//b1 @@ -867,7 +868,7 @@ def _eval(self, n): sage: [sloane.A003418._eval(n) for n in range(1,11)] [1, 2, 6, 12, 60, 60, 420, 840, 2520, 2520] """ - return arith.lcm([i for i in range(1,n+1)]) + return arith.lcm([i for i in range(1, n+1)]) class A007318(SloaneSequence): @@ -929,7 +930,7 @@ def _eval(self, n): m += 1 m -= 1 k = n - m*(m+1)//2 - return arith.binomial(m,k) + return arith.binomial(m, k) class A008275(SloaneSequence): @@ -998,7 +999,7 @@ def s(self, n, k): sage: sloane.A008275.s(5,3) 35 """ - return (-1)**(n-k) * combinat.stirling_number1(n,k) + return (-1)**(n-k) * combinat.stirling_number1(n, k) def _eval(self, n): """ @@ -1076,7 +1077,7 @@ def s2(self, n, k): sage: sloane.A008277.s2(4,2) 7 """ - return combinat.stirling_number2(n,k) + return combinat.stirling_number2(n, k) def _eval(self, n): """ @@ -1155,10 +1156,10 @@ def _eval(self, n): m += 1 m -= 1 k = n - m*(m+1)//2 - if (m+k)%2: + if (m+k) % 2: return ZZ(0) sign = (-1)**((m+k)//2 + k) - return sign * arith.binomial((m+k)//2,k) + return sign * arith.binomial((m+k)//2, k) class A000010(SloaneSequence): @@ -1977,7 +1978,7 @@ def _repr_(self): """ return "1's-counting sequence: number of 1's in binary expansion of n." - def f(self,n): + def f(self, n): """ EXAMPLES:: @@ -2383,7 +2384,8 @@ def _eval(self, n): """ if n == 0: return ZZ.one() - return ZZ(sum( (i%2) * arith.euler_phi(i) * 2**(n//i) / (2*n) for i in arith.divisors(n) )) + return ZZ(sum((i % 2) * arith.euler_phi(i) * 2**(n//i) / (2*n) + for i in arith.divisors(n))) class A000032(SloaneSequence): @@ -2562,12 +2564,12 @@ def _precompute(self, how_many=150): """ try: self._b - n = self._n + self._n except AttributeError: self._b = [] - n = self.offset - self._n = n - self._b += [i for i in range(self._n, self._n+how_many) if sloane.A004086(i) == i] + self._n = self.offset + self._b += [i for i in range(self._n, self._n + how_many) + if sloane.A004086(i) == i] self._n += how_many def _eval(self, n): @@ -2861,8 +2863,8 @@ def _eval(self, n): [1, 4, 6, 8, 9, 10, 12, 14, 15, 16] """ if n == 1: - return ZZ.one() - return sloane.A002808(n-1) + return ZZ.one() + return sloane.A002808(n - 1) class A000043(SloaneSequence): @@ -3291,7 +3293,7 @@ def _eval(self, n): sage: [sloane.A002110._eval(n) for n in range(10)] [1, 2, 6, 30, 210, 2310, 30030, 510510, 9699690, 223092870] """ - return prod([sloane.A000040(i) for i in range(1,n+1)]) #n-th prime = A000040(n) + return prod([sloane.A000040(i) for i in range(1, n + 1)]) # n-th prime = A000040(n) class A000720(SloaneSequence): @@ -3404,7 +3406,7 @@ def _eval(self, n): sage: [sloane.A064553._eval(n) for n in range(1,11)] [1, 2, 3, 4, 4, 6, 5, 8, 9, 8] """ - return prod([(prime_pi(p)+1)**e for p,e in arith.factor(n)]) + return prod([(prime_pi(p)+1)**e for p, e in arith.factor(n)]) class A001055(SloaneSequence): @@ -3469,15 +3471,15 @@ def nwf(self, n, m): return ZZ.one() if arith.is_prime(n): if m < n: - return ZZ(0) + return ZZ.zero() else: return ZZ.one() s = ZZ(0) for d in arith.divisors(n): if d > 1 and d <= m and d < n: - s += self.nwf(n//d, d) + s += self.nwf(n // d, d) if n <= m: - s += 1 + s += 1 return s def _eval(self, n): @@ -3692,7 +3694,8 @@ def _precompute(self, how_many=150): sage: len(sloane.A005117._b) - initial > 0 True """ - self._b += [i for i in range(self._n, self._n+how_many) if max(e for _,e in arith.factor(i)) <= 1] + self._b += [i for i in range(self._n, self._n+how_many) + if max(e for _, e in arith.factor(i)) <= 1] self._n += how_many def _eval(self, n): @@ -4580,7 +4583,8 @@ def _eval(self, n): # a(n) = Sum from k=1 to n of k! StirlingS2(n, k) if n == 0: return ZZ.one() - return sum(arith.factorial(k) * combinat.stirling_number2(n,k) for k in range(1, n+1)) + return sum(arith.factorial(k) * combinat.stirling_number2(n, k) + for k in range(1, n+1)) class A006318(SloaneSequence): @@ -4745,6 +4749,7 @@ def _eval(self, n): """ return arith.factorial(2*n) / (arith.factorial(n)*2**n) + class A006882(SloaneSequence): def __init__(self): r""" @@ -4897,7 +4902,7 @@ def _eval(self, n): sage: [sloane.A000984._eval(n) for n in range(10)] [1, 2, 6, 20, 70, 252, 924, 3432, 12870, 48620] """ - return arith.binomial(2*n,n) + return arith.binomial(2 * n, n) class A001405(SloaneSequence): @@ -5060,8 +5065,6 @@ def _eval(self, n): return ZZ(n * (n+1) * (2*n+1) // 6) - - # Theme: maximal permanent of an m x n (0,1)- matrix: # Seok-Zun Song et al. Extremes of permanents of (0,1)-matrices, p. 201-202. @@ -5083,7 +5086,7 @@ def _precompute(self, how_many=20): f = self._f self._b += [next(f) for i in range(how_many)] - def gen(self,a0,a1,d): + def gen(self, a0, a1, d): """ EXAMPLES:: @@ -5120,7 +5123,7 @@ def list(self, n): """ self._eval(n) # force computation return self._b[:n] - _k = 1 + _k = 1 class A000153(ExtremesOfPermanentsSequence): @@ -5163,7 +5166,7 @@ def __init__(self): """ SloaneSequence.__init__(self, offset=0) self._b = [] - self._a0a1d = (0,1,2) + self._a0a1d = (0, 1, 2) self._precompute(2) # force precomputation, e.g. a(0) will fail when asked first def _repr_(self): @@ -5218,7 +5221,7 @@ def __init__(self): """ SloaneSequence.__init__(self, offset=0) self._b = [] - self._a0a1d = (1,1,1) + self._a0a1d = (1, 1, 1) self._precompute(2) # force precomputation, e.g. a(0) will fail when asked first def _repr_(self): @@ -5277,7 +5280,7 @@ def __init__(self): - Jaap Spies (2007-01-23) """ SloaneSequence.__init__(self, offset=1) - self._a0a1d = (0,1,3) + self._a0a1d = (0, 1, 3) self._b = [] self._k = self.offset + 1 @@ -5337,7 +5340,7 @@ def __init__(self): - Jaap Spies (2007-01-13) """ SloaneSequence.__init__(self, offset=2) - self._a0a1d = (0,1,4) + self._a0a1d = (0, 1, 4) self._b = [] self._k = self.offset + 1 @@ -5397,7 +5400,7 @@ def __init__(self): - Jaap Spies (2007-01-13) """ SloaneSequence.__init__(self, offset=3) - self._a0a1d = (0,1,5) + self._a0a1d = (0, 1, 5) self._b = [] self._k = self.offset + 1 @@ -5410,8 +5413,9 @@ def _repr_(self): """ return "a(n) = n*a(n-1) + (n-5)*a(n-2), a(3) = 0, a(4) = 1." + class ExtremesOfPermanentsSequence2(ExtremesOfPermanentsSequence): - def gen(self,a0,a1,d): + def gen(self, a0, a1, d): """ EXAMPLES:: @@ -5483,7 +5487,7 @@ def __init__(self): - Jaap Spies (2007-01-23) """ SloaneSequence.__init__(self, offset=1) - self._a0a1d = (6,43,6) + self._a0a1d = (6, 43, 6) self._k = self.offset + 1 self._b = [] @@ -5545,7 +5549,7 @@ def __init__(self): - Jaap Spies (2007-01-23) """ SloaneSequence.__init__(self, offset=0) - self._a0a1d = (0,2,1) + self._a0a1d = (0, 2, 1) self._b = [] self._precompute(2) self._k1 = 2 @@ -6054,7 +6058,7 @@ def _eval(self, n): sage: [sloane.A000203._eval(n) for n in range(1,11)] [1, 3, 4, 7, 6, 12, 8, 15, 13, 18] """ - return sum(arith.divisors(n)) #alternative: return arith.sigma(n) + return sum(arith.divisors(n)) # alternative: return arith.sigma(n) class A001157(SloaneSequence): @@ -6110,7 +6114,7 @@ def _eval(self, n): sage: [sloane.A001157._eval(n) for n in range(1,11)] [1, 5, 10, 21, 26, 50, 50, 85, 91, 130] """ - return arith.sigma(n,2) + return arith.sigma(n, 2) class A008683(SloaneSequence): @@ -6395,11 +6399,8 @@ def _eval(self, n): return ZZ(10**n-1)//9 - - - # inhomogeneous second order recurrences -def recur_gen2b(a0,a1,a2,a3,b): +def recur_gen2b(a0, a1, a2, a3, b): r""" Inhomogeneous second-order linear recurrence generator with fixed coefficients and `b = f(n)` @@ -6422,6 +6423,7 @@ def recur_gen2b(a0,a1,a2,a3,b): x, y = y, a3*x+a2*y + b(n) yield x + class RecurrenceSequence(SloaneSequence): def _precompute(self, how_many=20): """ @@ -6495,7 +6497,7 @@ def __init__(self): - Jaap Spies (2007-01-19) """ SloaneSequence.__init__(self, offset=0) - self._params = (0,1,34,-1,self.g) + self._params = (0, 1, 34, -1, self.g) self._b = [] self._precompute() @@ -6510,7 +6512,7 @@ def _repr_(self): """ return "Numbers that are both triangular and square: a(n) = 34a(n-1) - a(n-2) + 2." - def g(self,k): + def g(self, k): """ EXAMPLES:: @@ -6645,7 +6647,7 @@ def _eval(self, n): sage: [sloane.A001221._eval(n) for n in range(1,10)] [0, 1, 1, 1, 1, 2, 1, 1, 1] """ - return len(arith.prime_divisors(n)) # there is a PARI function omega + return len(arith.prime_divisors(n)) # there is a PARI function omega class A001222(SloaneSequence): @@ -6891,12 +6893,12 @@ def _precompute(self, how_many=150): """ try: self._b - n = self._n + self._n except AttributeError: self._b = [] - n = 1 - self._n = n - self._b += [i for i in range(self._n, self._n+how_many) if sum(e for _,e in arith.factor(i)) == 2] + self._n = 1 + self._b += [i for i in range(self._n, self._n + how_many) + if sum(e for _, e in arith.factor(i)) == 2] self._n += how_many def _eval(self, n): @@ -6995,12 +6997,11 @@ def _precompute(self, how_many=10000): """ try: self._b - n = self._n + self._n except AttributeError: self._b = [1] - n = 1 - self._n = n - self._b += self._powerful_numbers_in_range(self._n, self._n+how_many) + self._n = 1 + self._b += self._powerful_numbers_in_range(self._n, self._n + how_many) self._n += how_many def _powerful_numbers_in_range(self, n, m): @@ -7017,7 +7018,7 @@ def _powerful_numbers_in_range(self, n, m): n = 4 # Use PARI directly -- much faster. from sage.libs.pari.all import pari - L = pari('v=listcreate(); for(i=%s,%s,if(vecmin(factor(i)[,2])>1,listput(v,i))); v'%(n,m)) + L = pari('v=listcreate(); for(i=%s,%s,if(vecmin(factor(i)[,2])>1,listput(v,i))); v' % (n, m)) return [ZZ(x) for x in L] # not very many, so not much overhead def _eval(self, n): @@ -7159,12 +7160,12 @@ def _precompute(self, how_many=150): """ try: self._b - n = self._n + self._n except AttributeError: self._b = [] - n = self.offset - self._n = n - self._b += [i for i in range(self._n, self._n+how_many) if arith.euler_phi(2*i-1) < arith.euler_phi(2*i)] + self._n = self.offset + self._b += [i for i in range(self._n, self._n + how_many) + if arith.euler_phi(2 * i - 1) < arith.euler_phi(2 * i)] self._n += how_many def _eval(self, n): @@ -7199,10 +7200,8 @@ def list(self, n): return self.list(n) - - # a group of sequences uses this function: -def recur_gen2(a0,a1,a2,a3): +def recur_gen2(a0, a1, a2, a3): r""" homogeneous general second-order linear recurrence generator with fixed coefficients @@ -7768,9 +7767,6 @@ def _repr_(self): return "Linear 2nd order recurrence, a(n) = 6 a(n-1) + 5 a(n-2)." - - - # todo jsp # # @@ -8134,7 +8130,7 @@ def _eval(self, n): # a group of sequences uses this function: -def recur_gen3(a0,a1,a2,a3,a4,a5): +def recur_gen3(a0, a1, a2, a3, a4, a5): r""" homogeneous general third-order linear recurrence generator with fixed coefficients @@ -8149,7 +8145,7 @@ def recur_gen3(a0,a1,a2,a3,a4,a5): sage: [next(it) for i in range(10)] [1, 1, 1, 3, 5, 9, 17, 31, 57, 105] """ - x, y ,z = ZZ(a0), ZZ(a1), ZZ(a2) + x, y, z = ZZ(a0), ZZ(a1), ZZ(a2) yield x while True: x, y, z = y, z, a5*x+a4*y+a3*z @@ -8583,8 +8579,11 @@ def _eval(self, n): if n == 1: return ZZ.one() m = 0 - for d in [i for i in arith.divisors(n) if i%2]: # d is odd divisor - k = min(d, 2*n/d) + for d in arith.divisors(n): + if not d % 2: + continue + # d is odd divisor + k = min(d, 2 * n // d) if k > m: m = k return ZZ(m) @@ -8660,12 +8659,12 @@ def _precompute(self, how_many=150): """ try: self._b - n = self._n + self._n except AttributeError: self._b = [] - n = 1 - self._n = n - self._b += [i for i in range(self._n, self._n+how_many) if self.is_number_of_the_third_kind(i)] + self._n = 1 + self._b += [i for i in range(self._n, self._n + how_many) + if self.is_number_of_the_third_kind(i)] self._n += how_many def _eval(self, n): @@ -8822,8 +8821,8 @@ def _eval(self, n): """ if n == 1 or n == 0: return ZZ.zero() - k = sum(i%2 for i in arith.divisors(n)) # A001227, the number of odd divisors - if n % 2 ==0: + k = sum(i % 2 for i in arith.divisors(n)) # A001227, the number of odd divisors + if n % 2 == 0: return k - 1 else: return k - 2 @@ -8902,7 +8901,7 @@ def _eval(self, n): if arith.is_prime(n) or arith.is_power_of_two(n): return ZZ.zero() - for d in srange(3,n,2): + for d in srange(3, n, 2): if n % d == 0: return min(d, 2*n//d) @@ -8942,8 +8941,8 @@ def _eval(self, n): if n < self.__n: return self.__data[n] from sage.combinat.expnums import expnums - self.__data = expnums(n+1, self.a) - self.__n = n+1 + self.__data = expnums(n + 1, self.a) + self.__n = n + 1 return self.__data[n] @@ -9111,9 +9110,8 @@ def _eval(self, n): """ if n <= 2: return ZZ.zero() - else: - return sum(sloane.A000045(i+1) * sloane.A000073(n-i-1) for i in range(n-2)) - + return sum(sloane.A000045(i + 1) * sloane.A000073(n - i - 1) + for i in range(n - 2)) ############################################################# @@ -9214,5 +9212,5 @@ def __getattribute__(self, name): except (AttributeError, TypeError): raise AttributeError(name) -sloane = Sloane() +sloane = Sloane() From 7ad6cd9a460a42a0d8a5f4f1397539bbc87d9c89 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 12:02:22 -0800 Subject: [PATCH 333/378] build/pkgs/sagemath_doc_*/SPKG.rst: New --- build/pkgs/sagemath_doc_html/SPKG.rst | 10 ++++++++++ build/pkgs/sagemath_doc_pdf/SPKG.rst | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100644 build/pkgs/sagemath_doc_html/SPKG.rst create mode 100644 build/pkgs/sagemath_doc_pdf/SPKG.rst diff --git a/build/pkgs/sagemath_doc_html/SPKG.rst b/build/pkgs/sagemath_doc_html/SPKG.rst new file mode 100644 index 00000000000..2ece53ab56e --- /dev/null +++ b/build/pkgs/sagemath_doc_html/SPKG.rst @@ -0,0 +1,10 @@ +sagemath_doc_html: SageMath documentation in HTML format +======================================================== + +Upon installation, this package builds the SageMath documentation +in HTML format. + +It is a standard package. It is built on every invocation +of ``make`` or ``make all``, but not on ``make build``. +The documentation build can also be run separately using +``make doc-html``. diff --git a/build/pkgs/sagemath_doc_pdf/SPKG.rst b/build/pkgs/sagemath_doc_pdf/SPKG.rst new file mode 100644 index 00000000000..25c77ff12ea --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/SPKG.rst @@ -0,0 +1,9 @@ +sagemath_doc_pdf: SageMath documentation in PDF format +====================================================== + +Upon installation, this package builds the SageMath documentation +in PDF format. + +It is an optional package. It can be enabled at configuration time +using ``./configure --enable-sagemath_doc_pdf``. Alternatively, +it can be installed by using ``make doc-pdf``. From eb65e034bad3ec82b19c90211ca5bf70533e8fe5 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 12:04:30 -0800 Subject: [PATCH 334/378] build/pkgs/sagemath_doc_*/dependencies: Add sage_docbuild --- build/pkgs/sagemath_doc_html/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/pkgs/sagemath_doc_html/dependencies b/build/pkgs/sagemath_doc_html/dependencies index 8d37b42880c..fc793f07bae 100644 --- a/build/pkgs/sagemath_doc_html/dependencies +++ b/build/pkgs/sagemath_doc_html/dependencies @@ -1,4 +1,4 @@ -sagelib sphinx | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol thebe ipywidgets +sagelib sphinx | $(SAGERUNTIME) maxima networkx scipy sympy matplotlib pillow mathjax mpmath ipykernel jupyter_client conway_polynomials tachyon jmol thebe ipywidgets sage_docbuild # Building the documentation has many dependencies, because all # documented modules are imported and because we use matplotlib to From 7989d8767056d68def98ee22116fbd24d7187d2f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 12:23:44 -0800 Subject: [PATCH 335/378] src/doc/Makefile: Handle errors from './sage --docbuild --all-documents' --- src/doc/Makefile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/doc/Makefile b/src/doc/Makefile index 304d5aca147..5d2031bd964 100644 --- a/src/doc/Makefile +++ b/src/doc/Makefile @@ -30,6 +30,7 @@ doc-inventory-reference: else doc-inventory-reference: $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) doc-inventory--$(subst /,-,$(BIBLIO)) @@ -40,6 +41,7 @@ endif # reference manual, html doc-html-reference: doc-inventory-reference $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" doc-html--$(subst /,-,$(BIBLIO)) @@ -48,7 +50,9 @@ doc-html-reference: doc-inventory-reference # other documentation, html doc-html-other: doc-html-reference - $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)), doc-html--$(subst /,-,$(doc))) + $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)) + @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-html--$(subst /,-,$(doc))) doc-html: doc-html-reference doc-html-other @@ -59,6 +63,7 @@ doc-pdf--%: # reference manual, pdf doc-pdf-reference: doc-inventory-reference $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents reference)) + @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi $(eval BIBLIO = $(firstword $(DOCS))) $(eval OTHER_DOCS = $(wordlist 2, 100, $(DOCS))) $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" doc-pdf--$(subst /,-,$(BIBLIO)) @@ -67,7 +72,9 @@ doc-pdf-reference: doc-inventory-reference # other documentation, pdf doc-pdf-other: doc-html-reference - $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)), doc-pdf--$(subst /,-,$(doc))) + $(eval DOCS = $(shell cd $(SAGE_ROOT) && ./sage --docbuild --all-documents all)) + @if [ -z "$(DOCS)" ]; then echo "Error: './sage --docbuild --all-documents' failed"; exit 1; fi + $(MAKE) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-prune-empty-dirs" $(foreach doc, $(wordlist 2, 100, $(DOCS)), doc-pdf--$(subst /,-,$(doc))) doc-pdf: doc-pdf-reference doc-pdf-other From f75d33f3dae372048920a95bbf4e2dddb467a8a4 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 9 Nov 2021 16:36:23 -0500 Subject: [PATCH 336/378] Trac #32836: don't let libSingular clobber the user's PATH. When we init_libsingular() in sage, singular prepends a few paths to the user's PATH environment variable, one of them being the directory where the "singular" executable lives. With a system singular package installed, this has the unfortunate consequence that something like "/usr/bin" will be given preference over the rest of your PATH, and in particular, preference over $SAGE_LOCAL/bin. This commit saves the PATH before calling init_libsingular(), and restores it afterwards. --- src/sage/libs/singular/singular.pyx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sage/libs/singular/singular.pyx b/src/sage/libs/singular/singular.pyx index ce93c3b8cb2..4e85f2158c5 100644 --- a/src/sage/libs/singular/singular.pyx +++ b/src/sage/libs/singular/singular.pyx @@ -803,8 +803,11 @@ cdef init_libsingular(): error_messages = [] -# call the init routine +# Save/restore the PATH because libSingular clobbers it: +# https://github.com/Singular/Singular/issues/1119 +saved_PATH = os.environ["PATH"] init_libsingular() +os.environ["PATH"] = saved_PATH cdef void libsingular_error_callback(const_char_ptr s): _s = char_to_str(s) From d64fb763d3f58e05954d576464a5c66cc1f5307f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 13:43:10 -0800 Subject: [PATCH 337/378] build/make/Makefile.in: Undo reintroduction of SAGE_SKIP_PLOT_DIRECTIVE, SAGE_DOC_MATHJAX settings --- build/make/Makefile.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index 4b9abbbcdb5..e6c9f3050cd 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -336,12 +336,12 @@ doc-html: sagemath_doc_html # megabytes of disk space. 'doc-clean' is a prerequisite because the # presence of graphics is cached in src/doc/output. doc-html-no-plot: doc-clean - +$(MAKE_REC) SAGE_SKIP_PLOT_DIRECTIVE=yes doc-html + +$(MAKE_REC) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) --no-plot" doc-html # Using mathjax is actually the default, but this target can be used # to override an environment setting of SAGE_DOC_MATHJAX=no doc-html-mathjax: - +$(MAKE_REC) SAGE_DOC_MATHJAX=yes doc-html + +$(MAKE_REC) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) -j" SAGE_DOC_MATHJAX=yes doc-html # Keep target 'doc-html-jsmath' for backwards compatibility. doc-html-jsmath: doc-html-mathjax From 6afc0d5535530f9f71538821ec07a7cb95d44d19 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 13:47:36 -0800 Subject: [PATCH 338/378] build/pkgs/sagemath_doc_html/spkg-install: Move handling of SAGE_DOC_JSMATH environment variable here from src/bin/sage-env --- build/pkgs/sagemath_doc_html/spkg-install | 14 ++++++++++++++ src/bin/sage-env | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/build/pkgs/sagemath_doc_html/spkg-install b/build/pkgs/sagemath_doc_html/spkg-install index 801aa7769fe..71e805869c0 100755 --- a/build/pkgs/sagemath_doc_html/spkg-install +++ b/build/pkgs/sagemath_doc_html/spkg-install @@ -1,3 +1,17 @@ #! /usr/bin/env bash + +# When building documentation, use MathJax by default. To turn it off, +# set SAGE_DOC_MATHJAX to be "no" or "False". +if [ -z "$SAGE_DOC_MATHJAX" ]; then + # For backwards compatibility, we use the value of SAGE_DOC_JSMATH + # if it is set. + if [ -n "$SAGE_DOC_JSMATH" ]; then + SAGE_DOC_MATHJAX="$SAGE_DOC_JSMATH" + else + SAGE_DOC_MATHJAX="True" + fi + export SAGE_DOC_MATHJAX +fi + cd $SAGE_ROOT/src/doc $MAKE doc-html diff --git a/src/bin/sage-env b/src/bin/sage-env index b4c0c6ea207..1f832183fb4 100644 --- a/src/bin/sage-env +++ b/src/bin/sage-env @@ -633,19 +633,6 @@ export MAKE export PIP_FORMAT="columns" -# When building documentation, use MathJax by default. To turn it off, -# set SAGE_DOC_MATHJAX to be "no" or "False". -if [ -z "$SAGE_DOC_MATHJAX" ]; then - # For backwards compatibility, we use the value of SAGE_DOC_JSMATH - # if it is set. - if [ -n "$SAGE_DOC_JSMATH" ]; then - SAGE_DOC_MATHJAX="$SAGE_DOC_JSMATH" - else - SAGE_DOC_MATHJAX="True" - fi - export SAGE_DOC_MATHJAX -fi - # Set the cysignals crash logs directory if [ -z "$CYSIGNALS_CRASH_LOGS" ]; then export CYSIGNALS_CRASH_LOGS="$DOT_SAGE/crash_logs" From b2cf40c2a9b023c2449dbf4186aeb369f604390a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 13:55:02 -0800 Subject: [PATCH 339/378] build/make/Makefile.in: Undo reintroduction of SAGE_SKIP_PLOT_DIRECTIVE, SAGE_DOC_MATHJAX settings (fixup) --- build/make/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/make/Makefile.in b/build/make/Makefile.in index e6c9f3050cd..4673be50224 100644 --- a/build/make/Makefile.in +++ b/build/make/Makefile.in @@ -341,7 +341,7 @@ doc-html-no-plot: doc-clean # Using mathjax is actually the default, but this target can be used # to override an environment setting of SAGE_DOC_MATHJAX=no doc-html-mathjax: - +$(MAKE_REC) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) -j" SAGE_DOC_MATHJAX=yes doc-html + +$(MAKE_REC) SAGE_DOCBUILD_OPTS="$(SAGE_DOCBUILD_OPTS) -j" doc-html # Keep target 'doc-html-jsmath' for backwards compatibility. doc-html-jsmath: doc-html-mathjax From 16816c8fb3ab4836474c7324800652673e094430 Mon Sep 17 00:00:00 2001 From: dcoudert Date: Wed, 10 Nov 2021 00:39:45 +0100 Subject: [PATCH 340/378] trac #30566: check that the output is a tree --- src/sage/graphs/spanning_tree.pyx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/graphs/spanning_tree.pyx b/src/sage/graphs/spanning_tree.pyx index 9cad7642635..7e13bdf1a6f 100644 --- a/src/sage/graphs/spanning_tree.pyx +++ b/src/sage/graphs/spanning_tree.pyx @@ -885,6 +885,15 @@ def random_spanning_tree(G, output_as_graph=False, by_weight=False, weight_funct sage: print(len(foo(K4, 100))) # random 16 + Check that the spanning tree returned when using weights is a tree:: + + sage: G = graphs.RandomBarabasiAlbert(50, 2) + sage: for u, v in G.edge_iterator(labels=False): + ....: G.set_edge_label(u, v, randint(1, 10)) + sage: T = G.random_spanning_tree(by_weight=True, output_as_graph=True) + sage: T.is_tree() + True + TESTS:: sage: G = Graph() From 37a03bd94e1716af2926c30eddbaf6d38303f869 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 16:09:36 -0800 Subject: [PATCH 341/378] src/doc/en/developer/packaging.rst: Fix up section label --- src/doc/en/developer/packaging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/packaging.rst b/src/doc/en/developer/packaging.rst index 9bdab77e80d..33df039bbec 100644 --- a/src/doc/en/developer/packaging.rst +++ b/src/doc/en/developer/packaging.rst @@ -718,7 +718,7 @@ packages and optional packages should only depend on standard or optional packages. -.. _section-dependencies: +.. _section-trees: Where packages are installed ---------------------------- From fc89a6657450c0e10c8322615f1fced0f8ebb984 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 16:21:15 -0800 Subject: [PATCH 342/378] build/pkgs/sagemath_doc_pdf/spkg-install: Set SAGE_DOC_MATHJAX as a workaround --- build/pkgs/sagemath_doc_pdf/spkg-install | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/build/pkgs/sagemath_doc_pdf/spkg-install b/build/pkgs/sagemath_doc_pdf/spkg-install index f04f4b75d9a..947fc17511f 100755 --- a/build/pkgs/sagemath_doc_pdf/spkg-install +++ b/build/pkgs/sagemath_doc_pdf/spkg-install @@ -1,3 +1,7 @@ #! /usr/bin/env bash +# This must be set; otherwise, sage.docs.conf uses sphinx.ext.imgmath, +# which leads to errors. +export SAGE_DOC_MATHJAX=yes + cd $SAGE_ROOT/src/doc $MAKE doc-pdf From 23f50092bf4af21742e834ef7b908102c85af4d8 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 18:23:35 -0800 Subject: [PATCH 343/378] sage.features.normaliz: New --- src/sage/features/normaliz.py | 28 +++++++++++++++++++ .../geometry/polyhedron/backend_normaliz.py | 4 +-- src/sage/geometry/polyhedron/base.py | 6 ++-- 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 src/sage/features/normaliz.py diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py new file mode 100644 index 00000000000..5135b7254ab --- /dev/null +++ b/src/sage/features/normaliz.py @@ -0,0 +1,28 @@ +r""" +Check for pynormaliz +""" +from . import PythonModule +from .join_feature import JoinFeature + + +class pynormaliz(JoinFeature): + r""" + A :class:`sage.features.Feature` describing the presence of the + Python package ``igraph``. + + EXAMPLES:: + + sage: from sage.features.igraph import pynormaliz + sage: pynormaliz().is_present() # optional - pynormaliz + FeatureTestResult('pynormaliz', True) + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.igraph import pynormaliz + sage: isinstance(pynormaliz(), pynormaliz) + True + """ + JoinFeature.__init__(self, 'pynormaliz', + [PythonModule('PyNormaliz', spkg="pynormaliz")]) diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index d1f30e2d31f..7c48b54cd96 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -26,10 +26,10 @@ from sage.structure.element import Element from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod -from sage.features import PythonModule +from sage.features.normaliz import pynormaliz from sage.misc.lazy_import import lazy_import lazy_import('PyNormaliz', ['NmzResult', 'NmzCompute', 'NmzCone', 'NmzConeCopy'], - feature=PythonModule("PyNormaliz", spkg="pynormaliz")) + feature=pynormaliz) from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index d44c3d508fb..f6969eab1eb 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -8729,16 +8729,18 @@ def volume(self, measure='ambient', engine='auto', **kwds): Latte().require() engine = 'latte' except FeatureNotPresentError: + from sage.features.normaliz import pynormaliz try: - PythonModule("PyNormaliz", spkg="pynormaliz").require() + pynormaliz.require() engine = 'normaliz' except FeatureNotPresentError: raise RuntimeError("the induced rational measure can only be computed with the optional packages `latte_int`, or `pynormaliz`") if engine == 'auto' and measure == 'induced_lattice': # Enforce a default choice, change if a better engine is found. + from sage.features.normaliz import pynormaliz try: - PythonModule("PyNormaliz", spkg="pynormaliz").require() + pynormaliz.require() engine = 'normaliz' except FeatureNotPresentError: try: From f5bdb919debe1f54a313e16940ae36ddc023b052 Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Wed, 10 Nov 2021 10:24:52 +0800 Subject: [PATCH 344/378] use PARI's fflog for binary finite fields --- .../rings/finite_rings/element_ntl_gf2e.pyx | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index 685f9a272bd..b437a4e20c9 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -1253,30 +1253,21 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): def log(self, base): """ - Return `x` such that `b^x = a`, where `x` is `a` and `b` - is the base. + Compute an integer `x` such that `b^x = a`, where `a` is ``self`` + and `b` is ``base``. INPUT: - - ``base`` -- finite field element that generates the multiplicative - group. + - ``base`` -- finite-field element. OUTPUT: Integer `x` such that `a^x = b`, if it exists. Raises a ``ValueError`` exception if no such `x` exists. - EXAMPLES:: + ALGORITHM: :pari:`fflog` - sage: F = GF(17) - sage: F(3^11).log(F(3)) - 11 - sage: F = GF(113) - sage: F(3^19).log(F(3)) - 19 - sage: F = GF(next_prime(10000)) - sage: F(23^997).log(F(23)) - 997 + EXAMPLES:: sage: F = FiniteField(2^10, 'a') sage: g = F.gen() @@ -1287,12 +1278,46 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): a^8 + a^7 + a^4 + a + 1 a^8 + a^7 + a^4 + a + 1 - AUTHOR: David Joyner and William Stein (2005-11) + Big instances used to take very long before :trac:`32842`:: + + sage: g = GF(2^61).gen() + sage: g.log(g^7) + 1976436865040309101 + + TESTS: + + Check that non-existence is correctly detected:: + + sage: g = GF(2^50).gen() + sage: (2^50-1) % 1023 + 0 + sage: g.log(g^1023) + Traceback (most recent call last): + ... + ValueError: no logarithm of z50 exists to base z50^49 + z50^46 + z50^45 + z50^44 + z50^41 + z50^34 + z50^33 + z50^32 + z50^27 + z50^25 + z50^24 + z50^21 + z50^18 + z50^17 + z50^16 + z50^15 + z50^12 + z50^11 + z50^10 + z50^8 + z50^7 + z50^3 + z50^2 + + AUTHORS: + + - David Joyner and William Stein (2005-11) + - Lorenz Panny (2021-11): use PARI's :pari:`fflog` instead of :func:`sage.groups.generic.discrete_log` """ - from sage.groups.generic import discrete_log + base = self.parent()(base) + + # The result is undefined if the input to fflog() is invalid. + # Since the unit group is cyclic, it suffices to check orders. + cdef Integer base_order = base.multiplicative_order() + cdef Integer self_order = self.multiplicative_order() + if not self_order.divides(base_order): + raise ValueError(f'no logarithm of {self} exists to base {base}') + + # Let's pass the known factorization of the order to PARI. + fs, = self._parent.factored_unit_order() # cached + ps = pari.Col(p for p,_ in fs) + vs = pari.Col(base_order.valuation(p) for p,_ in fs) + fac = pari.matconcat((ps, vs)) - b = self.parent()(base) - return discrete_log(self, b) + x = pari.fflog(self, base, (base_order, fac)) + return Integer(x) def unpickleFiniteField_ntl_gf2eElement(parent, elem): """ From 0b65b799ed5bc66fed7e1e39c1a07980a3a08616 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 19:58:58 -0800 Subject: [PATCH 345/378] src/sage/features/normaliz.py: Fix up --- src/sage/features/normaliz.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py index 5135b7254ab..e00077011aa 100644 --- a/src/sage/features/normaliz.py +++ b/src/sage/features/normaliz.py @@ -8,11 +8,11 @@ class pynormaliz(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of the - Python package ``igraph``. + Python package ``PyNormaliz``. EXAMPLES:: - sage: from sage.features.igraph import pynormaliz + sage: from sage.features.normaliz import pynormaliz sage: pynormaliz().is_present() # optional - pynormaliz FeatureTestResult('pynormaliz', True) """ @@ -20,7 +20,7 @@ def __init__(self): r""" TESTS:: - sage: from sage.features.igraph import pynormaliz + sage: from sage.features.normaliz import pynormaliz sage: isinstance(pynormaliz(), pynormaliz) True """ From fd298c4b7a6f845335b862f6dc2f8e18753937e7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 9 Nov 2021 21:44:24 -0800 Subject: [PATCH 346/378] build/pkgs/sagemath_doc_pdf/dependencies: Depend on sagemath_doc_html --- build/pkgs/sagemath_doc_pdf/dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 120000 => 100644 build/pkgs/sagemath_doc_pdf/dependencies diff --git a/build/pkgs/sagemath_doc_pdf/dependencies b/build/pkgs/sagemath_doc_pdf/dependencies deleted file mode 120000 index 5bad6e468d6..00000000000 --- a/build/pkgs/sagemath_doc_pdf/dependencies +++ /dev/null @@ -1 +0,0 @@ -../sagemath_doc_html/dependencies \ No newline at end of file diff --git a/build/pkgs/sagemath_doc_pdf/dependencies b/build/pkgs/sagemath_doc_pdf/dependencies new file mode 100644 index 00000000000..4bdc1055372 --- /dev/null +++ b/build/pkgs/sagemath_doc_pdf/dependencies @@ -0,0 +1 @@ +sagemath_doc_html From d457de75f32d2d41d30ee2f618e6e7dbd47fed41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Wed, 10 Nov 2021 09:55:40 +0100 Subject: [PATCH 347/378] various code details in combinat --- src/sage/combinat/baxter_permutations.py | 9 +++++---- src/sage/combinat/k_tableau.py | 13 +++++++------ src/sage/combinat/permutation.py | 6 +----- src/sage/combinat/shifted_primed_tableau.py | 4 ++-- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/sage/combinat/baxter_permutations.py b/src/sage/combinat/baxter_permutations.py index 59d9a0256fb..0e3c722f480 100644 --- a/src/sage/combinat/baxter_permutations.py +++ b/src/sage/combinat/baxter_permutations.py @@ -81,7 +81,7 @@ def __init__(self, n): self.element_class = Permutations(n).element_class self._n = ZZ(n) from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets - super(BaxterPermutations, self).__init__(category=FiniteEnumeratedSets()) + super(BaxterPermutations_size, self).__init__(category=FiniteEnumeratedSets()) def _repr_(self): """ @@ -128,7 +128,7 @@ def __contains__(self, x): if x_j > a and x_j < b and x_j > max_l: max_l = x_j min_r = len(x) + 1 - for x_j in x[i+2:]: + for x_j in x[i + 2:]: if x_j > a and x_j < b and x_j < min_r: min_r = x_j if max_l > min_r: @@ -139,7 +139,7 @@ def __contains__(self, x): if x_j < a and x_j > b and x_j < min_l: min_l = x_j max_r = 0 - for x_j in x[i+2:]: + for x_j in x[i + 2:]: if x_j < a and x_j > b and x_j > max_r: max_r = x_j if min_l < max_r: @@ -186,7 +186,8 @@ def __iter__(self): else: for b in BaxterPermutations(self._n - 1): # Left to right maxima. - for i in [self._n - 2 - i for i in b.reverse().saliances()]: + for j in b.reverse().saliances(): + i = self._n - 2 - j yield Permutations(self._n)(b[:i] + [self._n] + b[i:]) # Right to left maxima. for i in b.saliances(): diff --git a/src/sage/combinat/k_tableau.py b/src/sage/combinat/k_tableau.py index 17fccecd104..9d5a40e532d 100644 --- a/src/sage/combinat/k_tableau.py +++ b/src/sage/combinat/k_tableau.py @@ -2369,14 +2369,15 @@ def __classcall_private__(cls, T, k, weight=None): """ if isinstance(T, cls): return T - outer_shape = Core([len(t) for t in T], k+1) - inner_shape = Core([x for x in [row.count(None) for row in T] if x], k+1) - Te = [v for row in T for v in row if v is not None]+[0] + outer_shape = Core([len(t) for t in T], k + 1) + loop = (row.count(None) for row in T) + inner_shape = Core([x for x in loop if x], k + 1) + Te = [v for row in T for v in row if v is not None] + [0] count_marks = tuple(Te.count(-(i+1)) for i in range(-min(Te))) - if not all( v==1 for v in count_marks ): + if not all(v == 1 for v in count_marks): # if T is not standard -> turn into standard - if weight is not None and tuple(weight)!=count_marks: - raise ValueError("Weight = %s and tableau = %s do not agree"%(weight, T)) + if weight is not None and tuple(weight) != count_marks: + raise ValueError("Weight = %s and tableau = %s do not agree" % (weight, T)) tijseq = StrongTableaux.marked_CST_to_transposition_sequence(T, k) if tijseq is None or len(tijseq) Date: Wed, 10 Nov 2021 18:07:15 +0800 Subject: [PATCH 348/378] slightly rephrase docstring --- src/sage/rings/finite_rings/element_ntl_gf2e.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx index b437a4e20c9..7092888fddd 100644 --- a/src/sage/rings/finite_rings/element_ntl_gf2e.pyx +++ b/src/sage/rings/finite_rings/element_ntl_gf2e.pyx @@ -1278,7 +1278,7 @@ cdef class FiniteField_ntl_gf2eElement(FinitePolyExtElement): a^8 + a^7 + a^4 + a + 1 a^8 + a^7 + a^4 + a + 1 - Big instances used to take very long before :trac:`32842`:: + Big instances used to take a very long time before :trac:`32842`:: sage: g = GF(2^61).gen() sage: g.log(g^7) From 265e0dd9af89c09b5dc35b674e70395d9f9c6211 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 10 Nov 2021 15:04:14 +0100 Subject: [PATCH 349/378] fix precision in books doctest --- .../sol/linsolve_doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py index 14208cd98ba..008dce524ae 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py @@ -19,7 +19,7 @@ Sage example in ./sol/linsolve.tex, line 84:: sage: M = (X*X-a) - sage: all(abs(M[i,j]) < 10^-14 + sage: all(abs(M[i,j]) < 10^-13 # original claim is 10^-14, which sometimes fails ....: for i in range(4) for j in range(4) ) True From 452b012926240a59607bc38869b70c0bd62210d0 Mon Sep 17 00:00:00 2001 From: Jonathan Kliem Date: Wed, 10 Nov 2021 16:40:35 +0100 Subject: [PATCH 350/378] remove comment as source code of the book has been updated --- .../sol/linsolve_doctest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py index 008dce524ae..839ad0d7ec7 100644 --- a/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py +++ b/src/sage/tests/books/computational-mathematics-with-sagemath/sol/linsolve_doctest.py @@ -19,7 +19,7 @@ Sage example in ./sol/linsolve.tex, line 84:: sage: M = (X*X-a) - sage: all(abs(M[i,j]) < 10^-13 # original claim is 10^-14, which sometimes fails + sage: all(abs(M[i,j]) < 10^-13 ....: for i in range(4) for j in range(4) ) True From bbe3f338b1cb841137de0f8ed244cdfde60cd018 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 10 Nov 2021 10:35:28 -0800 Subject: [PATCH 351/378] build/pkgs/traitlets: Update to 5.1.1 --- build/pkgs/traitlets/checksums.ini | 6 +++--- build/pkgs/traitlets/package-version.txt | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/pkgs/traitlets/checksums.ini b/build/pkgs/traitlets/checksums.ini index 415ba07704b..dd2af5d21ac 100644 --- a/build/pkgs/traitlets/checksums.ini +++ b/build/pkgs/traitlets/checksums.ini @@ -1,5 +1,5 @@ tarball=traitlets-VERSION.tar.gz -sha1=08d9b2db5b0cf7794e9c4ca76f7981cccc3233b6 -md5=19483ec0685e837912cff128209aa845 -cksum=3463913536 +sha1=86d03557843700d6dd0657371d15f0520c2f392f +md5=31f7fd84518fe08cb40ab18f6dde0d54 +cksum=1147319509 upstream_url=https://pypi.io/packages/source/t/traitlets/traitlets-VERSION.tar.gz diff --git a/build/pkgs/traitlets/package-version.txt b/build/pkgs/traitlets/package-version.txt index 831446cbd27..ac14c3dfaa8 100644 --- a/build/pkgs/traitlets/package-version.txt +++ b/build/pkgs/traitlets/package-version.txt @@ -1 +1 @@ -5.1.0 +5.1.1 From 00cb9c7fe2e9dacb1270d556e51b2a8e08bf92f4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 10 Nov 2021 16:13:54 -0800 Subject: [PATCH 352/378] src/sage/features/normaliz.py: Rename class to PyNormaliz, fix uses --- src/sage/features/normaliz.py | 10 +++++----- src/sage/geometry/polyhedron/backend_normaliz.py | 4 ++-- src/sage/geometry/polyhedron/base.py | 8 ++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/sage/features/normaliz.py b/src/sage/features/normaliz.py index e00077011aa..ceb67875b01 100644 --- a/src/sage/features/normaliz.py +++ b/src/sage/features/normaliz.py @@ -5,23 +5,23 @@ from .join_feature import JoinFeature -class pynormaliz(JoinFeature): +class PyNormaliz(JoinFeature): r""" A :class:`sage.features.Feature` describing the presence of the Python package ``PyNormaliz``. EXAMPLES:: - sage: from sage.features.normaliz import pynormaliz - sage: pynormaliz().is_present() # optional - pynormaliz + sage: from sage.features.normaliz import PyNormaliz + sage: PyNormaliz().is_present() # optional - pynormaliz FeatureTestResult('pynormaliz', True) """ def __init__(self): r""" TESTS:: - sage: from sage.features.normaliz import pynormaliz - sage: isinstance(pynormaliz(), pynormaliz) + sage: from sage.features.normaliz import PyNormaliz + sage: isinstance(PyNormaliz(), PyNormaliz) True """ JoinFeature.__init__(self, 'pynormaliz', diff --git a/src/sage/geometry/polyhedron/backend_normaliz.py b/src/sage/geometry/polyhedron/backend_normaliz.py index 7c48b54cd96..4b413193c26 100644 --- a/src/sage/geometry/polyhedron/backend_normaliz.py +++ b/src/sage/geometry/polyhedron/backend_normaliz.py @@ -26,10 +26,10 @@ from sage.structure.element import Element from sage.misc.cachefunc import cached_method from sage.misc.misc_c import prod -from sage.features.normaliz import pynormaliz from sage.misc.lazy_import import lazy_import +import sage.features.normaliz lazy_import('PyNormaliz', ['NmzResult', 'NmzCompute', 'NmzCone', 'NmzConeCopy'], - feature=pynormaliz) + feature=sage.features.normaliz.PyNormaliz()) from sage.rings.integer_ring import ZZ from sage.rings.rational_field import QQ diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index f6969eab1eb..354672ba01d 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -8729,18 +8729,18 @@ def volume(self, measure='ambient', engine='auto', **kwds): Latte().require() engine = 'latte' except FeatureNotPresentError: - from sage.features.normaliz import pynormaliz + from sage.features.normaliz import PyNormaliz try: - pynormaliz.require() + PyNormaliz().require() engine = 'normaliz' except FeatureNotPresentError: raise RuntimeError("the induced rational measure can only be computed with the optional packages `latte_int`, or `pynormaliz`") if engine == 'auto' and measure == 'induced_lattice': # Enforce a default choice, change if a better engine is found. - from sage.features.normaliz import pynormaliz + from sage.features.normaliz import PyNormaliz try: - pynormaliz.require() + PyNormaliz().require() engine = 'normaliz' except FeatureNotPresentError: try: From 7632e539cf7c7bfa15e8be3ed2cb7d6804d4ce27 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 10 Nov 2021 17:04:07 -0800 Subject: [PATCH 353/378] src/sage/geometry/polyhedron/base.py: Remove unused import --- src/sage/geometry/polyhedron/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/geometry/polyhedron/base.py b/src/sage/geometry/polyhedron/base.py index 354672ba01d..32a95a8b7a6 100644 --- a/src/sage/geometry/polyhedron/base.py +++ b/src/sage/geometry/polyhedron/base.py @@ -8717,7 +8717,7 @@ def volume(self, measure='ambient', engine='auto', **kwds): sage: Q.volume.is_in_cache() True """ - from sage.features import FeatureNotPresentError, PythonModule + from sage.features import FeatureNotPresentError if measure == 'induced_rational' and engine not in ['auto', 'latte', 'normaliz']: raise RuntimeError("the induced rational measure can only be computed with the engine set to `auto`, `latte`, or `normaliz`") if measure == 'induced_lattice' and engine not in ['auto', 'latte', 'normaliz']: From d6a179f69c1cceaf1af2ecd6ea5fa4463d1edcbd Mon Sep 17 00:00:00 2001 From: Lorenz Panny Date: Fri, 12 Nov 2021 14:03:55 +0800 Subject: [PATCH 354/378] fix doctest formatting --- src/sage/rings/finite_rings/integer_mod_ring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/rings/finite_rings/integer_mod_ring.py b/src/sage/rings/finite_rings/integer_mod_ring.py index 28fb2736491..00f64ed4bd3 100644 --- a/src/sage/rings/finite_rings/integer_mod_ring.py +++ b/src/sage/rings/finite_rings/integer_mod_ring.py @@ -1366,7 +1366,7 @@ def unit_gens(self, **kwds): The choice of generators is affected by the optional keyword ``algorithm``; this can be ``'sage'`` (default) or ``'pari'``. - See :meth:`unit_group` for details. + See :meth:`unit_group` for details. :: sage: A = Zmod(55) sage: A.unit_gens(algorithm='sage') From e25bbfde58aec0f64a3b955b08eb29065ae1020f Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 18 Oct 2021 16:02:03 -0700 Subject: [PATCH 355/378] src/requirements.txt.m4: Add memory_allocator --- src/requirements.txt.m4 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/requirements.txt.m4 b/src/requirements.txt.m4 index 57dca4227a6..9a2e448c603 100644 --- a/src/requirements.txt.m4 +++ b/src/requirements.txt.m4 @@ -23,6 +23,7 @@ gmpy2==esyscmd(`printf $(sed "s/[.]p.*//;" ../gmpy2/package-version.txt)') jinja2==esyscmd(`printf $(sed "s/[.]p.*//;" ../jinja2/package-version.txt)') dnl ... for sage_setup.autogen.interpreters jupyter_core==esyscmd(`printf $(sed "s/[.]p.*//;" ../jupyter_core/package-version.txt)') +memory_allocator==esyscmd(`printf $(sed "s/[.]p.*//;" ../memory_allocator/package-version.txt)') numpy==esyscmd(`printf $(sed "s/[.]p.*//;" ../numpy/package-version.txt)') dnl ... already needed by sage.env pkgconfig==esyscmd(`printf $(sed "s/[.]p.*//;" ../pkgconfig/package-version.txt)') From 4d021ab87a4a44b2928a25d4d33721018985f62f Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 12 Nov 2021 23:31:21 +0900 Subject: [PATCH 356/378] Convert < to < and back --- src/sage/misc/html.py | 19 +++++++++---------- src/sage/repl/rich_output/output_browser.py | 6 ++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/sage/misc/html.py b/src/sage/misc/html.py index 7dacc5f2748..237177337fe 100644 --- a/src/sage/misc/html.py +++ b/src/sage/misc/html.py @@ -294,12 +294,13 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): sage: MathJax().eval(3, mode='inline') \(\newcommand{\Bold}[1]{\mathbf{#1}}3\) sage: MathJax().eval(type(3), mode='inline') - \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb||\) + \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb||\) """ # Get a regular LaTeX representation of x x = latex(x, combine_all=combine_all) - # The following block, hopefully, can be removed in some future MathJax. + # The "\text{\texttt{...}}" blocks are reformed to be renderable by MathJax. + # These blocks are produced by str_function() defined in sage.misc.latex. prefix = r"\text{\texttt{" parts = x.split(prefix) for i, part in enumerate(parts): @@ -324,7 +325,6 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): delimiter = "|" y = "(complicated string)" wrapper = r"\verb" + delimiter + "%s" + delimiter - spacer = r"\phantom{\verb!%s!}" y = y.replace("{ }", " ").replace("{-}", "-") for c in r"#$%&\^_{}~": char_wrapper = r"{\char`\%s}" % c @@ -336,14 +336,12 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): nspaces += 1 continue if nspaces > 0: - subparts.append(spacer % ("x" * nspaces)) + subparts.append(wrapper % (" " * nspaces)) nspaces = 1 subparts.append(wrapper % subpart) - # There is a bug with omitting empty lines in arrays - if not y: - subparts.append(spacer % "x") subparts.append(part[closing + 1:]) parts[i] = "".join(subparts) + from sage.misc.latex_macros import sage_configurable_latex_macros from sage.misc.latex import _Latex_prefs latex_string = ''.join( @@ -351,15 +349,16 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): [_Latex_prefs._option['macros']] + parts ) + mathjax_string = latex_string.replace('<', '<') if mode == 'display': html = r'\[{0}\]' elif mode == 'inline': html = r'\({0}\)' elif mode == 'plain': - return latex_string + return mathjax_string else: raise ValueError("mode must be either 'display', 'inline', or 'plain'") - return MathJaxExpr(html.format(latex_string)) + return MathJaxExpr(html.format(mathjax_string)) class HTMLFragmentFactory(SageObject): @@ -412,7 +411,7 @@ def __call__(self, obj, concatenate=True, strict=False): sagemath sage: html('sagemath', strict=True) - \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|sagemath|\] + \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|sagemath|\] """ # string obj is interpreted as an HTML in not strict mode if isinstance(obj, str) and not strict: diff --git a/src/sage/repl/rich_output/output_browser.py b/src/sage/repl/rich_output/output_browser.py index 2746e3dff8e..3d7cda599a1 100644 --- a/src/sage/repl/rich_output/output_browser.py +++ b/src/sage/repl/rich_output/output_browser.py @@ -40,10 +40,12 @@ def __init__(self, html): # pdf export of a notebook m = latex_re.match(html) if m: + mathjax_string = m.group('latex') + latex_string = mathjax_string.replace('<', '<') if m.group('mathstart') == r'\[' and m.group('mathend') == r'\]': - self.latex = OutputBuffer('$$' + m.group('latex') + '$$') + self.latex = OutputBuffer('$$' + latex_string + '$$') else: - self.latex = OutputBuffer('$' + m.group('latex') + '$') + self.latex = OutputBuffer('$' + latex_string + '$') else: self.latex = None From ba099ec02228f44a7923a81f27aaad760e948fff Mon Sep 17 00:00:00 2001 From: Kwankyu Lee Date: Fri, 12 Nov 2021 23:53:45 +0900 Subject: [PATCH 357/378] Fix doctests --- src/sage/misc/html.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/html.py b/src/sage/misc/html.py index 237177337fe..cc310888512 100644 --- a/src/sage/misc/html.py +++ b/src/sage/misc/html.py @@ -294,7 +294,7 @@ def eval(self, x, globals=None, locals=None, mode='display', combine_all=False): sage: MathJax().eval(3, mode='inline') \(\newcommand{\Bold}[1]{\mathbf{#1}}3\) sage: MathJax().eval(type(3), mode='inline') - \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb||\) + \(\newcommand{\Bold}[1]{\mathbf{#1}}\verb|<class|\verb| |\verb|'sage.rings.integer.Integer'>|\) """ # Get a regular LaTeX representation of x x = latex(x, combine_all=combine_all) @@ -411,7 +411,7 @@ def __call__(self, obj, concatenate=True, strict=False): sagemath sage: html('sagemath', strict=True) - \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|sagemath|\] + \[\newcommand{\Bold}[1]{\mathbf{#1}}\verb|<a|\verb| |\verb|href="http://sagemath.org">sagemath</a>|\] """ # string obj is interpreted as an HTML in not strict mode if isinstance(obj, str) and not strict: From f061fbc8d37321ab931e1bdb74bf8ffc8fb216db Mon Sep 17 00:00:00 2001 From: Isuru Fernando Date: Fri, 12 Nov 2021 09:07:08 -0800 Subject: [PATCH 358/378] add memory_allocator/distros/conda.txt --- build/pkgs/memory_allocator/distros/conda.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 build/pkgs/memory_allocator/distros/conda.txt diff --git a/build/pkgs/memory_allocator/distros/conda.txt b/build/pkgs/memory_allocator/distros/conda.txt new file mode 100644 index 00000000000..8dda733d5a5 --- /dev/null +++ b/build/pkgs/memory_allocator/distros/conda.txt @@ -0,0 +1 @@ +memory-allocator From 6ec717a56dcb0fd629ca850d9b9391ea8d96ccac Mon Sep 17 00:00:00 2001 From: Release Manager Date: Fri, 12 Nov 2021 23:32:35 +0100 Subject: [PATCH 359/378] Updated SageMath version to 9.5.beta6 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 4a9c0e96236..489c739efdd 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.5.beta5", - "version": "9.5.beta5", + "title": "sagemath/sage: 9.5.beta6", + "version": "9.5.beta6", "upload_type": "software", - "publication_date": "2021-10-28", + "publication_date": "2021-11-12", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.5.beta5", + "identifier": "https://github.com/sagemath/sage/tree/9.5.beta6", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index c79c2d06798..b437f328147 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.5.beta5, Release Date: 2021-10-28 +SageMath version 9.5.beta6, Release Date: 2021-11-12 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 1b37654eb3b..b05711699f4 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=1121284fc8328593926f7f71f8fe35521349311f -md5=7b880b7643f2dc04cd937aa05c9d3ebd -cksum=3817986496 +sha1=bdfd5753a2548365230216455d9a543fe238f092 +md5=49ffa01e32a876dd4feea975d822351e +cksum=3517586928 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index c5852d555c3..d6c01edf77e 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -ce02f46a8014a2b7f52ba2fbf6c136d6c3b8837c +fda367752b5e7afa3ec0fda483b162645192e008 diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index 2b08eebb761..a72129631b5 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.5.beta5 +9.5.beta6 diff --git a/src/VERSION.txt b/src/VERSION.txt index 2b08eebb761..a72129631b5 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.5.beta5 +9.5.beta6 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index ed215d6aeb0..547dbe14054 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.5.beta5' -SAGE_RELEASE_DATE='2021-10-28' -SAGE_VERSION_BANNER='SageMath version 9.5.beta5, Release Date: 2021-10-28' +SAGE_VERSION='9.5.beta6' +SAGE_RELEASE_DATE='2021-11-12' +SAGE_VERSION_BANNER='SageMath version 9.5.beta6, Release Date: 2021-11-12' diff --git a/src/sage/version.py b/src/sage/version.py index a0bf87ed037..7785a1ebba4 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.5.beta5' -date = '2021-10-28' -banner = 'SageMath version 9.5.beta5, Release Date: 2021-10-28' +version = '9.5.beta6' +date = '2021-11-12' +banner = 'SageMath version 9.5.beta6, Release Date: 2021-11-12' From f546c3c34a3909bfbcdbd28e209847f91e6550fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 13 Nov 2021 09:52:15 +0100 Subject: [PATCH 360/378] fix E713 and E714 in coding/ --- src/sage/coding/grs_code.py | 7 ++++--- src/sage/coding/linear_code.py | 6 +++--- src/sage/coding/linear_code_no_metric.py | 12 +++++------ src/sage/coding/linear_rank_metric.py | 6 +++--- .../coding/relative_finite_field_extension.py | 21 +++++++++---------- src/sage/coding/subfield_subcode.py | 2 +- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/sage/coding/grs_code.py b/src/sage/coding/grs_code.py index 74c59ffec89..1bdbc70727f 100644 --- a/src/sage/coding/grs_code.py +++ b/src/sage/coding/grs_code.py @@ -1965,13 +1965,14 @@ def decode_to_message(self, word_and_erasure_vector): n, k = C.length(), C.dimension() if word not in C.ambient_space(): raise ValueError("The word to decode has to be in the ambient space of the code") - if not erasure_vector in VectorSpace(GF(2), n): + if erasure_vector not in VectorSpace(GF(2), n): raise ValueError("The erasure vector has to be a vector over GF(2) of the same length as the code") if erasure_vector.hamming_weight() >= self.code().minimum_distance(): raise DecodingError("Too many erasures in the received word") - punctured_word = vector(self.code().base_ring(), [word[i] for i in - range(len(word)) if erasure_vector[i]!=1]) + punctured_word = vector(self.code().base_ring(), + [word[i] for i in range(len(word)) + if not erasure_vector[i]]) C1_length = len(punctured_word) if C1_length == k: return self.connected_encoder().unencode_nocheck(word) diff --git a/src/sage/coding/linear_code.py b/src/sage/coding/linear_code.py index 643e7239460..c335f04e1a9 100644 --- a/src/sage/coding/linear_code.py +++ b/src/sage/coding/linear_code.py @@ -2309,12 +2309,12 @@ def __init__(self, generator, d=None): try: basis = None - if hasattr(generator,"nrows"): # generator matrix case + if hasattr(generator, "nrows"): # generator matrix case if generator.rank() < generator.nrows(): basis = generator.row_space().basis() else: - basis = generator.basis() # vector space etc. case - if not basis is None: + basis = generator.basis() # vector space etc. case + if basis is not None: from sage.matrix.constructor import matrix generator = matrix(base_ring, basis) if generator.nrows() == 0: diff --git a/src/sage/coding/linear_code_no_metric.py b/src/sage/coding/linear_code_no_metric.py index 85fd48f3226..9e4b6115ad3 100644 --- a/src/sage/coding/linear_code_no_metric.py +++ b/src/sage/coding/linear_code_no_metric.py @@ -179,9 +179,9 @@ def __init__(self, base_field, length, default_encoder_name, default_decoder_nam if not base_field.is_field(): raise ValueError("'base_field' must be a field (and {} is not one)".format(base_field)) - if not default_encoder_name in self._registered_encoders: + if default_encoder_name not in self._registered_encoders: raise ValueError("You must set a valid encoder as default encoder for this code, by filling in the dictionary of registered encoders") - if not default_decoder_name in self._registered_decoders: + if default_decoder_name not in self._registered_decoders: raise ValueError("You must set a valid decoder as default decoder for this code, by filling in the dictionary of registered decoders") #if not self.dimension() <= length: @@ -509,7 +509,7 @@ def __contains__(self, v): sage: vector((1, 0, 0, 0, 0, 1/2, 1)) in C # indirect doctest False """ - if not v in self.ambient_space() or len(v) != self.length(): + if v not in self.ambient_space() or len(v) != self.length(): return False return self.syndrome(v) == 0 @@ -1296,13 +1296,13 @@ def systematic_permutation(self): n = self.code().length() systematic_positions = self.systematic_positions() k = len(systematic_positions) - lp = [ None ]*n - for (i,j) in zip(range(k), systematic_positions): + lp = [None] * n + for (i, j) in zip(range(k), systematic_positions): lp[i] = j j = k set_sys_pos = set(systematic_positions) for i in range(n): - if not i in set_sys_pos: + if i not in set_sys_pos: lp[j] = i j += 1 from sage.combinat.permutation import Permutation diff --git a/src/sage/coding/linear_rank_metric.py b/src/sage/coding/linear_rank_metric.py index f746acf3c91..c06b16aa05b 100644 --- a/src/sage/coding/linear_rank_metric.py +++ b/src/sage/coding/linear_rank_metric.py @@ -694,12 +694,12 @@ def __init__(self, generator, sub_field=None, basis=None): try: gen_basis = None - if hasattr(generator,"nrows"): # generator matrix case + if hasattr(generator, "nrows"): # generator matrix case if generator.rank() < generator.nrows(): gen_basis = generator.row_space().basis() else: - gen_basis = generator.basis() # vector space etc. case - if not gen_basis is None: + gen_basis = generator.basis() # vector space etc. case + if gen_basis is not None: from sage.matrix.constructor import matrix generator = matrix(base_field, gen_basis) if generator.nrows() == 0: diff --git a/src/sage/coding/relative_finite_field_extension.py b/src/sage/coding/relative_finite_field_extension.py index 2319d708f85..1a329624cce 100644 --- a/src/sage/coding/relative_finite_field_extension.py +++ b/src/sage/coding/relative_finite_field_extension.py @@ -120,7 +120,7 @@ def __init__(self, absolute_field, relative_field, embedding=None): if not s.divides(sm): raise ValueError("relative_field has to be a subfield of absolute_field") H = Hom(relative_field, absolute_field) - if embedding is not None and not embedding in H: + if embedding is not None and embedding not in H: raise ValueError("embedding has to be an embedding from relative_field to absolute_field") elif embedding is not None: self._phi = embedding @@ -231,7 +231,7 @@ def _flattened_relative_field_representation(self, b): sage: FE._flattened_relative_field_representation(b) (1, 0, 1, 1) """ - if not b in self.absolute_field(): + if b not in self.absolute_field(): raise ValueError("The input has to be an element of the absolute field") return self._representation_matrix() * vector(b) @@ -254,19 +254,18 @@ def relative_field_representation(self, b): sage: FE.relative_field_representation(b) (1, a + 1) """ - if not b in self.absolute_field(): + if b not in self.absolute_field(): raise ValueError("The input has to be an element of the absolute field") s = self.relative_field_degree() if s == 1: return vector(b) - else: - Fq = self.relative_field() - vect = self._flattened_relative_field_representation(b) - sm = self.absolute_field_degree() - list_elts = [] - for i in range(0, sm, s): - list_elts.append(Fq(vect[i:i+s])) - return vector(Fq, list_elts) + Fq = self.relative_field() + vect = self._flattened_relative_field_representation(b) + sm = self.absolute_field_degree() + list_elts = [] + for i in range(0, sm, s): + list_elts.append(Fq(vect[i:i + s])) + return vector(Fq, list_elts) def absolute_field_representation(self, a): r""" diff --git a/src/sage/coding/subfield_subcode.py b/src/sage/coding/subfield_subcode.py index c08d27a4cb3..ed7b18d7a90 100644 --- a/src/sage/coding/subfield_subcode.py +++ b/src/sage/coding/subfield_subcode.py @@ -86,7 +86,7 @@ def __init__(self, original_code, subfield, embedding=None): raise ValueError("subfield has to be a subfield of the base field of the original code") self._original_code = original_code H = Hom(subfield, F) - if embedding is not None and not embedding in H: + if embedding is not None and embedding not in H: raise ValueError("embedding has to be an embedding from subfield to original_code's base field") elif embedding is not None: self._embedding = RelativeFiniteFieldExtension(F, subfield, embedding) From 2a03332229b3dba97f88383ae7b2cdc516f87e81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sat, 13 Nov 2021 11:22:21 +0100 Subject: [PATCH 361/378] fix E713 and E714 in graphs --- src/sage/graphs/bipartite_graph.py | 4 +-- src/sage/graphs/digraph_generators.py | 4 +-- src/sage/graphs/generators/chessboard.py | 6 ++-- src/sage/graphs/generators/smallgraphs.py | 2 +- src/sage/graphs/generic_graph.py | 42 +++++++++++------------ src/sage/graphs/graph.py | 7 ++-- src/sage/graphs/graph_database.py | 2 +- src/sage/graphs/isgci.py | 2 +- src/sage/graphs/pq_trees.py | 2 +- 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/src/sage/graphs/bipartite_graph.py b/src/sage/graphs/bipartite_graph.py index e95565a9e1b..b782aa989ed 100644 --- a/src/sage/graphs/bipartite_graph.py +++ b/src/sage/graphs/bipartite_graph.py @@ -1757,7 +1757,7 @@ def vertex_cover(self, algorithm="Konig", value_only=False, Y = set() for u in X: for v in self.neighbors(u): - if not v in Z and not M.has_edge(u, v): + if v not in Z and not M.has_edge(u, v): Y.add(v) Z.update(Y) @@ -1765,7 +1765,7 @@ def vertex_cover(self, algorithm="Konig", value_only=False, X = set() for u in Y: for v in M.neighbor_iterator(u): - if not v in Z: + if v not in Z: X.add(v) Z.update(X) diff --git a/src/sage/graphs/digraph_generators.py b/src/sage/graphs/digraph_generators.py index 921aa754bb5..45bf0bb7f5b 100644 --- a/src/sage/graphs/digraph_generators.py +++ b/src/sage/graphs/digraph_generators.py @@ -763,7 +763,7 @@ def Circulant(self, n, integers): # Bad input and loops loops = False for i in integers: - if not i in ZZ: + if i not in ZZ: raise ValueError("the list must contain only integers") if not i % n: loops = True @@ -1456,7 +1456,7 @@ def RandomDirectedGNM(self, n, m, loops=False): u = int(rand.random() * n) v = int(rand.random() * n) - if (u != v or loops) and (not v in adj[u]): + if (u != v or loops) and (v not in adj[u]): adj[u][v] = 1 m -= 1 if not is_dense: diff --git a/src/sage/graphs/generators/chessboard.py b/src/sage/graphs/generators/chessboard.py index 9a10f7e8ada..50f82d47dd1 100644 --- a/src/sage/graphs/generators/chessboard.py +++ b/src/sage/graphs/generators/chessboard.py @@ -154,14 +154,14 @@ def ChessboardGraphGenerator(dim_list, rook=True, rook_radius=None, if rook: if rook_radius is None: rook_radius = max(dim) - elif not rook_radius in ZZ or rook_radius < 1: + elif rook_radius not in ZZ or rook_radius < 1: raise ValueError('the rook_radius must be either None or have an integer value >= 1') if bishop: if bishop_radius is None: bishop_radius = max(dim) - elif not bishop_radius in ZZ or bishop_radius < 1: + elif bishop_radius not in ZZ or bishop_radius < 1: raise ValueError('the bishop_radius must be either None or have an integer value >= 1') - if knight and ( not knight_x in ZZ or not knight_y in ZZ or knight_x < 1 or knight_y < 1 ): + if knight and (knight_x not in ZZ or knight_y not in ZZ or knight_x < 1 or knight_y < 1): raise ValueError('the knight_x and knight_y values must be integers of value >= 1') # We build the set of vertices of the d-dimensional chessboard diff --git a/src/sage/graphs/generators/smallgraphs.py b/src/sage/graphs/generators/smallgraphs.py index 072812c75c4..5a87ae14cf5 100644 --- a/src/sage/graphs/generators/smallgraphs.py +++ b/src/sage/graphs/generators/smallgraphs.py @@ -3571,7 +3571,7 @@ def McLaughlinGraph(): g = Graph() for b in B: for x in range(1, 23): - if not x in b: + if x not in b: g.add_edge(b, x) for b in C: diff --git a/src/sage/graphs/generic_graph.py b/src/sage/graphs/generic_graph.py index 0df574c5721..93264c6a4fd 100644 --- a/src/sage/graphs/generic_graph.py +++ b/src/sage/graphs/generic_graph.py @@ -1777,13 +1777,13 @@ def to_dictionary(self, edge_labels=False, multiple_edges=False): if self.is_directed(): for u, v, l in self.edge_iterator(): - if not v in d[u]: + if v not in d[u]: d[u][v] = [] d[u][v].append(l) else: for u, v, l in self.edge_iterator(): - if not v in d[u]: + if v not in d[u]: d[u][v] = [] d[v][u] = [] @@ -3105,7 +3105,7 @@ def allow_multiple_edges(self, new, check=True, keep_label='any'): sage: D.edges() [(0, 1, None)] """ - if not keep_label in ['any', 'min', 'max']: + if keep_label not in ['any', 'min', 'max']: raise ValueError("variable keep_label must be 'any', 'min', or 'max'") # TODO: this should be much faster for c_graphs, but for now we just do this @@ -4686,7 +4686,7 @@ def cycle_basis(self, output='vertex'): [(4, 3, 'e'), (3, 2, 'b'), (2, 1, 'a'), (1, 4, 'f')]] """ - if not output in ['vertex', 'edge']: + if output not in ['vertex', 'edge']: raise ValueError('output must be either vertex or edge') if self.is_directed(): @@ -7673,7 +7673,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, if use_edge_labels or algorithm is None: # We force the algorithm to 'MILP' algorithm = 'MILP' - elif not algorithm in ['MILP', 'backtrack']: + elif algorithm not in ['MILP', 'backtrack']: raise ValueError("algorithm must be either 'backtrack' or 'MILP'") if self.order() < 2: @@ -7704,7 +7704,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, elif len(zeros) == 1: if new_s is None: new_s = zeros.pop() - elif not new_s in zeros: + elif new_s not in zeros: return (0, None) if use_edge_labels else None zeros = [u for u in g if not g.out_degree(u)] @@ -7713,7 +7713,7 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, elif len(zeros) == 1: if new_t is None: new_t = zeros.pop() - elif not new_t in zeros: + elif new_t not in zeros: return (0, None) if use_edge_labels else None else: @@ -7725,28 +7725,27 @@ def hamiltonian_path(self, s=None, t=None, use_edge_labels=False, return (0, None) if use_edge_labels else None elif len(ones) == 2: - if not new_s is None and not new_s in ones: + if new_s is not None and new_s not in ones: return (0, None) if use_edge_labels else None - if not new_t is None and not new_t in ones: + if new_t is not None and new_t not in ones: return (0, None) if use_edge_labels else None # Set new_s and new_t if possible if new_s is None and new_t is None: new_s,new_t = ones - elif not new_s is None and new_t is None: + elif new_s is not None and new_t is None: new_t = ones[1] if new_s == ones[0] else ones[0] - elif new_s is None and not new_t is None: + elif new_s is None and new_t is not None: new_s = ones[1] if new_t == ones[0] else ones[0] elif len(ones) == 1: - if not new_s is None and not new_t is None and not (new_s in ones or new_t in ones): + if new_s is not None and new_t is not None and not (new_s in ones or new_t in ones): return (0, None) if use_edge_labels else None - elif new_s is None and (new_t is None or (not new_t is None and not new_t in ones)): + elif new_s is None and (new_t is None or (new_t is not None and new_t not in ones)): new_s = ones.pop() - elif new_t is None and not new_s is None and not new_s in ones: + elif new_t is None and new_s is not None and new_s not in ones: new_t = ones.pop() - if not use_edge_labels and algorithm == "backtrack": path = g.longest_path(s=new_s, t=new_t, algorithm="backtrack") return path if path.order() == g.order() else None @@ -10918,7 +10917,8 @@ def merge_vertices(self, vertices): if self.is_directed(): out_edges = self.edge_boundary(vertices) - in_edges = self.edge_boundary([v for v in self if not v in vertices]) + in_edges = self.edge_boundary([v for v in self + if v not in vertices]) self.delete_vertices(vertices[1:]) self.add_edges((u, v0, l) for (u0, v0, l) in out_edges if u0 != u) self.add_edges((v0, u, l) for (v0, u0, l) in in_edges if u0 != u) @@ -13619,7 +13619,7 @@ def is_chordal(self, certificate=False, algorithm="B"): nb1 = [u for u in g.neighbor_iterator(v) if pos_in_peo[u] > pos_in_peo[v]] for xi in nb1: for yi in nb1: - if not yi in neighbors_subsets[xi]: + if yi not in neighbors_subsets[xi]: new_tup = (pos_in_peo[xi], pos_in_peo[yi]) if max_tup < new_tup: max_tup = new_tup @@ -13645,7 +13645,7 @@ def is_chordal(self, certificate=False, algorithm="B"): # ---------------- # 1- The graph is not chordal - if not hole is None: + if hole is not None: # There was a bug there once, so it's better to check the # answer is valid, especially when it is so cheap ;-) @@ -14478,7 +14478,7 @@ def clustering_average(self, implementation=None): else: implementation = 'sparse_copy' - if not implementation in ['networkx', 'boost', 'dense_copy', 'sparse_copy']: + if implementation not in ['networkx', 'boost', 'dense_copy', 'sparse_copy']: raise ValueError("the implementation can only be 'networkx', " "'boost', 'sparse_copy', 'dense_copy' or None") @@ -14602,7 +14602,7 @@ def clustering_coeff(self, else: implementation = 'sparse_copy' - if not implementation in ['networkx', 'boost', 'dense_copy', 'sparse_copy']: + if implementation not in ['networkx', 'boost', 'dense_copy', 'sparse_copy']: raise ValueError("the implementation can only be 'networkx', " "'boost', 'sparse_copy', 'dense_copy' or None") @@ -19105,7 +19105,7 @@ def layout_extend_randomly(self, pos, dim=2): # Check each vertex position is in pos, add position randomly within the # plot range if none is defined for v in self: - if not v in pos: + if v not in pos: pos[v] = [xmin + dx * random(), ymin + dy * random()] return pos diff --git a/src/sage/graphs/graph.py b/src/sage/graphs/graph.py index 75fb6241f23..fe601ddeea9 100644 --- a/src/sage/graphs/graph.py +++ b/src/sage/graphs/graph.py @@ -1530,7 +1530,7 @@ def is_tree(self, certificate=False, output='vertex'): sage: G.is_tree(certificate=True, output='edge') (False, [(0, 0, None)]) """ - if not output in ['vertex', 'edge']: + if output not in ['vertex', 'edge']: raise ValueError('output must be either vertex or edge') if not self.order() or not self.is_connected(): @@ -6499,8 +6499,7 @@ def independent_set(self, algorithm="Cliquer", value_only=False, reduction_rules return self.order() - my_cover else: my_cover = set(my_cover) - return [u for u in self if not u in my_cover] - + return [u for u in self if u not in my_cover] @doc_index("Algorithmically hard stuff") @rename_keyword(deprecation=32238, verbosity='verbose') @@ -6757,7 +6756,7 @@ def vertex_cover(self, algorithm="Cliquer", value_only=False, if value_only: size_cover_g = g.order() - len(independent) else: - cover_g = set(uu for uu in g if not uu in independent) + cover_g = set(uu for uu in g if uu not in independent) elif algorithm == "MILP": diff --git a/src/sage/graphs/graph_database.py b/src/sage/graphs/graph_database.py index c7c6fe18cca..fc114c0afec 100644 --- a/src/sage/graphs/graph_database.py +++ b/src/sage/graphs/graph_database.py @@ -430,7 +430,7 @@ class located in :mod:`sage.databases.sql_db` to make the query for key in kwds: # check validity - if not key in valid_kwds: + if key not in valid_kwds: raise KeyError('%s is not a valid key for this database.'%str(key)) # designate a query_dict diff --git a/src/sage/graphs/isgci.py b/src/sage/graphs/isgci.py index 4ddd64d2171..99f90f76179 100644 --- a/src/sage/graphs/isgci.py +++ b/src/sage/graphs/isgci.py @@ -456,7 +456,7 @@ class represented by ``gc_id`` ?* self._name = name self._gc_id = gc_id - if not recognition_function is None: + if recognition_function is not None: self._recognition_function = recognition_function def _repr_(self): diff --git a/src/sage/graphs/pq_trees.py b/src/sage/graphs/pq_trees.py index 7dfbe72349f..6a36cfa8886 100644 --- a/src/sage/graphs/pq_trees.py +++ b/src/sage/graphs/pq_trees.py @@ -220,7 +220,7 @@ def __init__(self, seq): if isinstance(e, list): e = Set(e) - if not e in self._children: + if e not in self._children: self._children.append(e) def reverse(self): From 6ce2bedfabdf3f5fbf0f6b776baa222005e8de7a Mon Sep 17 00:00:00 2001 From: Miguel Marco Date: Sat, 13 Nov 2021 23:12:58 +0100 Subject: [PATCH 362/378] Adapt overflow doctest to 32 bits --- src/sage/rings/polynomial/polydict.pyx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/polynomial/polydict.pyx b/src/sage/rings/polynomial/polydict.pyx index 651d4041272..95785f04521 100644 --- a/src/sage/rings/polynomial/polydict.pyx +++ b/src/sage/rings/polynomial/polydict.pyx @@ -1628,7 +1628,8 @@ cdef class ETuple: sage: y^(2^32) Traceback (most recent call last): ... - OverflowError: exponent overflow (...) + OverflowError: exponent overflow (...) # 64-bit + OverflowError: Python int too large to convert to C unsigned long # 32-bit """ if self._length!=other._length: raise ArithmeticError From feff55e50727d51b270320518ebeed932fcd1823 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Wed, 10 Nov 2021 17:38:20 +0000 Subject: [PATCH 363/378] fixes for arb's incomplete gamma and erfi also add a bit of docs --- src/sage/rings/real_arb.pyx | 43 ++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index c616e9cd304..87085ca091d 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3468,9 +3468,27 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res - def gamma(self): + def erfi(self): """ - Return the image of this ball by the Euler Gamma function. + Imaginary error function. + + EXAMPLES:: + + sage: RBF(1/2).erfi() + [0.614952094696511 +/- 2.22e-16] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_erfi(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + def gamma(self, a=None): + """ + Image of this ball by the (incomplete) Euler Gamma function + + For `a` real, return the upper incomplete Gamma function + of `\Gamma(self,a)`. For integer and rational arguments, :meth:`~sage.rings.real_arb.RealBallField.gamma` may be faster. @@ -3479,14 +3497,27 @@ cdef class RealBall(RingElement): sage: RBF(1/2).gamma() [1.772453850905516 +/- ...e-16] + sage: RBF(gamma(3/2,sqrt(2))) + [0.37118875695353 +/- 3.29e-15] + sage: RBF(3/2).gamma(sqrt(2)) + [0.37118875695353 +/- 3.29e-15] + sage: RBF(gamma(3/2,RIF(sqrt(2)))) + [0.37118875695353 +/- 3.15e-15] .. SEEALSO:: :meth:`~sage.rings.real_arb.RealBallField.gamma` """ + cdef RealBall a_ball cdef RealBall res = self._new() - if _do_sig(prec(self)): sig_on() - arb_gamma(res.value, self.value, prec(self)) - if _do_sig(prec(self)): sig_off() + if a is None: + if _do_sig(prec(self)): sig_on() + arb_gamma(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + else: + if _do_sig(prec(self)): sig_on() + a_ball = RBF(a) + arb_hypgeom_gamma_upper(res.value, self.value, a_ball.value, 0, prec(self)) + if _do_sig(prec(self)): sig_off() return res def log_gamma(self): @@ -3569,6 +3600,8 @@ cdef class RealBall(RingElement): For ``a = 1`` (or ``a = None``), this computes the Riemann zeta function. + Otherwise, it computes Hurwitz zeta function. + Use :meth:`RealBallField.zeta` to compute the Riemann zeta function of a small integer without first converting it to a real ball. From 2a4bf9647b36f78ad93e6220a93cad72528dcb15 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 11 Nov 2021 11:37:40 +0000 Subject: [PATCH 364/378] wrap arb's Ei --- src/sage/rings/real_arb.pyx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 87085ca091d..642abc9742e 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3483,6 +3483,21 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + def Ei(self): + """ + Exponential integral + + EXAMPLES:: + + sage: RBF(1).Ei() + [1.89511781635594 +/- 4.94e-15] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_ei(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + def gamma(self, a=None): """ Image of this ball by the (incomplete) Euler Gamma function From b5892c9e57d87bd825b69a8e8bd8e0f8ae2034f5 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 11 Nov 2021 12:14:28 +0000 Subject: [PATCH 365/378] wrap arb's gamma_inc_lower --- src/sage/rings/real_arb.pyx | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 642abc9742e..e0275e5a3d2 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3500,7 +3500,7 @@ cdef class RealBall(RingElement): def gamma(self, a=None): """ - Image of this ball by the (incomplete) Euler Gamma function + Image of this ball by the (upper incomplete) Euler Gamma function For `a` real, return the upper incomplete Gamma function of `\Gamma(self,a)`. @@ -3535,6 +3535,28 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + def gamma_inc_lower(self, a): + """ + Image of this ball by the lower incomplete Euler Gamma function + + For `a` real, return the lower incomplete Gamma function + of `\Gamma(self,a)`. + + EXAMPLES:: + + sage: RBF(gamma_inc_lower(1/2,sqrt(2))) + [1.60830863772925 +/- 2.75e-15] + sage: RBF(7/2).gamma_inc_lower(5) + [2.69665515418630 +/- 9.50e-15] + """ + cdef RealBall a_ball + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + a_ball = RBF(a) + arb_hypgeom_gamma_lower(res.value, self.value, a_ball.value, 0, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + def log_gamma(self): """ Return the image of this ball by the logarithmic Gamma function. From 335ccc78b3ecdf1722a309bcd2f99fdc79a801f0 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 11 Nov 2021 16:25:38 +0000 Subject: [PATCH 366/378] wrapped arb chi, shi, li, Li --- src/sage/rings/real_arb.pyx | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index e0275e5a3d2..974282d7328 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3470,7 +3470,7 @@ cdef class RealBall(RingElement): def erfi(self): """ - Imaginary error function. + Imaginary error function EXAMPLES:: @@ -3485,7 +3485,7 @@ cdef class RealBall(RingElement): def Ei(self): """ - Exponential integral + Exponential integral EXAMPLES:: @@ -3498,6 +3498,97 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + def Si(self): + """ + Sine integral + + EXAMPLES:: + + sage: RBF(1).Si() + [0.946083070367183 +/- 9.22e-16] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_si(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + def Ci(self): + """ + Cosine integral + + EXAMPLES:: + + sage: RBF(1).Ci() + [0.337403922900968 +/- 3.25e-16] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_ci(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + + def Shi(self): + """ + Hyperbolic sine integral + + EXAMPLES:: + + sage: RBF(1).Shi() + [1.05725087537573 +/- 2.77e-15] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_shi(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + def Chi(self): + """ + Hyperbolic cosine integral + + EXAMPLES:: + + sage: RBF(1).Chi() + [0.837866940980208 +/- 4.72e-16] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_chi(res.value, self.value, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + def li(self): + """ + Logarithmic integral + + EXAMPLES:: + + sage: RBF(3).li() + [2.16358859466719 +/- 4.72e-15] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_li(res.value, self.value, 0, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + + def Li(self): + """ + Offset logarithmic integral + + EXAMPLES:: + + sage: RBF(3).Li() + [1.11842481454970 +/- 7.61e-15] + """ + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + arb_hypgeom_li(res.value, self.value, 1, prec(self)) + if _do_sig(prec(self)): sig_off() + return res + def gamma(self, a=None): """ Image of this ball by the (upper incomplete) Euler Gamma function From 8a532ebf510ad650addd0375daf7801f3a914a90 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 11 Nov 2021 17:46:58 +0000 Subject: [PATCH 367/378] wrapped arb's complete beta function there are issues with Sage's beta being also implemented via pynac, so RBF(beta(a,b)) does not work, one needs RBF(a).beta(b) instead. --- src/sage/rings/real_arb.pyx | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 974282d7328..18cc3a8be69 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3588,6 +3588,32 @@ cdef class RealBall(RingElement): arb_hypgeom_li(res.value, self.value, 1, prec(self)) if _do_sig(prec(self)): sig_off() return res + + def beta(self, a): + """ + Image of this ball by the complete beta function + + For `a` real, return the complete Gamma function `B(self,a)`. + + EXAMPLES:: + + sage: RBF(sin(3)).beta(sqrt(2/3)) + [7.407661629415 +/- 1.26e-13] + + .. TODO:: + + At the moment RBF(beta(a,b)) does not work, one needs + RBF(a).beta(b) for this to work. See :trac:`32851` + and :trac:`24641`. + """ + cdef RealBall a_ball, aone + cdef RealBall res = self._new() + if _do_sig(prec(self)): sig_on() + a_ball = RBF(a) + aone = RBF(1) + arb_hypgeom_beta_lower(res.value, self.value, a_ball.value, aone.value, 0, prec(self)) + if _do_sig(prec(self)): sig_off() + return res def gamma(self, a=None): """ From 03e7d80d40cd04ebf431073e50cef92393c71032 Mon Sep 17 00:00:00 2001 From: Dima Pasechnik Date: Thu, 11 Nov 2021 20:17:05 +0000 Subject: [PATCH 368/378] add missing article and gamma_inc defn and test --- src/sage/rings/real_arb.pyx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 18cc3a8be69..9a9a465377e 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3631,7 +3631,7 @@ cdef class RealBall(RingElement): [1.772453850905516 +/- ...e-16] sage: RBF(gamma(3/2,sqrt(2))) [0.37118875695353 +/- 3.29e-15] - sage: RBF(3/2).gamma(sqrt(2)) + sage: RBF(3/2).gamma_inc(sqrt(2)) [0.37118875695353 +/- 3.29e-15] sage: RBF(gamma(3/2,RIF(sqrt(2)))) [0.37118875695353 +/- 3.15e-15] @@ -3652,6 +3652,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + gamma_inc = gamma + def gamma_inc_lower(self, a): """ Image of this ball by the lower incomplete Euler Gamma function @@ -3754,7 +3756,7 @@ cdef class RealBall(RingElement): For ``a = 1`` (or ``a = None``), this computes the Riemann zeta function. - Otherwise, it computes Hurwitz zeta function. + Otherwise, it computes the Hurwitz zeta function. Use :meth:`RealBallField.zeta` to compute the Riemann zeta function of a small integer without first converting it to a real ball. From 2d82f61a1533b70b25baa9c840ecc2d96b295b87 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Fri, 12 Nov 2021 10:02:34 +0100 Subject: [PATCH 369/378] #32851 fix conversions --- src/sage/rings/real_arb.pyx | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index 9a9a465377e..a8fdd633206 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3591,14 +3591,16 @@ cdef class RealBall(RingElement): def beta(self, a): """ - Image of this ball by the complete beta function + Image of this ball by the complete beta function For `a` real, return the complete Gamma function `B(self,a)`. EXAMPLES:: - sage: RBF(sin(3)).beta(sqrt(2/3)) - [7.407661629415 +/- 1.26e-13] + sage: RBF(sin(3)).beta(RBF(2/3).sqrt()) + [7.407661629415 +/- 1.07e-13] + sage: RealBallField(100)(7/2).beta(1) + [0.28571428571428571428571428571 +/- 5.23e-30] .. TODO:: @@ -3609,8 +3611,8 @@ cdef class RealBall(RingElement): cdef RealBall a_ball, aone cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() - a_ball = RBF(a) - aone = RBF(1) + a_ball = self._parent.coerce(a) + aone = self._parent.one() arb_hypgeom_beta_lower(res.value, self.value, a_ball.value, aone.value, 0, prec(self)) if _do_sig(prec(self)): sig_off() return res @@ -3629,15 +3631,18 @@ cdef class RealBall(RingElement): sage: RBF(1/2).gamma() [1.772453850905516 +/- ...e-16] - sage: RBF(gamma(3/2,sqrt(2))) - [0.37118875695353 +/- 3.29e-15] - sage: RBF(3/2).gamma_inc(sqrt(2)) - [0.37118875695353 +/- 3.29e-15] - sage: RBF(gamma(3/2,RIF(sqrt(2)))) - [0.37118875695353 +/- 3.15e-15] + sage: RBF(gamma(3/2, RBF(2).sqrt())) + [0.37118875695353 +/- 3.00e-15] + sage: RBF(3/2).gamma_inc(RBF(2).sqrt()) + [0.37118875695353 +/- 3.00e-15] .. SEEALSO:: :meth:`~sage.rings.real_arb.RealBallField.gamma` + + TESTS:: + + sage: RealBallField(100).gamma(1/2) + [1.77245385090551602729816748334 +/- 1.90e-30] """ cdef RealBall a_ball cdef RealBall res = self._new() @@ -3647,7 +3652,7 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() else: if _do_sig(prec(self)): sig_on() - a_ball = RBF(a) + a_ball = self._parent.coerce(a) arb_hypgeom_gamma_upper(res.value, self.value, a_ball.value, 0, prec(self)) if _do_sig(prec(self)): sig_off() return res @@ -3663,10 +3668,10 @@ cdef class RealBall(RingElement): EXAMPLES:: - sage: RBF(gamma_inc_lower(1/2,sqrt(2))) - [1.60830863772925 +/- 2.75e-15] - sage: RBF(7/2).gamma_inc_lower(5) - [2.69665515418630 +/- 9.50e-15] + sage: RBF(gamma_inc_lower(1/2, RBF(2).sqrt())) + [1.608308637729248 +/- 8.14e-16] + sage: RealBallField(100)(7/2).gamma_inc_lower(5) + [2.6966551541863035516887949614 +/- 8.91e-29] """ cdef RealBall a_ball cdef RealBall res = self._new() From 8092951b7bd52619405cf90c00f4a4fd1312e331 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Fri, 12 Nov 2021 10:05:47 +0100 Subject: [PATCH 370/378] #32851 update a doctest --- src/sage/symbolic/function.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/symbolic/function.pyx b/src/sage/symbolic/function.pyx index 91c66fc5eff..89cdce56d70 100644 --- a/src/sage/symbolic/function.pyx +++ b/src/sage/symbolic/function.pyx @@ -627,7 +627,7 @@ cdef class Function(SageObject): sage: airy_ai(b) airy_ai([1.500000000 +/- 1.01e-10]) sage: gamma(b, 1) - gamma([1.500000000 +/- 1.01e-10], 1) + [0.50728223 +/- 4.67e-9] sage: hurwitz_zeta(b, b) hurwitz_zeta([1.500000000 +/- 1.01e-10], [1.500000000 +/- 1.01e-10]) sage: hurwitz_zeta(1/2, b) From 3a5d60cb59816538050236ebb3f9c760617601ac Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 14 Nov 2021 10:41:51 +0100 Subject: [PATCH 371/378] #32851 incomplete beta function + minor fixes --- src/sage/libs/arb/arb_hypgeom.pxd | 12 ++++++------ src/sage/rings/real_arb.pyx | 31 +++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/src/sage/libs/arb/arb_hypgeom.pxd b/src/sage/libs/arb/arb_hypgeom.pxd index 627e083bdc9..fb1c40ddaa8 100644 --- a/src/sage/libs/arb/arb_hypgeom.pxd +++ b/src/sage/libs/arb/arb_hypgeom.pxd @@ -30,9 +30,9 @@ cdef extern from "arb_wrap.h": void arb_hypgeom_gamma_lower(arb_t res, const arb_t s, const arb_t z, int regularized, long prec) void _arb_hypgeom_gamma_lower_series(arb_ptr res, const arb_t s, arb_srcptr z, long zlen, int regularized, long n, long prec) void arb_hypgeom_gamma_lower_series(arb_poly_t res, const arb_t s, const arb_poly_t z, int regularized, long n, long prec) - void arb_hypgeom_beta_lower(arb_t res, const arb_t a, const arb_t b, const arb_t z, int regularized, long prec) - void _arb_hypgeom_beta_lower_series(arb_ptr res, const arb_t a, const arb_t b, arb_srcptr z, long zlen, int regularized, long n, long prec) - void arb_hypgeom_beta_lower_series(arb_poly_t res, const arb_t a, const arb_t b, const arb_poly_t z, int regularized, long n, long prec) + void arb_hypgeom_beta_lower(arb_t res, const arb_t a, const arb_t b, const arb_t z, bint regularized, long prec) + void _arb_hypgeom_beta_lower_series(arb_ptr res, const arb_t a, const arb_t b, arb_srcptr z, long zlen, bint regularized, long n, long prec) + void arb_hypgeom_beta_lower_series(arb_poly_t res, const arb_t a, const arb_t b, const arb_poly_t z, bint regularized, long n, long prec) void arb_hypgeom_expint(arb_t res, const arb_t s, const arb_t z, long prec) void arb_hypgeom_ei(arb_t res, const arb_t z, long prec) void _arb_hypgeom_ei_series(arb_ptr res, arb_srcptr z, long zlen, long len, long prec) @@ -49,9 +49,9 @@ cdef extern from "arb_wrap.h": void arb_hypgeom_chi(arb_t res, const arb_t z, long prec) void _arb_hypgeom_chi_series(arb_ptr res, arb_srcptr z, long zlen, long len, long prec) void arb_hypgeom_chi_series(arb_poly_t res, const arb_poly_t z, long len, long prec) - void arb_hypgeom_li(arb_t res, const arb_t z, int offset, long prec) - void _arb_hypgeom_li_series(arb_ptr res, arb_srcptr z, long zlen, int offset, long len, long prec) - void arb_hypgeom_li_series(arb_poly_t res, const arb_poly_t z, int offset, long len, long prec) + void arb_hypgeom_li(arb_t res, const arb_t z, bint offset, long prec) + void _arb_hypgeom_li_series(arb_ptr res, arb_srcptr z, long zlen, bint offset, long len, long prec) + void arb_hypgeom_li_series(arb_poly_t res, const arb_poly_t z, bint offset, long len, long prec) void arb_hypgeom_bessel_j(arb_t res, const arb_t nu, const arb_t z, long prec) void arb_hypgeom_bessel_y(arb_t res, const arb_t nu, const arb_t z, long prec) void arb_hypgeom_bessel_jy(arb_t res1, arb_t res2, const arb_t nu, const arb_t z, long prec) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index a8fdd633206..b375d2758e7 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3570,7 +3570,7 @@ cdef class RealBall(RingElement): """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() - arb_hypgeom_li(res.value, self.value, 0, prec(self)) + arb_hypgeom_li(res.value, self.value, False, prec(self)) if _do_sig(prec(self)): sig_off() return res @@ -3585,15 +3585,23 @@ cdef class RealBall(RingElement): """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() - arb_hypgeom_li(res.value, self.value, 1, prec(self)) + arb_hypgeom_li(res.value, self.value, True, prec(self)) if _do_sig(prec(self)): sig_off() return res - - def beta(self, a): + + def beta(self, a, z=1): """ - Image of this ball by the complete beta function + (Incomplete) beta function + + INPUT: + + - ``a``, ``z`` (optional) -- real balls - For `a` real, return the complete Gamma function `B(self,a)`. + OUTPUT: + + The lower incomplete beta function `B(self, a, z)`. + + With the default value of ``z``, the complete beta function `B(self, a)`. EXAMPLES:: @@ -3601,6 +3609,8 @@ cdef class RealBall(RingElement): [7.407661629415 +/- 1.07e-13] sage: RealBallField(100)(7/2).beta(1) [0.28571428571428571428571428571 +/- 5.23e-30] + sage: RealBallField(100)(7/2).beta(1, 1/2) + [0.025253813613805268728601584361 +/- 2.53e-31] .. TODO:: @@ -3608,12 +3618,13 @@ cdef class RealBall(RingElement): RBF(a).beta(b) for this to work. See :trac:`32851` and :trac:`24641`. """ - cdef RealBall a_ball, aone + cdef RealBall a_ball, z_ball cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() a_ball = self._parent.coerce(a) - aone = self._parent.one() - arb_hypgeom_beta_lower(res.value, self.value, a_ball.value, aone.value, 0, prec(self)) + z_ball = self._parent.coerce(z) + arb_hypgeom_beta_lower(res.value, self.value, a_ball.value, + z_ball.value, False, prec(self)) if _do_sig(prec(self)): sig_off() return res @@ -3622,7 +3633,7 @@ cdef class RealBall(RingElement): Image of this ball by the (upper incomplete) Euler Gamma function For `a` real, return the upper incomplete Gamma function - of `\Gamma(self,a)`. + `\Gamma(self,a)`. For integer and rational arguments, :meth:`~sage.rings.real_arb.RealBallField.gamma` may be faster. From d9ee935f95001716b8493be7689b4e3b52b1afc5 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 14 Nov 2021 11:43:29 +0100 Subject: [PATCH 372/378] #32869 ComplexBall: rename + add aliases for some special functions for consistency with sage.symbolic (and RealBall after #32851). --- src/sage/rings/complex_arb.pyx | 105 ++++++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 16 deletions(-) diff --git a/src/sage/rings/complex_arb.pyx b/src/sage/rings/complex_arb.pyx index b18359ca151..ce9b1b19a95 100644 --- a/src/sage/rings/complex_arb.pyx +++ b/src/sage/rings/complex_arb.pyx @@ -188,6 +188,7 @@ from sage.structure.parent cimport Parent from sage.structure.unique_representation import UniqueRepresentation from sage.arith.long cimport is_small_python_int +from sage.misc.superseded import deprecated_function_alias from sage.rings.complex_mpfr import ComplexField from sage.rings.complex_interval_field import ComplexIntervalField, ComplexIntervalField_class from sage.rings.integer_ring import ZZ @@ -4175,16 +4176,21 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return res - def ei(self): + def Ei(self): """ Return the exponential integral with argument ``self``. EXAMPLES:: - sage: CBF(1, 1).ei() + sage: CBF(1, 1).Ei() [1.76462598556385 +/- ...e-15] + [2.38776985151052 +/- ...e-15]*I - sage: CBF(0).ei() + sage: CBF(0).Ei() nan + + TESTS: + + sage: CBF(Ei(I)) + [0.337403922900968 +/- 3.76e-16] + [2.51687939716208 +/- 2.01e-15]*I """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4192,16 +4198,23 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return result - def si(self): + ei = deprecated_function_alias(32869, Ei) + + def Si(self): """ Return the sine integral with argument ``self``. EXAMPLES:: - sage: CBF(1, 1).si() + sage: CBF(1, 1).Si() [1.10422265823558 +/- ...e-15] + [0.88245380500792 +/- ...e-15]*I - sage: CBF(0).si() + sage: CBF(0).Si() 0 + + TESTS: + + sage: CBF(Si(I)) + [1.05725087537573 +/- 2.77e-15]*I """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4209,16 +4222,25 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return result - def ci(self): + sin_integral = Si # as for the symbolic function + + si = deprecated_function_alias(32869, Si) + + def Ci(self): """ Return the cosine integral with argument ``self``. EXAMPLES:: - sage: CBF(1, 1).ci() + sage: CBF(1, 1).Ci() [0.882172180555936 +/- ...e-16] + [0.287249133519956 +/- ...e-16]*I - sage: CBF(0).ci() + sage: CBF(0).Ci() nan + nan*I + + TESTS: + + sage: CBF(Ci(I)) + [0.837866940980208 +/- 4.72e-16] + [1.570796326794897 +/- 5.54e-16]*I """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4226,34 +4248,51 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return result - def shi(self): + cos_integral = Ci # as for the symbolic function + + ci = deprecated_function_alias(32869, Ci) + + def Shi(self): """ Return the hyperbolic sine integral with argument ``self``. EXAMPLES:: - sage: CBF(1, 1).shi() + sage: CBF(1, 1).Shi() [0.88245380500792 +/- ...e-15] + [1.10422265823558 +/- ...e-15]*I - sage: CBF(0).shi() + sage: CBF(0).Shi() 0 - """ + TESTS: + + sage: CBF(Shi(I)) + [0.946083070367183 +/- 9.22e-16]*I + """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() acb_hypgeom_shi(result.value, self.value, prec(self)) if _do_sig(prec(self)): sig_off() return result - def chi(self): + sinh_integral = Shi + + shi = deprecated_function_alias(32869, Shi) + + def Chi(self): """ Return the hyperbolic cosine integral with argument ``self``. EXAMPLES:: - sage: CBF(1, 1).chi() + sage: CBF(1, 1).Chi() [0.882172180555936 +/- ...e-16] + [1.28354719327494 +/- ...e-15]*I - sage: CBF(0).chi() + sage: CBF(0).Chi() nan + nan*I + + TESTS: + + sage: CBF(Chi(I)) + [0.337403922900968 +/- 3.25e-16] + [1.570796326794897 +/- 5.54e-16]*I """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4261,6 +4300,10 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return result + cosh_integral = Chi + + chi = deprecated_function_alias(32869, Chi) + def li(self, bint offset=False): """ Return the logarithmic integral with argument ``self``. @@ -4279,6 +4322,13 @@ cdef class ComplexBall(RingElement): 0.000000000000000 sage: Li(0).n() -1.04516378011749 + + TESTS:: + + sage: CBF(li(0)) + 0 + sage: CBF(Li(0)) + [-1.04516378011749...] """ cdef ComplexBall result = self._new() if _do_sig(prec(self)): sig_on() @@ -4286,6 +4336,29 @@ cdef class ComplexBall(RingElement): if _do_sig(prec(self)): sig_off() return result + log_integral = li + + def Li(self): + """ + Offset logarithmic integral. + + EXAMPLES:: + + sage: CBF(0).Li() + [-1.045163780117493 +/- ...e-16] + sage: li(0).n() + 0.000000000000000 + sage: Li(0).n() + -1.04516378011749 + """ + cdef ComplexBall result = self._new() + if _do_sig(prec(self)): sig_on() + acb_hypgeom_li(result.value, self.value, True, prec(self)) + if _do_sig(prec(self)): sig_off() + return result + + log_integral_offset = Li + def jacobi_theta(self, tau): r""" Return the four Jacobi theta functions evaluated at the argument From 5ef7cc8873ac811d4861f1b55a79a3183856a969 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 14 Nov 2021 12:00:59 +0100 Subject: [PATCH 373/378] =?UTF-8?q?#32871=20fix=20infinite=20recursion=20i?= =?UTF-8?q?n=20SR=20=E2=86=92=20[RC]BF=20conversion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sage/symbolic/expression.pyx | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sage/symbolic/expression.pyx b/src/sage/symbolic/expression.pyx index 8c29b6c6657..843cfee7f4c 100644 --- a/src/sage/symbolic/expression.pyx +++ b/src/sage/symbolic/expression.pyx @@ -1793,7 +1793,20 @@ cdef class Expression(Expression_abc): Traceback (most recent call last): ... ValueError: nonzero imaginary part + + sage: from sage.symbolic.function import BuiltinFunction + sage: f = BuiltinFunction("bogus_builtin_function") + sage: RBF(f(1)) + Traceback (most recent call last): + ... + TypeError: unable to convert bogus_builtin_function(1) to a RealBall + sage: CBF(f(1)) + Traceback (most recent call last): + ... + TypeError: unable to convert bogus_builtin_function(1) to a ComplexBall """ + cdef bint progress = False + cdef int i # Note that we deliberately don't use _eval_self and don't try going # through RIF/CIF in order to avoid unsafe conversions. operator = self.operator() @@ -1827,11 +1840,18 @@ cdef class Expression(Expression_abc): # Generic case: walk through the expression. In this case, we do # not bother trying to stay in the real field. try: - res = self.operator()(*[C(a) for a in args]) + for i in range(len(args)): + if args[i].parent() is not C: + progress = True + args[i] = C(args[i]) except (TypeError, ValueError): pass - else: - return R(res) + if progress: + try: + res = self.operator()(*[C(a) for a in args]) + return R(res) + except (TypeError, ValueError): + pass # Typically more informative and consistent than the exceptions that # would propagate raise TypeError("unable to convert {!r} to a {!s}".format( From 535719018598e165bee841f6e7c8911870b5f4de Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 14 Nov 2021 12:11:11 +0100 Subject: [PATCH 374/378] #32851 more aliases for compatibility with symbolic functions --- src/sage/rings/real_arb.pyx | 43 +++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/sage/rings/real_arb.pyx b/src/sage/rings/real_arb.pyx index b375d2758e7..80a840e7868 100644 --- a/src/sage/rings/real_arb.pyx +++ b/src/sage/rings/real_arb.pyx @@ -3491,6 +3491,11 @@ cdef class RealBall(RingElement): sage: RBF(1).Ei() [1.89511781635594 +/- 4.94e-15] + + TESTS:: + + sage: RBF(Ei(1)) + [1.89511781635594 +/- 4.94e-15] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3506,6 +3511,11 @@ cdef class RealBall(RingElement): sage: RBF(1).Si() [0.946083070367183 +/- 9.22e-16] + + TESTS:: + + sage: RBF(Si(1)) + [0.946083070367183 +/- 9.22e-16] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3513,6 +3523,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + sin_integral = Si + def Ci(self): """ Cosine integral @@ -3521,6 +3533,11 @@ cdef class RealBall(RingElement): sage: RBF(1).Ci() [0.337403922900968 +/- 3.25e-16] + + TESTS:: + + sage: RBF(Ci(1)) + [0.337403922900968 +/- 3.25e-16] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3528,6 +3545,7 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + cos_integral = Ci def Shi(self): """ @@ -3537,6 +3555,11 @@ cdef class RealBall(RingElement): sage: RBF(1).Shi() [1.05725087537573 +/- 2.77e-15] + + TESTS:: + + sage: RBF(Shi(1)) + [1.05725087537573 +/- 2.77e-15] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3544,6 +3567,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + sinh_integral = Shi + def Chi(self): """ Hyperbolic cosine integral @@ -3552,6 +3577,11 @@ cdef class RealBall(RingElement): sage: RBF(1).Chi() [0.837866940980208 +/- 4.72e-16] + + TESTS:: + + sage: RBF(Chi(1)) + [0.837866940980208 +/- 4.72e-16] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3559,6 +3589,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + cosh_integral = Chi + def li(self): """ Logarithmic integral @@ -3567,6 +3599,13 @@ cdef class RealBall(RingElement): sage: RBF(3).li() [2.16358859466719 +/- 4.72e-15] + + TESTS:: + + sage: RBF(li(0)) + 0 + sage: RBF(Li(0)) + [-1.04516378011749 +/- 4.23e-15] """ cdef RealBall res = self._new() if _do_sig(prec(self)): sig_on() @@ -3574,6 +3613,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + log_integral = li + def Li(self): """ Offset logarithmic integral @@ -3589,6 +3630,8 @@ cdef class RealBall(RingElement): if _do_sig(prec(self)): sig_off() return res + log_integral_offset = Li + def beta(self, a, z=1): """ (Incomplete) beta function From aa35a2b92adefed50bebf4b02029df7867d250f7 Mon Sep 17 00:00:00 2001 From: Marc Mezzarobba Date: Sun, 14 Nov 2021 12:15:50 +0100 Subject: [PATCH 375/378] #32851 partial support for symbolic beta --- src/sage/functions/gamma.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/sage/functions/gamma.py b/src/sage/functions/gamma.py index 3e58cbe5a22..3a4deef625d 100644 --- a/src/sage/functions/gamma.py +++ b/src/sage/functions/gamma.py @@ -1045,4 +1045,13 @@ def __init__(self): fricas='Beta', giac='Beta')) + def _method_arguments(self, x, y): + r""" + TESTS:: + + sage: RBF(beta(sin(3),sqrt(RBF(2).add_error(1e-8)/3))) + [7.407662 +/- 6.17e-7] + """ + return [x, y] + beta = Function_beta() From ed63aeba2be4fdfe02f3b2ed20e55577fe2e896d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Sun, 14 Nov 2021 14:08:59 +0100 Subject: [PATCH 376/378] some details in plot (unicode, pep, etc) --- src/sage/plot/colors.py | 31 ++-- src/sage/plot/graphics.py | 364 ++++++++++++++++++-------------------- 2 files changed, 189 insertions(+), 206 deletions(-) diff --git a/src/sage/plot/colors.py b/src/sage/plot/colors.py index 0f2923aa972..6fdba0f0da0 100644 --- a/src/sage/plot/colors.py +++ b/src/sage/plot/colors.py @@ -21,7 +21,7 @@ For a list of color maps in Sage, evaluate:: sage: sorted(colormaps) - [u'Accent', u'Blues', u'BrBG', ...] + ['Accent', 'Blues', 'BrBG', ...] These are imported from matplotlib's cm_ module. @@ -290,16 +290,10 @@ def rgbcolor(c, space='rgb'): (0.25, 0.4, 0.9) sage: rgbcolor('purple') (0.5019607843137255, 0.0, 0.5019607843137255) - sage: rgbcolor(u'purple') - (0.5019607843137255, 0.0, 0.5019607843137255) sage: rgbcolor('#fa0') (1.0, 0.6666666666666666, 0.0) - sage: rgbcolor(u'#fa0') - (1.0, 0.6666666666666666, 0.0) sage: rgbcolor('#ffffff') (1.0, 1.0, 1.0) - sage: rgbcolor(u'#ffffff') - (1.0, 1.0, 1.0) sage: rgbcolor((1,1/2,1/3)) (1.0, 0.5, 0.3333333333333333) sage: rgbcolor([1,1/2,1/3]) @@ -510,8 +504,7 @@ def __eq__(self, right): """ if isinstance(right, Color): return self._rgb == right._rgb - else: - return False + return False def __ne__(self, right): """ @@ -824,7 +817,7 @@ def __int__(self): OUTPUT: - the integer `256^2 r_int + 256 g_int + b_int`, where `r_int`, `g_int`, and `b_int` - are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] + are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] to the integer range 0, 1, ..., 255. EXAMPLES:: @@ -1115,7 +1108,7 @@ def __getattr__(self, name): try: return self[name] except KeyError: - raise AttributeError("'%s' has no attribute or colormap %s"%(type(self).__name__,name)) + raise AttributeError("'%s' has no attribute or colormap %s" % (type(self).__name__, name)) def __dir__(self): """ @@ -1136,8 +1129,10 @@ def __dir__(self): methods = ['__dir__', '__getattr__'] return dir(super(ColorsDict, self)) + methods + sorted(self) + colors = ColorsDict() + # Add convenient module-scope colors. These are Color instances. for c in colors: vars()[c] = colors[c] @@ -1254,7 +1249,7 @@ def float_to_integer(r, g, b): OUTPUT: - the integer `256^2 r_int + 256 g_int + b_int`, where `r_int`, `g_int`, and `b_int` - are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] + are obtained from `r`, `g`, and `b` by converting from the real interval [0.0, 1.0] to the integer range 0, 1, ..., 255. EXAMPLES:: @@ -1337,7 +1332,7 @@ def get_cmap(cmap): and color names. For a list of map names, evaluate:: sage: sorted(colormaps) - [u'Accent', u'Blues', ...] + ['Accent', 'Blues', ...] See :func:`rgbcolor` for valid list/tuple element formats. @@ -1356,8 +1351,6 @@ def get_cmap(cmap): sage: from sage.plot.colors import get_cmap sage: get_cmap('jet') - sage: get_cmap(u'jet') - sage: get_cmap([(0,0,0), (0.5,0.5,0.5), (1,1,1)]) sage: get_cmap(['green', 'lightblue', 'blue']) @@ -1383,7 +1376,7 @@ def get_cmap(cmap): return cmap elif isinstance(cmap, str): - if not cmap in cm.datad: + if cmap not in cm.datad: raise RuntimeError("Color map %s not known (type import matplotlib.cm; matplotlib.cm.datad.keys() for valid names)" % cmap) return cm.__dict__[cmap] @@ -1431,7 +1424,7 @@ class Colormaps(MutableMapping): For a list of map names, evaluate:: sage: sorted(colormaps) - [u'Accent', u'Blues', ...] + ['Accent', 'Blues', ...] """ def __init__(self): """ @@ -1616,7 +1609,7 @@ def __getattr__(self, name): try: return self[name] except KeyError: - raise AttributeError("'%s' has no attribute or colormap %s"%(type(self).__name__,name)) + raise AttributeError("'%s' has no attribute or colormap %s" % (type(self).__name__, name)) def __repr__(self): """ @@ -1678,7 +1671,7 @@ def __delitem__(self, name): sage: maps = Colormaps() sage: count = len(maps) sage: maps.popitem() # random - (u'Spectral', ) + ('Spectral', ) sage: count - 1 == len(maps) True """ diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index 61fa25dd277..137f65016f4 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -99,7 +99,7 @@ def _parse_figsize(figsize): if len(figsize) != 2: raise ValueError("figsize should be a positive number or a list " "of two positive numbers, not {0}".format(figsize)) - figsize = (float(figsize[0]), float(figsize[1])) # floats for mpl + figsize = (float(figsize[0]), float(figsize[1])) # floats for mpl if not (figsize[0] > 0 and figsize[1] > 0): raise ValueError("figsize should be positive numbers, " "not {0} and {1}".format(figsize[0], figsize[1])) @@ -107,12 +107,12 @@ def _parse_figsize(figsize): # in this case, figsize is a single number representing the width and # should be positive try: - figsize = float(figsize) # to pass to mpl + figsize = float(figsize) # to pass to mpl except TypeError: raise TypeError("figsize should be a positive number, not {0}".format(figsize)) if figsize > 0: default_width, default_height = rcParams['figure.figsize'] - figsize = (figsize, default_height*figsize/default_width) + figsize = (figsize, default_height * figsize / default_width) else: raise ValueError("figsize should be positive, not {0}".format(figsize)) return figsize @@ -435,7 +435,6 @@ def set_legend_options(self, **kwds): else: self._legend_opts.update(kwds) - def get_axes_range(self): """ Returns a dictionary of the range of the axes for this graphics @@ -784,9 +783,9 @@ def axes_labels(self, l=None): :: sage: c = circle((0,0), 1) - sage: c.axes_labels(['axe des abscisses', u'axe des ordonnées']) + sage: c.axes_labels(['axe des abscisses', 'axe des ordonnées']) sage: c._axes_labels - ('axe des abscisses', u'axe des ordonn\xe9es') + ('axe des abscisses', 'axe des ordonnées') """ if l is None: try: @@ -852,7 +851,6 @@ def axes_label_color(self, c=None): return self._axes_label_color self._axes_label_color = rgbcolor(c) - def axes_width(self, w=None): r""" Set the axes width. Use this to draw a plot with really fat or @@ -1019,7 +1017,7 @@ def __str__(self): sage: print(S) Graphics object consisting of 1 graphics primitive """ - s = "Graphics object consisting of %s graphics primitives"%(len(self)) + s = "Graphics object consisting of %s graphics primitives" % (len(self)) if len(self) == 1: s = s[:-1] return s @@ -1193,7 +1191,7 @@ def __add__(self, other): from sage.plot.plot3d.base import Graphics3d if isinstance(other, Graphics3d): return self.plot3d() + other - raise TypeError("other (=%s) must be a Graphics objects"%other) + raise TypeError("other (=%s) must be a Graphics objects" % other) g = Graphics() g._objects = self._objects + other._objects g._show_legend = self._show_legend or other._show_legend @@ -1208,9 +1206,9 @@ def __add__(self, other): if 'flip_y' in self._extra_kwds and 'flip_y' in other._extra_kwds: g._extra_kwds['flip_y'] = (self._extra_kwds['flip_y'] or other._extra_kwds['flip_y']) - if self.aspect_ratio()=='automatic': + if self.aspect_ratio() == 'automatic': g.set_aspect_ratio(other.aspect_ratio()) - elif other.aspect_ratio()=='automatic': + elif other.aspect_ratio() == 'automatic': g.set_aspect_ratio(self.aspect_ratio()) else: g.set_aspect_ratio(max(self.aspect_ratio(), other.aspect_ratio())) @@ -1275,7 +1273,7 @@ def plot3d(self, z=0, **kwds): from sage.plot.plot3d.base import Graphics3dGroup g = Graphics3dGroup([g.plot3d(**kwds) for g in self._objects]) if z: - g = g.translate(0,0,z) + g = g.translate(0, 0, z) return g @classmethod @@ -1412,7 +1410,6 @@ def _set_scale(self, subplot, scale=None, base=None): return (xscale, yscale, basex, basey) - # This dictionary has the default values for the keywords to show(). When # show is invoked with keyword arguments, those arguments are merged with # this dictionary to create a set of keywords with the defaults filled in. @@ -2199,7 +2196,6 @@ def ymax(self, ymax=None): else: self.set_axes_range(ymax=ymax) - def get_minmax_data(self): r""" Return the x and y coordinate minimum and maximum @@ -2252,16 +2248,16 @@ def get_minmax_data(self): ymin = min(d['ymin'] for d in minmax_data) ymax = max(d['ymax'] for d in minmax_data) if isnan(xmin): - xmin=0 + xmin = 0 sage.misc.verbose.verbose("xmin was NaN (setting to 0)", level=0) if isnan(xmax): - xmax=0 + xmax = 0 sage.misc.verbose.verbose("xmax was NaN (setting to 0)", level=0) if isnan(ymin): - ymin=0 + ymin = 0 sage.misc.verbose.verbose("ymin was NaN (setting to 0)", level=0) if isnan(ymax): - ymax=0 + ymax = 0 sage.misc.verbose.verbose("ymax was NaN (setting to 0)", level=0) else: xmin = xmax = ymin = ymax = 0 @@ -2312,18 +2308,18 @@ def _limit_output_aspect_ratio(self, xmin, xmax, ymin, ymax): if aspect_ratio != 'automatic': width = xmax - xmin height = ymax - ymin - output_aspect = abs(width/height/aspect_ratio) + output_aspect = abs(width / height / aspect_ratio) if output_aspect > 1e15: height = 1e15 * width / aspect_ratio ycenter = (ymax - ymin) / 2 - ymin = ycenter - height/2 - ymax = ycenter + height/2 + ymin = ycenter - height / 2 + ymax = ycenter + height / 2 if output_aspect < 1e-15: width = 1e-15 * height * aspect_ratio xcenter = (xmax - xmin) / 2 - xmin = xcenter - width/2 - xmax = xcenter + width/2 - return {'xmin':xmin, 'xmax':xmax, 'ymin':ymin, 'ymax':ymax} + xmin = xcenter - width / 2 + xmax = xcenter + width / 2 + return {'xmin': xmin, 'xmax': xmax, 'ymin': ymin, 'ymax': ymax} def _matplotlib_tick_formatter(self, subplot, base=(10, 10), locator_options={}, scale=('linear', 'linear'), @@ -2356,45 +2352,45 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), MultipleLocator, NullLocator, ScalarFormatter) x_locator, y_locator = ticks - #---------------------- Location of x-ticks ---------------------# + # ---------------------- Location of x-ticks --------------------- if x_locator is None: if scale[0] == 'log': x_locator = LogLocator(base=base[0]) else: x_locator = MaxNLocator(**locator_options) - elif isinstance(x_locator,Locator): + elif isinstance(x_locator, Locator): pass elif x_locator == []: x_locator = NullLocator() - elif isinstance(x_locator,list): + elif isinstance(x_locator, list): x_locator = FixedLocator(x_locator) - else: # x_locator is a number which can be made a float + else: # x_locator is a number which can be made a float from sage.functions.other import ceil, floor - if floor(xmax/x_locator)-ceil(xmin/x_locator)>1: - x_locator=MultipleLocator(float(x_locator)) - else: # not enough room for two major ticks + if floor(xmax / x_locator) - ceil(xmin / x_locator) > 1: + x_locator = MultipleLocator(float(x_locator)) + else: # not enough room for two major ticks raise ValueError('Expand the range of the independent ' 'variable to allow two multiples of your tick locator ' '(option `ticks`).') - #---------------------- Location of y-ticks ---------------------# + # ---------------------- Location of y-ticks --------------------- if y_locator is None: if scale[1] == 'log': y_locator = LogLocator(base=base[1]) else: y_locator = MaxNLocator(**locator_options) - elif isinstance(y_locator,Locator): + elif isinstance(y_locator, Locator): pass elif y_locator == []: y_locator = NullLocator() - elif isinstance(y_locator,list): + elif isinstance(y_locator, list): y_locator = FixedLocator(y_locator) - else: # y_locator is a number which can be made a float + else: # y_locator is a number which can be made a float from sage.functions.other import ceil, floor - if floor(ymax/y_locator)-ceil(ymin/y_locator)>1: - y_locator=MultipleLocator(float(y_locator)) - else: # not enough room for two major ticks + if floor(ymax / y_locator) - ceil(ymin / y_locator) > 1: + y_locator = MultipleLocator(float(y_locator)) + else: # not enough room for two major ticks raise ValueError('Expand the range of the dependent ' 'variable to allow two multiples of your tick locator ' '(option `ticks`).') @@ -2404,7 +2400,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), from sage.misc.latex import latex from sage.symbolic.ring import SR from .misc import _multiple_of_constant - #---------------------- Formatting x-ticks ----------------------# + # ---------------------- Formatting x-ticks ---------------------- if x_formatter is None: if scale[0] == 'log': x_formatter = LogFormatterMathtext(base=base[0]) @@ -2412,16 +2408,16 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), x_formatter = ScalarFormatter() elif x_formatter in SR: x_const = x_formatter - x_formatter = FuncFormatter(lambda n,pos: - _multiple_of_constant(n,pos,x_const)) + x_formatter = FuncFormatter(lambda n, pos: + _multiple_of_constant(n, pos, x_const)) elif x_formatter == "latex": if scale[0] == 'log': # We need to strip out '\\mathdefault' from the string - x_formatter = FuncFormatter(lambda n,pos: - LogFormatterMathtext(base=base[0])(n,pos).replace( - "\\mathdefault","")) + x_formatter = FuncFormatter(lambda n, pos: + LogFormatterMathtext(base=base[0])(n, pos).replace( + "\\mathdefault", "")) else: - x_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n)) + x_formatter = FuncFormatter(lambda n, pos: '$%s$' % latex(n)) elif isinstance(x_formatter, (list, tuple)): if (not isinstance(ticks[0], (list, tuple)) or len(ticks[0]) != len(x_formatter)): @@ -2429,7 +2425,7 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), "`tick_formatter` is a list then the first component " "of `ticks` must also be a list of equal length.") x_formatter = FixedFormatter(x_formatter) - #---------------------- Formatting y-ticks ----------------------# + # ---------------------- Formatting y-ticks ---------------------- if y_formatter is None: if scale[1] == 'log': y_formatter = LogFormatterMathtext(base=base[1]) @@ -2437,16 +2433,16 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), y_formatter = ScalarFormatter() elif y_formatter in SR: y_const = y_formatter - y_formatter = FuncFormatter(lambda n,pos: - _multiple_of_constant(n,pos,y_const)) + y_formatter = FuncFormatter(lambda n, pos: + _multiple_of_constant(n, pos, y_const)) elif y_formatter == "latex": if scale[1] == 'log': # We need to strip out '\\mathdefault' from the string - y_formatter = FuncFormatter(lambda n,pos: - LogFormatterMathtext(base=base[1])(n,pos).replace( - "\\mathdefault","")) + y_formatter = FuncFormatter(lambda n, pos: + LogFormatterMathtext(base=base[1])(n, pos).replace( + "\\mathdefault", "")) else: - y_formatter = FuncFormatter(lambda n,pos: '$%s$'%latex(n)) + y_formatter = FuncFormatter(lambda n, pos: '$%s$' % latex(n)) elif isinstance(y_formatter, (list, tuple)): if (not isinstance(ticks[1], (list, tuple)) or len(ticks[1]) != len(y_formatter)): @@ -2478,7 +2474,6 @@ def _matplotlib_tick_formatter(self, subplot, base=(10, 10), return (subplot, x_locator, y_locator, x_formatter, y_formatter) - def _get_vmin_vmax(self, vmin, vmax, basev, axes_pad): r""" Determine the min/max value for a variable plotted on a logarithmic @@ -2570,14 +2565,14 @@ def _get_vmin_vmax(self, vmin, vmax, basev, axes_pad): else: axes_pad = float(abs(axes_pad)) - logvmin = math.log(vmin)/math.log(basev) - logvmax = math.log(vmax)/math.log(basev) + logvmin = math.log(vmin) / math.log(basev) + logvmax = math.log(vmax) / math.log(basev) if math.floor(logvmax) - math.ceil(logvmin) < 0: vmax = basev**math.ceil(logvmax) vmin = basev**math.floor(logvmin) elif math.floor(logvmax) - math.ceil(logvmin) < 1: - if logvmax-math.floor(logvmax) > math.ceil(logvmin)-logvmin: + if logvmax - math.floor(logvmax) > math.ceil(logvmin) - logvmin: vmax = basev**math.ceil(logvmax) if axes_pad > 0: vmin -= vmin * basev**(-axes_pad) @@ -2730,15 +2725,15 @@ def matplotlib(self, filename=None, axes = self._show_axes from matplotlib.figure import Figure - if typeset == 'type1': # Requires LaTeX, dvipng, gs to be installed. + if typeset == 'type1': # Requires LaTeX, dvipng, gs to be installed. rcParams['ps.useafm'] = True rcParams['pdf.use14corefonts'] = True rcParams['text.usetex'] = True - elif typeset == 'latex': # Requires LaTeX, dvipng, gs to be installed. + elif typeset == 'latex': # Requires LaTeX, dvipng, gs to be installed. rcParams['ps.useafm'] = False rcParams['pdf.use14corefonts'] = False rcParams['text.usetex'] = True - elif typeset != 'default': # We won't change (maybe user-set) defaults + elif typeset != 'default': # We won't change (maybe user-set) defaults raise ValueError("typeset must be set to one of 'default', 'latex'," " or 'type1'; got '{}'.".format(typeset)) @@ -2772,13 +2767,13 @@ def matplotlib(self, filename=None, self._bbox_extra_artists.extend(g._bbox_extra_artists) # Set the aspect ratio if aspect_ratio is None: - aspect_ratio=self.aspect_ratio() + aspect_ratio = self.aspect_ratio() if aspect_ratio == 'automatic': subplot.set_aspect('auto', adjustable='box') else: subplot.set_aspect(aspect_ratio, adjustable='box') - #---------------- Set the axes limits and scale ------------------# + # ---------------- Set the axes limits and scale ------------------ self.set_axes_range(xmin, xmax, ymin, ymax) d = self.get_axes_range() xmin = d['xmax' if flip_x else 'xmin'] @@ -2797,7 +2792,7 @@ def matplotlib(self, filename=None, xmax, xmin = self._get_vmin_vmax(xmax, xmin, basex, axes_pad) else: xpad = 0.02 if axes_pad is None else axes_pad - xpad = (xmax - xmin)*float(xpad) + xpad = (xmax - xmin) * float(xpad) xmax += xpad xmin -= xpad @@ -2809,11 +2804,11 @@ def matplotlib(self, filename=None, ymax, ymin = self._get_vmin_vmax(ymax, ymin, basey, axes_pad) else: ypad = 0.02 if axes_pad is None else axes_pad - ypad = (ymax - ymin)*float(ypad) + ypad = (ymax - ymin) * float(ypad) ymax += ypad ymin -= ypad - #-------------------------- Set the legend -----------------------# + # -------------------------- Set the legend ----------------------- if show_legend is None: show_legend = self._show_legend @@ -2823,12 +2818,11 @@ def matplotlib(self, filename=None, lopts.update(legend_options) lopts.update(self._legend_opts) prop = FontProperties( - family = lopts.pop('font_family', 'sans-serif'), - size = lopts.pop('font_size', 'medium'), - style = lopts.pop('font_style', 'normal'), - weight = lopts.pop('font_weight', 'medium'), - variant = lopts.pop('font_variant', 'normal') - ) + family=lopts.pop('font_family', 'sans-serif'), + size=lopts.pop('font_size', 'medium'), + style=lopts.pop('font_style', 'normal'), + weight=lopts.pop('font_weight', 'medium'), + variant=lopts.pop('font_variant', 'normal')) color = lopts.pop('back_color', 'white') leg = subplot.legend(prop=prop, **lopts) if leg is None: @@ -2846,7 +2840,8 @@ def matplotlib(self, filename=None, subplot.set_xlim([xmin, xmax]) subplot.set_ylim([ymin, ymax]) - locator_options=dict(nbins=9,steps=[1,2,5,10],integer=ticks_integer) + locator_options = dict(nbins=9, steps=[1, 2, 5, 10], + integer=ticks_integer) if axes is None: axes = self._show_axes @@ -2855,7 +2850,6 @@ def matplotlib(self, filename=None, spine.set_color(self._axes_color) spine.set_linewidth(self._axes_width) - if frame: # For now, set the formatter to the old one, since that is # sort of what we are used to. We should eventually look at @@ -2863,24 +2857,24 @@ def matplotlib(self, filename=None, (subplot, x_locator, y_locator, x_formatter, y_formatter) = self._matplotlib_tick_formatter( - subplot, base=(basex, basey), - locator_options=locator_options, - scale=(xscale, yscale), - tick_formatter=tick_formatter, ticks=ticks, - xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin) + subplot, base=(basex, basey), + locator_options=locator_options, + scale=(xscale, yscale), + tick_formatter=tick_formatter, ticks=ticks, + xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin) subplot.set_frame_on(True) if axes and xscale == 'linear' and yscale == 'linear': - if (ymin<=0 and ymax>=0) or (ymax<=0 and ymin>=0): + if (ymin <= 0 and ymax >= 0) or (ymax <= 0 and ymin >= 0): subplot.axhline(color=self._axes_color, linewidth=self._axes_width) - if (xmin<=0 and xmax>=0) or (xmax<=0 and xmin>=0): + if (xmin <= 0 and xmax >= 0) or (xmax <= 0 and xmin >= 0): subplot.axvline(color=self._axes_color, linewidth=self._axes_width) elif axes: - ymiddle=False - xmiddle=False + ymiddle = False + xmiddle = False # Note that the user may specify a custom xmin and xmax which # flips the axis horizontally. Hence we need to check for both # the possibilities in the if statements below. Similar @@ -2888,68 +2882,68 @@ def matplotlib(self, filename=None, if xscale == 'log': if xmax > xmin: subplot.spines['right'].set_visible(False) - subplot.spines['left'].set_position(('outward',10)) + subplot.spines['left'].set_position(('outward', 10)) subplot.yaxis.set_ticks_position('left') subplot.yaxis.set_label_position('left') - yaxis='left' + yaxis = 'left' elif xmax < xmin: subplot.spines['left'].set_visible(False) - subplot.spines['right'].set_position(('outward',10)) + subplot.spines['right'].set_position(('outward', 10)) subplot.yaxis.set_ticks_position('right') subplot.yaxis.set_label_position('right') - yaxis='right' + yaxis = 'right' elif (xmin > 0 and xmax > xmin) or (xmax > 0 and xmin > xmax): subplot.spines['right'].set_visible(False) - subplot.spines['left'].set_position(('outward',10)) + subplot.spines['left'].set_position(('outward', 10)) subplot.yaxis.set_ticks_position('left') subplot.yaxis.set_label_position('left') - yaxis='left' + yaxis = 'left' elif (xmax < 0 and xmax > xmin) or (xmin < 0 and xmin > xmax): subplot.spines['left'].set_visible(False) - subplot.spines['right'].set_position(('outward',10)) + subplot.spines['right'].set_position(('outward', 10)) subplot.yaxis.set_ticks_position('right') subplot.yaxis.set_label_position('right') - yaxis='right' + yaxis = 'right' else: subplot.spines['left'].set_position('zero') subplot.yaxis.set_ticks_position('left') subplot.yaxis.set_label_position('left') subplot.spines['right'].set_visible(False) - ymiddle=True - yaxis='left' + ymiddle = True + yaxis = 'left' if yscale == 'log': if ymax > ymin: subplot.spines['top'].set_visible(False) - subplot.spines['bottom'].set_position(('outward',10)) + subplot.spines['bottom'].set_position(('outward', 10)) subplot.xaxis.set_ticks_position('bottom') subplot.xaxis.set_label_position('bottom') - xaxis='bottom' + xaxis = 'bottom' elif ymax < ymin: subplot.spines['bottom'].set_visible(False) - subplot.spines['top'].set_position(('outward',10)) + subplot.spines['top'].set_position(('outward', 10)) subplot.xaxis.set_ticks_position('top') subplot.xaxis.set_label_position('top') - xaxis='top' + xaxis = 'top' elif (ymin > 0 and ymax > ymin) or (ymax > 0 and ymin > ymax): subplot.spines['top'].set_visible(False) - subplot.spines['bottom'].set_position(('outward',10)) + subplot.spines['bottom'].set_position(('outward', 10)) subplot.xaxis.set_ticks_position('bottom') subplot.xaxis.set_label_position('bottom') - xaxis='bottom' + xaxis = 'bottom' elif (ymax < 0 and ymax > ymin) or (ymin < 0 and ymin > ymax): subplot.spines['bottom'].set_visible(False) - subplot.spines['top'].set_position(('outward',10)) + subplot.spines['top'].set_position(('outward', 10)) subplot.xaxis.set_ticks_position('top') subplot.xaxis.set_label_position('top') - xaxis='top' + xaxis = 'top' else: subplot.spines['bottom'].set_position('zero') subplot.xaxis.set_ticks_position('bottom') subplot.xaxis.set_label_position('bottom') subplot.spines['top'].set_visible(False) - xmiddle=True - xaxis='bottom' + xmiddle = True + xaxis = 'bottom' # For now, set the formatter to the old one, since that is # sort of what we are used to. We should eventually look at @@ -2957,11 +2951,11 @@ def matplotlib(self, filename=None, (subplot, x_locator, y_locator, x_formatter, y_formatter) = self._matplotlib_tick_formatter( - subplot, base=(basex, basey), - locator_options=locator_options, - scale=(xscale, yscale), - tick_formatter=tick_formatter, ticks=ticks, - xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin) + subplot, base=(basex, basey), + locator_options=locator_options, + scale=(xscale, yscale), + tick_formatter=tick_formatter, ticks=ticks, + xmax=xmax, xmin=xmin, ymax=ymax, ymin=ymin) # Make ticklines go on both sides of the axes # if xmiddle: @@ -2982,8 +2976,7 @@ def matplotlib(self, filename=None, # Make the zero tick labels disappear if the axes cross # inside the picture, but only if log scale is not used - if (xmiddle and ymiddle and xscale == 'linear' and - yscale == 'linear'): + if (xmiddle and ymiddle and xscale == 'linear' == yscale): from sage.plot.plot import SelectiveFormatter subplot.yaxis.set_major_formatter(SelectiveFormatter( subplot.yaxis.get_major_formatter(), skip_values=[0])) @@ -3009,20 +3002,20 @@ def matplotlib(self, filename=None, subplot.xaxis.set_minor_locator(NullLocator()) elif xscale == 'linear': subplot.xaxis.set_minor_locator(AutoMinorLocator()) - else: # log scale + else: # log scale from sage.arith.srange import srange - base_inv = 1.0/basex - subs = [float(_) for _ in srange(2*base_inv, 1, base_inv)] + base_inv = 1.0 / basex + subs = [float(_) for _ in srange(2 * base_inv, 1, base_inv)] subplot.xaxis.set_minor_locator(LogLocator(base=basex, subs=subs)) if isinstance(y_locator, (NullLocator, FixedLocator)): subplot.yaxis.set_minor_locator(NullLocator()) elif yscale == 'linear': subplot.yaxis.set_minor_locator(AutoMinorLocator()) - else: # log scale + else: # log scale from sage.arith.srange import srange - base_inv = 1.0/basey - subs = [float(_) for _ in srange(2*base_inv, 1, base_inv)] + base_inv = 1.0 / basey + subs = [float(_) for _ in srange(2 * base_inv, 1, base_inv)] subplot.yaxis.set_minor_locator(LogLocator(base=basey, subs=subs)) # Set the color and fontsize of ticks @@ -3032,121 +3025,119 @@ def matplotlib(self, filename=None, if gridlines is not None: if isinstance(gridlines, (list, tuple)): - vgridlines,hgridlines=gridlines + vgridlines, hgridlines = gridlines else: - hgridlines=gridlines - vgridlines=gridlines + hgridlines = gridlines + vgridlines = gridlines if gridlinesstyle is None: # Set up the default grid style - gridlinesstyle=dict(color='black',linestyle=':',linewidth=0.5) + gridlinesstyle = dict(color='black', linestyle=':', + linewidth=0.5) - vgridstyle=gridlinesstyle.copy() + vgridstyle = gridlinesstyle.copy() if vgridlinesstyle is not None: vgridstyle.update(vgridlinesstyle) - hgridstyle=gridlinesstyle.copy() + hgridstyle = gridlinesstyle.copy() if hgridlinesstyle is not None: hgridstyle.update(hgridlinesstyle) - if hgridlines=='minor': - hgridstyle['which']='both' - if vgridlines=='minor': - vgridstyle['which']='both' + if hgridlines == 'minor': + hgridstyle['which'] = 'both' + if vgridlines == 'minor': + vgridstyle['which'] = 'both' if not isinstance(hgridlines, str) and hasattr(hgridlines, '__iter__'): - hlines=iter(hgridlines) - hgridstyle.pop("minor",None) + hlines = iter(hgridlines) + hgridstyle.pop("minor", None) for hline in hlines: if isinstance(hline, (list, tuple)): - hl, style=hline - st=hgridstyle.copy() + hl, style = hline + st = hgridstyle.copy() st.update(style) else: - hl=hline - st=hgridstyle - subplot.axhline(hl,**st) + hl = hline + st = hgridstyle + subplot.axhline(hl, **st) else: if hgridlines not in (None, False): subplot.yaxis.grid(True, **hgridstyle) if not isinstance(vgridlines, str) and hasattr(vgridlines, '__iter__'): - vlines=iter(vgridlines) - vgridstyle.pop("minor",None) + vlines = iter(vgridlines) + vgridstyle.pop("minor", None) for vline in vlines: if isinstance(vline, (list, tuple)): - vl, style=vline - st=vgridstyle.copy() + vl, style = vline + st = vgridstyle.copy() st.update(style) else: - vl=vline - st=vgridstyle - subplot.axvline(vl,**st) + vl = vline + st = vgridstyle + subplot.axvline(vl, **st) else: if vgridlines not in (None, False): subplot.xaxis.grid(True, **vgridstyle) - - if self._axes_labels is not None: - label_options={} - label_options['color']=self._axes_label_color - label_options['size']=int(self._axes_labels_size * self._fontsize) + label_options = {} + label_options['color'] = self._axes_label_color + label_options['size'] = int(self._axes_labels_size * self._fontsize) subplot.set_xlabel(self._axes_labels[0], **label_options) subplot.set_ylabel(self._axes_labels[1], **label_options) - if axes is True and frame is False: # We set the label positions according to where we are # drawing the axes. - if xaxis=='bottom': - yaxis_labely=subplot.get_ylim()[1] - yaxis_labeloffset=8 - yaxis_vert='bottom' - xaxis_labely=0 - xaxis_vert='baseline' + if xaxis == 'bottom': + yaxis_labely = subplot.get_ylim()[1] + yaxis_labeloffset = 8 + yaxis_vert = 'bottom' + xaxis_labely = 0 + xaxis_vert = 'baseline' else: - yaxis_labely=subplot.get_ylim()[0] - yaxis_labeloffset=-8 - yaxis_vert='top' - xaxis_labely=1 - xaxis_vert='top' - - if yaxis=='left': - xaxis_labelx=subplot.get_xlim()[1] - xaxis_labeloffset=8 - xaxis_horiz='left' - yaxis_labelx=0 + yaxis_labely = subplot.get_ylim()[0] + yaxis_labeloffset = -8 + yaxis_vert = 'top' + xaxis_labely = 1 + xaxis_vert = 'top' + + if yaxis == 'left': + xaxis_labelx = subplot.get_xlim()[1] + xaxis_labeloffset = 8 + xaxis_horiz = 'left' + yaxis_labelx = 0 else: - xaxis_labelx=subplot.get_xlim()[0] - xaxis_labeloffset=-8 - xaxis_horiz='right' - yaxis_labelx=1 + xaxis_labelx = subplot.get_xlim()[0] + xaxis_labeloffset = -8 + xaxis_horiz = 'right' + yaxis_labelx = 1 from matplotlib.transforms import offset_copy - xlabel=subplot.xaxis.get_label() + xlabel = subplot.xaxis.get_label() xlabel.set_horizontalalignment(xaxis_horiz) xlabel.set_verticalalignment(xaxis_vert) - trans=subplot.spines[xaxis].get_transform() - labeltrans=offset_copy(trans, figure, x=xaxis_labeloffset, - y=0, units='points') + trans = subplot.spines[xaxis].get_transform() + labeltrans = offset_copy(trans, figure, x=xaxis_labeloffset, + y=0, units='points') subplot.xaxis.set_label_coords(x=xaxis_labelx, y=xaxis_labely, transform=labeltrans) - ylabel=subplot.yaxis.get_label() + ylabel = subplot.yaxis.get_label() ylabel.set_horizontalalignment('center') ylabel.set_verticalalignment(yaxis_vert) ylabel.set_rotation('horizontal') - trans=subplot.spines[yaxis].get_transform() - labeltrans=offset_copy(trans, figure, x=0, - y=yaxis_labeloffset, units='points') + trans = subplot.spines[yaxis].get_transform() + labeltrans = offset_copy(trans, figure, x=0, + y=yaxis_labeloffset, units='points') subplot.yaxis.set_label_coords(x=yaxis_labelx, y=yaxis_labely, transform=labeltrans) # This option makes the xlim and ylim limits not take effect # todo: figure out which limits were specified, and let the # free limits autoscale - #subplot.autoscale_view(tight=True) + # subplot.autoscale_view(tight=True) if title is not None: if title_pos is not None: if (not isinstance(title_pos, (list, tuple)) or @@ -3161,7 +3152,8 @@ def matplotlib(self, filename=None, position=title_pos) else: subplot.set_title(title, fontsize=fontsize) - else: # frame is false axes is not None, and neither is axes_labels + else: + # frame is false axes is not None, and neither is axes_labels # Then, the title is moved up to avoid overlap with axes labels if title_pos is None: title_pos = (0.5, 1.05) @@ -3195,7 +3187,6 @@ def save_image(self, filename=None, *args, **kwds): """ self.save(filename, *args, **kwds) - # filename argument is written explicitly so that it can be used as a # positional one, which is a very likely usage for this function. @@ -3304,13 +3295,13 @@ def save(self, filename, **kwds): else: from matplotlib import rcParams rc_backup = (rcParams['ps.useafm'], rcParams['pdf.use14corefonts'], - rcParams['text.usetex']) # save the rcParams + rcParams['text.usetex']) # save the rcParams figure = self.matplotlib(**options) # You can output in PNG, PS, EPS, PDF, PGF, or SVG format, depending # on the file extension. # PGF is handled by a different backend if ext == '.pgf': - from sage.features.latex import xelatex,pdflatex,lualatex + from sage.features.latex import xelatex, pdflatex, lualatex latex_implementations = [] if xelatex().is_present(): latex_implementations.append('xelatex') @@ -3325,12 +3316,10 @@ def save(self, filename, **kwds): # use pdflatex and set font encoding as per # matplotlib documentation: # https://matplotlib.org/users/pgf.html#pgf-tutorial - pgf_options= {"pgf.texsystem": "pdflatex", - "pgf.preamble": [ - r"\usepackage[utf8x]{inputenc}", - r"\usepackage[T1]{fontenc}" - ] - } + pgf_options = {"pgf.texsystem": "pdflatex", + "pgf.preamble": [ + r"\usepackage[utf8x]{inputenc}", + r"\usepackage[T1]{fontenc}"]} else: pgf_options = { "pgf.texsystem": latex_implementations[0], @@ -3348,7 +3337,7 @@ def save(self, filename, **kwds): from matplotlib.backends.backend_agg import FigureCanvasAgg figure.set_canvas(FigureCanvasAgg(figure)) # this messes up the aspect ratio! - #figure.canvas.mpl_connect('draw_event', pad_for_tick_labels) + # figure.canvas.mpl_connect('draw_event', pad_for_tick_labels) # tight_layout adjusts the *subplot* parameters so ticks aren't cut off, etc. figure.tight_layout() @@ -3363,7 +3352,7 @@ def save(self, filename, **kwds): # Restore the rcParams to the original, possibly user-set values (rcParams['ps.useafm'], rcParams['pdf.use14corefonts'], - rcParams['text.usetex']) = rc_backup + rcParams['text.usetex']) = rc_backup def _latex_(self, **kwds): """ @@ -3386,7 +3375,7 @@ def _latex_(self, **kwds): tmpfilename = tmp_filename(ext='.pgf') self.save(filename=tmpfilename, **kwds) with open(tmpfilename, "r") as tmpfile: - latex_list = tmpfile.readlines() + latex_list = tmpfile.readlines() from sage.misc.latex import latex latex.add_package_to_preamble_if_available('pgf') return ''.join(latex_list) @@ -3502,6 +3491,7 @@ def inset(self, graphics, pos=None, fontsize=None): graphics._extra_kwds['fontsize'] = 6 return MultiGraphics([(self, pos0), (graphics, pos)]) + # Deprecation notice for GraphicsArray import def GraphicsArray(*args, **kwargs): r""" From db5510e1a20932fdd81db0b710481b09af61bc1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Chapoton?= Date: Mon, 15 Nov 2021 17:18:44 +0100 Subject: [PATCH 377/378] fix the Krull dimension --- .../polynomial/polynomial_quotient_ring.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/sage/rings/polynomial/polynomial_quotient_ring.py b/src/sage/rings/polynomial/polynomial_quotient_ring.py index f342447c8f0..64cbec3e25d 100644 --- a/src/sage/rings/polynomial/polynomial_quotient_ring.py +++ b/src/sage/rings/polynomial/polynomial_quotient_ring.py @@ -1056,6 +1056,23 @@ def is_field(self, proof = True): return ret def krull_dimension(self): + """ + Return the Krull dimension. + + This is the Krull dimension of the base ring, unless the + quotient is zero. + + EXAMPLES:: + + sage: R = PolynomialRing(ZZ,'x').quotient(x**6-1) + sage: R.krull_dimension() + 1 + sage: R = PolynomialRing(ZZ,'x').quotient(1) + sage: R.krull_dimension() + -1 + """ + if self.is_zero(): + return -1 return self.base_ring().krull_dimension() def modulus(self): From cc60cfebc4576fed8b01f0fc487271bdee3cefed Mon Sep 17 00:00:00 2001 From: Release Manager Date: Fri, 19 Nov 2021 00:39:31 +0100 Subject: [PATCH 378/378] Updated SageMath version to 9.5.beta7 --- .zenodo.json | 8 ++++---- VERSION.txt | 2 +- build/pkgs/configure/checksums.ini | 6 +++--- build/pkgs/configure/package-version.txt | 2 +- build/pkgs/sagelib/package-version.txt | 2 +- src/VERSION.txt | 2 +- src/bin/sage-version.sh | 6 +++--- src/sage/version.py | 6 +++--- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index 489c739efdd..fd96736f3c1 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,10 +1,10 @@ { "description": "Mirror of the Sage https://sagemath.org/ source tree", "license": "other-open", - "title": "sagemath/sage: 9.5.beta6", - "version": "9.5.beta6", + "title": "sagemath/sage: 9.5.beta7", + "version": "9.5.beta7", "upload_type": "software", - "publication_date": "2021-11-12", + "publication_date": "2021-11-18", "creators": [ { "affiliation": "SageMath.org", @@ -15,7 +15,7 @@ "related_identifiers": [ { "scheme": "url", - "identifier": "https://github.com/sagemath/sage/tree/9.5.beta6", + "identifier": "https://github.com/sagemath/sage/tree/9.5.beta7", "relation": "isSupplementTo" }, { diff --git a/VERSION.txt b/VERSION.txt index b437f328147..be62107d97e 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -SageMath version 9.5.beta6, Release Date: 2021-11-12 +SageMath version 9.5.beta7, Release Date: 2021-11-18 diff --git a/build/pkgs/configure/checksums.ini b/build/pkgs/configure/checksums.ini index 007dd069dce..f97cfada907 100644 --- a/build/pkgs/configure/checksums.ini +++ b/build/pkgs/configure/checksums.ini @@ -1,4 +1,4 @@ tarball=configure-VERSION.tar.gz -sha1=3658781e6dec76acbbcbc405ebc379a8d66438d0 -md5=a9e8b1ee469619a5fcecfda4e61ffc7e -cksum=1864932829 +sha1=d9fff88398cb15f16c7dcb3b6180163bb206a699 +md5=585dece094717b58049a2bfaf9811162 +cksum=3669459096 diff --git a/build/pkgs/configure/package-version.txt b/build/pkgs/configure/package-version.txt index 81a86beb1ab..0cae6c531de 100644 --- a/build/pkgs/configure/package-version.txt +++ b/build/pkgs/configure/package-version.txt @@ -1 +1 @@ -5cb64b3cc4129ec37883c15b81f88fb24fe0bc3d +cdb3614b34926cee3c4cc918313678d3deea4e8d diff --git a/build/pkgs/sagelib/package-version.txt b/build/pkgs/sagelib/package-version.txt index a72129631b5..8f24c817c21 100644 --- a/build/pkgs/sagelib/package-version.txt +++ b/build/pkgs/sagelib/package-version.txt @@ -1 +1 @@ -9.5.beta6 +9.5.beta7 diff --git a/src/VERSION.txt b/src/VERSION.txt index a72129631b5..8f24c817c21 100644 --- a/src/VERSION.txt +++ b/src/VERSION.txt @@ -1 +1 @@ -9.5.beta6 +9.5.beta7 diff --git a/src/bin/sage-version.sh b/src/bin/sage-version.sh index 547dbe14054..5d9a4f586f3 100644 --- a/src/bin/sage-version.sh +++ b/src/bin/sage-version.sh @@ -1,5 +1,5 @@ # Sage version information for shell scripts # This file is auto-generated by the sage-update-version script, do not edit! -SAGE_VERSION='9.5.beta6' -SAGE_RELEASE_DATE='2021-11-12' -SAGE_VERSION_BANNER='SageMath version 9.5.beta6, Release Date: 2021-11-12' +SAGE_VERSION='9.5.beta7' +SAGE_RELEASE_DATE='2021-11-18' +SAGE_VERSION_BANNER='SageMath version 9.5.beta7, Release Date: 2021-11-18' diff --git a/src/sage/version.py b/src/sage/version.py index 7785a1ebba4..60df61416a0 100644 --- a/src/sage/version.py +++ b/src/sage/version.py @@ -1,5 +1,5 @@ # Sage version information for Python scripts # This file is auto-generated by the sage-update-version script, do not edit! -version = '9.5.beta6' -date = '2021-11-12' -banner = 'SageMath version 9.5.beta6, Release Date: 2021-11-12' +version = '9.5.beta7' +date = '2021-11-18' +banner = 'SageMath version 9.5.beta7, Release Date: 2021-11-18'